我正在VB.NET中编写COM互操作DLL,我需要将事件暴露给VBA COM客户端。我只是无法绕过这一个。
这是.NET FTP库的COM包装器,所以不要因为我在BytesTransferred事件上引发BytesTransferred事件而感到困惑。
我最好回想一下,这段代码可以工作,但是当我使用对象浏览器时,它无法在COM客户端中显示任何事件。当我尝试将变量WithEvents:
变暗时,它也无法编译Public Interface IFTP
Event BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String)
End Interface
'Here's the relevant part of my class:
Public Interface IFTP
Event BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String)
End Interface
Here's the relevant part of my class:
<ClassInterface(ClassInterfaceType.None)> _
Public Class FTP : Implements IFTP
Public Sub New()
'This needed for com interop
End Sub
Public Event BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String) Implements IFTP.BytesTransferred
Private Sub fCon_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles fCon.BytesTransferred
RaiseEvent BytesTransferred(e.ByteCount, e.RemoteFile)
End Sub
End Class
我也尝试过类似的东西,但我觉得我在这里遗漏了一些东西,因为它没有编译。我看到一个错误,表示我未能为接口IFTP实现Sub BytesTransferred:
Public Delegate Sub BytesTransferredDelegate(ByVal ByteCount As Long, ByVal RemoteFileName As String)
Public Interface IFTP
<DispId(1)> _
Sub BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String)
End Interface
'Here's the relevant part of my class:
<ClassInterface(ClassInterfaceType.None)> _
<ProgId("MyTestClass.FTP")> _
<ComSourceInterfaces(GetType(IFTP))> _
Public Class FTP : Implements IFTP
Public Event BytesTransferred As BytesTransferredDelegate
Public Sub New()
'This needed for com interop
End Sub
Private Sub fCon_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles fCon.BytesTransferred
RaiseEvent BytesTransferred(e.ByteCount, e.RemoteFile)
End Sub
End Class
答案 0 :(得分:6)
<强>解决方案:强>
1)在代码模块的顶部声明Delegate Subs(带参数,如果需要)(如果你使用的话,在你的命名空间内)
2)为您的活动创建一个单独的界面,如下所示。请务必包含IDispatch声明
3)无需在主界面中为您的活动添加任何内容
4)将ComSourceInterfaces声明与您的类声明一起使用
5)在您的课程中,使用“As”声明您的事件以指向您的Delegate Sub
如Hans Passant所述,请务必使用与VB6 / VBA兼容的数据类型。 Long不是兼容的数据类型。
这是我现在可以使用的代码:
Public Delegate Sub BytesTransferredDelegate(ByVal ByteCount As Long, _
ByVal RemoteFileName As String)
Public Delegate Sub OnUploaded()
<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface IFTPEvents
<DispId(1)> _
Sub BytesTransferred(ByVal ByteCount As Double, _
ByVal RemoteFileName As String)
<DispId(2)> _
Sub Uploaded()
End Interface
Public Interface IFTP
'Subs, Functions, Properties go here
'No subs, functions, or events need to be declared here
'to make our events work properly in COM
End Interface
<ComSourceInterfaces(GetType(IFTPEvents)), ClassInterface(ClassInterfaceType.None)> _
Public Class FTP : Implements IFTP
Public Event BytesTransferred As BytesTransferredDelegate
Public Event Uploaded As OnUploaded
Public Sub New()
'This needed for com interop
End Sub
Private Sub fCon_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles fCon.BytesTransferred
RaiseEvent BytesTransferred(e.ByteCount, e.RemoteFile)
End Sub
Private Sub fCon_Uploaded(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.FTPFileTransferEventArgs) Handles fCon.Uploaded
RaiseEvent Uploaded()
End Sub
End Class
以下是我用来解决这个问题的来源:
http://msdn.microsoft.com/en-us/library/dd8bf0x3%28v=VS.90%29.aspx
http://www.codeproject.com/KB/COM/cominterop.aspx#UnmanagedSinks
http://www.developerfusion.com/tools/convert/csharp-to-vb/