Создание событий в библиотеке классов, доступной для COM - PullRequest
1 голос
/ 20 декабря 2010

Я пытаюсь написать оболочку для службы, которая будет использоваться существующим проектом VB6. У меня работает большинство базовых фреймворков, за исключением одного важного аспекта: я могу ссылаться на оболочку в проекте VB6, а вызовы sub / function и т. Д. Работают как положено, а события - нет. События видны в приложении 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 печатает «Done», как и ожидалось, но событие Action_Response не срабатывает. Есть ли что-то еще, что мне нужно сделать, чтобы запустить событие?

1 Ответ

7 голосов
/ 21 декабря 2010

Слишком много, чтобы написать в комментарии, поэтому я сделаю это ответом.

Сначала определите класс .net, который вы хотите выставить для COM.Я выберу класс с именем 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-интерфейсах).

...