2011-03-28 88 views
4

我正在VB.NET中編寫COM互操作DLL,我需要將事件公開給VBA COM客戶端。我無法圍繞這一個包裹我的頭。VB.Net Com Interop - 將COM事件接收到VBA客戶端

這是一個.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 

我也試過這樣的事情,但我想我在這裏的東西,因爲它不會編譯。我看,說我已經沒有實行分BytesTransferred的接口IFTP錯誤:

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 

回答

6

解決方案:
1)聲明委託替補(與代碼模塊的頂部,如果需要的參數)(裏面你命名空間,如果你使用的話)
2)爲你的事件創建一個單獨的界面,如下所示。一定要包括IDispatch聲明
3)不需要在您的主界面中爲您的事件添加任何內容。
4)使用ComSourceInterfaces聲明與類聲明
5)你的類中使用聲明的事件「作爲」指向你的委派副

正如漢斯帕桑特提到,一定要使用的數據類型與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/

+0

謝謝,這是真棒!有沒有辦法避免重複聲明事件的簽名(一次在'Public Delegate Sub BytesTransferredDelegate'中,一次在'Sub BytesTransferred'中)? – krlmlr 2016-07-26 09:59:27

+0

我不是這方面的權威,但我認爲除非你找到解決辦法。代表似乎將實際例程暴露給COM。 – HK1 2016-07-26 14:39:08