2010-12-20 66 views
1

我正在嘗試將一個包裝器寫入一個服務,該服務將由現有的VB6項目使用。除了一個重要的方面,我已經掌握了大部分基礎框架:除了一個重要的方面:我可以在VB6項目中引用包裝器,並且子/函數調用等按預期工作,但事件不會。這些事件在VB6應用程序中可見,但他們從不開火。提高暴露給COM的類庫中的事件

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不會觸發事件。我還需要做些什麼才能讓事件發生?

+0

文檔你是如何使你的VB.NET類'' – 2010-12-20 16:56:53

+0

@Hans:我創建了類庫項目,刪除了默認類,然後添加了一個新項目,並從選項中選擇了「COM類」。 – Antagony 2010-12-20 17:25:40

+0

我不得不直接使用來使事件正常工作。我+雖然+ 會自動做到這一點,但它似乎並沒有這樣工作。 – DarinH 2010-12-20 22:49:50

回答

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接口上保留版本兼容性)。

+0

感謝您的詳細解答,我創建了一個新項目來測試它。不幸的是,似乎存在一個問題:「實現ICore」行爲屬性產生錯誤 - 類'Core'必須爲接口'ICore'實現'ReadOnly Property Name As String'。實現屬性必須具有匹配的「ReadOnly」或「WriteOnly」說明符。我自己嘗試了一些東西,但沒有明顯的解決方案涌向我。 – Antagony 2010-12-21 18:37:22

+0

我幾乎在那裏,我想,drventure。因爲我複製並粘貼了你的代碼,VB沒有在Core類中創建相應的屬性 - 我只需要在Implements行上返回並解決了這個問題。 D'哦! – Antagony 2010-12-21 19:24:23

+0

現在,我已經構建了該類,並使用regasm將其註冊爲一個tlb文件。該類顯示在VB6測試項目中,就事件,方法和屬性而言,一切都看起來沒問題 - 它們都在IDE中正確顯示 - 但只要我嘗試創建新實例的類我得到一個自動化錯誤:「系統找不到指定的文件。」這似乎很奇怪,因爲似乎沒有任何文件被引用到代碼中的任何地方。 – Antagony 2010-12-21 19:24:46