簡體   English   中英

在VB6代碼中處理VB.NET事件

[英]Handling VB.NET events in VB6 code

我有一些VB6代碼實例化一個類來處理從VB.NET組件引發的事件。 VB6非常簡單:

private m_eventHandler as new Collection

...

public sub InitSomething()
  dim handler as EventHandler

  set handler = new EventHandler
  m_eventHandler.Add handler
  ...
  m_engine.Start

end sub 

請注意,事件處理程序對象必須超出init方法的范圍(這就是它存儲在Collection中的原因)。 另請注意, m_engine.Start表示程序中VB.NET組件將開始引發事件的點。

實際的事件處理程序(根據要求):

Private WithEvents m_SomeClass As SomeClass
Private m_object as Object
...

Private Sub m_SomeClass_SomeEvent(obj As Variant)
    Set obj = m_object
End Sub

請注意,在創建EventHandler實例時會初始化m_object

引發事件的VB.NET代碼更簡單:

Public ReadOnly Property SomeProp() As Object
    Get
        Dim obj As Object
        obj = Nothing
        RaiseEvent SomeEvent(obj)
        SomeProp = obj
    End Get
End Property

我的問題是,當我調試 VB6程序時,第一次InitSomething時,將不會處理該事件(永遠不會輸入VB6事件處理程序)。 InitSomething后續調用確實有效。

當我在調試器外部運行程序時,一切正常。 在這一點上,我甚至不確定這是否是我應該擔心的事情。

它可能相關也可能不相關,但VB.NET是使用Visual Studio代碼轉換工具從VB6轉換而來(隨后手動清理)。

我發現如果你在VB6(或任何其他COM環境)中編寫用於消費的.Net組件,接口的使用絕對是批判性的。

與VStudio一起開箱即用的COM模板還有很多不足之處,尤其是在您嘗試使用事件時。

這就是我用過的東西。

Imports System.Runtime.InteropServices
Imports System.ComponentModel

<InterfaceType(ComInterfaceType.InterfaceIsDual), Guid(ClientAction.InterfaceId)> Public Interface IClientAction
        <DispId(1), Description("Make the system raise the event")> sub SendMessage(ByVal theMessage As String)
    End Interface


    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid(ClientAction.EventsId)> Public Interface IClientActionEvents
        <DispId(1)> Sub TestEvent(ByVal sender As Object, ByVal e As PacketArrivedEventArgs)
    End Interface



    <ComSourceInterfaces(GetType(IClientActionEvents)), Guid(ClientAction.ClassId), ClassInterface(ClassInterfaceType.None)> _
    Public Class ClientAction
        Implements IClientAction

        Public Delegate Sub TestEventDelegate(ByVal sender As Object, ByVal e As PacketArrivedEventArgs)

        Public Event TestEvent As TestEventDelegate

    public sub New()
        //Init etc
    end sub

    public sub SendMessage(theMessage as string) implements IClientAction.SendMessage
        onSendMessage(theMessage)
    end sub 

        Protected Sub onSendMessage(message as string)
            If mRaiseEvents Then
                RaiseEvent TestEvent(Me, New PacketArrivedEventArgs(theMessage))
            End If
        End Sub

    end Class

我已經能夠使Assembly和Component的COM和.Net使用者能夠正常使用事件,並能夠調試進出組件。

希望這可以幫助。

只是嘗試一下 - 我對“新的......”有一種固有的不信任感。

你能試一下嗎

private m_eventHandler as Collection

public sub InitSomething()
  dim handler as EventHandler

  set handler = new EventHandler

  If m_eventHandler Is Nothing Then
    Set m_eventHandler = New Collection
  End if

  m_eventHandler.Add handler
 ...

  m_engine.Start

end sub

唉,我不知道為什么這在正常執行中有效,而不是在調試中除了一些模糊的懷疑,這與.NET無法實例化VBA.Collection對象有關(MS建議您編寫一個快速的VB6組件來做)所以,但由於你不是在.NET代碼中創建集合,它仍然只是一個模糊的懷疑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM