2009-05-12 9 views
3

J'ai du code VB6 qui instancie une classe qui gère les événements qui sont levés à partir d'un composant VB.NET. Le VB6 est assez simple:Gestion des événements VB.NET dans le code 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 

Notez que l'objet de gestionnaire d'événements doit vivre au-delà de la portée de la méthode init (ce qui est la raison pour laquelle il est stocké dans une collection). Notez également que m_engine.Start indique le point dans le programme où le composant VB.NET commencerait à déclencher des événements.

Le gestionnaire d'événement réel (comme demandé):

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 

Notez que m_object est initialisé lorsqu'une instance de EventHandler est créé.

Le code VB.NET qui déclenche l'événement est encore plus simple:

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

Mon problème est que quand je debug le programme VB6, la première fois InitSomething est appelée, l'événement pas être manipulé (le gestionnaire d'événement VB6 n'est jamais entré). Les appels suivants au InitSomething fonctionnent.

Tout fonctionne comme je l'aurais prévu lorsque j'ai exécuté le programme en dehors du débogueur. À ce stade, je ne suis même pas sûr si c'est quelque chose que je devrais être inquiété.

Cela peut être ou ne pas être pertinent, mais le VB.NET a été converti à partir d'un VB6 en utilisant l'outil de conversion de code Visual Studio (et ensuite nettoyé manuellement).

+0

Pouvez-vous afficher le gestionnaire d'événements actuel et la déclaration de l'objet de gestion? (celui avec "WithEvents")? –

Répondre

0

Juste quelque chose à essayer - je une méfiance inhérente de « As New .. »

Pouvez-vous essayer

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 

Hélas, je n'ai aucune idée pourquoi cela fonctionne dans l'exécution normale pas dans le débogage sauf de vagues soupçons que c'est à cause de .NET étant incapable d'instancier l'objet VBA.Collection (MS vous recommande d'écrire un composant VB6 rapide pour le faire), mais puisque vous ne créez pas de collections dans le code .NET , ce n'est encore qu'un vague soupçon.

5

J'ai trouvé que si vous écrivez des composants .Net pour la consommation en VB6 (ou tout autre environnement COM), l'utilisation d'Interfaces est absolument critique. Les modèles COM sortis de la boîte avec VStudio laissent beaucoup à désirer, en particulier lorsque vous essayez de faire fonctionner les événements.

Voici ce que j'ai utilisé.

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 

Je suis en mesure d'obtenir les consommateurs COM et .Net de l'Assemblée/composants pour fonctionner correctement avec les événements et être en mesure de déboguer dans et hors du composant.

Espérons que cela aide.

Questions connexes