我有一些VB6代码实例化一个类来处理从VB.NET组件引发的事件. VB6非常简单: private m_eventHandler as new Collection...public sub InitSomething() dim handler as EventHandler set handler = new EventHandler m_eventHandl
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使用者能够正常使用事件,并能够调试进出组件.
希望这可以帮助.