在暴露给COM的类库中引发事件

时间:2010-12-20 16:48:25

标签: vb.net com vb6 interop

我正在尝试为服务编写一个包装器,它将由现有的VB6项目使用。我有大部分基本框架工作,除了一个重要方面:我可以在VB6项目中引用包装器和子/函数调用等按预期工作,但事件不会。这些事件在VB6应用程序中可见,但它们从未触发过。

VB.NET代码:

Public Event Action_Response(ByVal Status as String)
Public Function TestEvent()
    RaiseEvent Action_Response("Test Done")
    Return "Done"
End Function

VB6代码:

Dim WithEvents my_Wrapper as Wrapper_Class
Private Sub cmdTest_Click()
    Set my_Wrapper = New Wrapper_Class
    Debug.Print my_Wrapper.TestEvent() 
End Sub

Private Sub my_Wrapper_Action_Response(ByVal Status As String)
    Debug.Print Status
    Set my_Wrapper = Nothing
End Sub

因此,cmdTest按钮代码按预期打印“完成”,但不会触发Action_Response事件。我还需要做些什么才能让事件发生?

1 个答案:

答案 0 :(得分:7)

写评论太多了,所以我会把它作为答案......

首先,确定要向COM公开的.net类。我会选一个名为CORE的课程。

创建一个界面,描述CORE对象将要生成的事件(即生成)。

<ComVisible(True)> _
<Guid("some guid here...use guidgen, I'll call it GUID1")> _
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface ICoreEvents
    <System.Runtime.InteropServices.DispId(1)> _
    Sub FileLoaded(ByVal Message As String)
End Interface

接下来,为COM公开的属性和类的方法创建一个接口。

<ComVisible(True)> _
<Guid("another GUID, I'll call it guid2")> _
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _
Public Interface ICore
    ReadOnly Property Property1() As Boolean
    ReadOnly Property AnotherProperty() As ISettings
    ReadOnly Property Name() As String
    ReadOnly Property Phone() As String
End Interface

现在,创建您的实际.net类

<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
<ComDefaultInterface(GetType(ICore))> _
<ComSourceInterfaces(GetType(ICoreEvents))> _
<Guid("a third GUID, I'll call it GUID3")> _
Public Class Core
    Implements ICore

    <System.Runtime.InteropServices.ComVisible(False)> _
    Public Delegate Sub OnFileLoaded(ByVal Message As String)
    Public Event FileLoaded As OnFileLoaded
End Class

现在,当您需要引发FileLoaded事件时,只需从您的类中提取RAISEEVENT FILELOADED(消息)。 .NET会将事件转发给COM,因为您已经连接了COMSourceInterfaces属性。

该属性是其中大部分内容的简写,但遗憾的是并不能完全控制您需要执行某些操作(例如,保留com接口上的版本兼容性)。