Обработка событий VB.NET в коде VB6 - PullRequest
4 голосов
/ 12 мая 2009

У меня есть некоторый код VB6, который создает экземпляр класса, который обрабатывает события, которые возникают из компонента VB.NET. VB6 довольно прост:

private m_eventHandler as new Collection

...

public sub InitSomething()
  dim handler as EventHandler

  set handler = new EventHandler
  m_eventHandler.Add handler
  ...
  m_engine.Start

end sub 

Обратите внимание, что объект обработчика событий должен находиться за пределами области действия метода init (именно поэтому он хранится в коллекции). Также обратите внимание, что m_engine.Start указывает точку в программе, где компонент VB.NET начинает вызывать события.

Фактический обработчик события (по запросу):

Private WithEvents m_SomeClass As SomeClass
Private m_object as Object
...

Private Sub m_SomeClass_SomeEvent(obj As Variant)
    Set obj = m_object
End Sub

Обратите внимание, что m_object инициализируется при создании экземпляра EventHandler.

Код VB.NET, который вызывает событие, еще проще:

Public ReadOnly Property SomeProp() As Object
    Get
        Dim obj As Object
        obj = Nothing
        RaiseEvent SomeEvent(obj)
        SomeProp = obj
    End Get
End Property

Моя проблема в том, что когда я отлаживаю программу VB6, при первом вызове InitSomething событие не будет обработано (обработчик события VB6 никогда не вводится) , Последующие звонки на InitSomething действительно работают.

Все работает так, как я ожидал, когда запускаю программу вне отладчика. На данный момент я даже не уверен, стоит ли беспокоиться об этом.

Это может иметь или не иметь значение, но VB.NET был преобразован из VB6 с использованием инструмента преобразования кода Visual Studio (и впоследствии очищен вручную).

Ответы [ 2 ]

6 голосов
/ 18 июня 2009

Я обнаружил, что если вы пишете .Net Компоненты для потребления в VB6 (или любой другой среде COM), использование Интерфейсов абсолютно критично.

COM-шаблоны, которые входят в комплект поставки VStudio, оставляют желать лучшего, особенно когда вы пытаетесь заставить события работать.

Вот что я использовал.

Imports System.Runtime.InteropServices
Imports System.ComponentModel

<InterfaceType(ComInterfaceType.InterfaceIsDual), Guid(ClientAction.InterfaceId)> Public Interface IClientAction
        <DispId(1), Description("Make the system raise the event")> sub SendMessage(ByVal theMessage As String)
    End Interface


    <InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid(ClientAction.EventsId)> Public Interface IClientActionEvents
        <DispId(1)> Sub TestEvent(ByVal sender As Object, ByVal e As PacketArrivedEventArgs)
    End Interface



    <ComSourceInterfaces(GetType(IClientActionEvents)), Guid(ClientAction.ClassId), ClassInterface(ClassInterfaceType.None)> _
    Public Class ClientAction
        Implements IClientAction

        Public Delegate Sub TestEventDelegate(ByVal sender As Object, ByVal e As PacketArrivedEventArgs)

        Public Event TestEvent As TestEventDelegate

    public sub New()
        //Init etc
    end sub

    public sub SendMessage(theMessage as string) implements IClientAction.SendMessage
        onSendMessage(theMessage)
    end sub 

        Protected Sub onSendMessage(message as string)
            If mRaiseEvents Then
                RaiseEvent TestEvent(Me, New PacketArrivedEventArgs(theMessage))
            End If
        End Sub

    end Class

Мне удалось заставить потребителей COM и .Net сборки / компонента правильно работать с событиями и иметь возможность отлаживать вход и выход компонента.

Надеюсь, это поможет.

0 голосов
/ 18 мая 2009

Просто кое-что попробовать - мне присуще недоверие к «Новому ...»

Можете ли вы попробовать

private m_eventHandler as Collection

public sub InitSomething()
  dim handler as EventHandler

  set handler = new EventHandler

  If m_eventHandler Is Nothing Then
    Set m_eventHandler = New Collection
  End if

  m_eventHandler.Add handler
 ...

  m_engine.Start

end sub

Увы, я понятия не имею, почему это работает в обычном исполнении, а не в отладке, за исключением некоторых смутных подозрений, что это связано с тем, что .NET не может создать экземпляр объекта VBA.Collection (MS рекомендует вам написать быстрый VB6 компонент, чтобы сделать это), но так как вы не создаете коллекции в коде .NET, это все еще лишь смутное подозрение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...