2009-05-19 7 views
3

tirant vraiment mes cheveux avec celui-ci ...C# pour VB6 événements COM (« objet ou classe ne prend pas en charge l'ensemble des événements »)

J'ai un projet C# avec une interface définie comme:

/* Externally Accessible API */ 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface ISerial 
{ 
    [DispId(1)] 
    bool Startup(); 

    [DispId(2)] 
    bool Shutdown(); 

    [DispId(3)] 
    bool UserInput_FloorButton(int floor_number); 

    [DispId(4)] 
    bool Initialize(); 
} 

/* Externally Accesssible Event API */ 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface ISerialEvent 
{ 
    [DispId(5)] 
    void DataEvent(); 
} 

[ComSourceInterfaces(typeof(ISerialEvent), typeof(ISerial))] 
[ClassInterface(ClassInterfaceType.None)] 
public class SerialIface : ISerial 
{ 
    public delegate void DataEvent(); 
    public event DataEvent dEvent; 

    public bool Initialize() 
    { 
     //testing the event callback 
     if (dEvent != null) 
     { 
      dEvent(); 
     } 
    } 
    ... 
} 

Et le code VB6 ressemble:

Private WithEvents objSerial As SerialIface 

Private Sub objSerial_DataEvent() 
    'do something happy' 
End Sub 

Public Sub Class_Initialize() 
    Set objSerial = New SerialIface '<---this is the line that fails' 
    Call objSerial.Initialize '<--Initialize would trigger DataEvent, if it got this far' 
End Sub 

Eh bien, les fonctions normales de type API semblent fonctionner (si je déclare objSerial sans le mot clé WithEvents), mais je ne peux pas pour la vie de moi obtenir le "DataE évent "pour travailler. Il échoue avec le message "objet ou classe ne prend pas en charge le jeu d'événements".

Initialement, j'avais regroupé les deux interfaces, mais C# s'est plaint que DataEvent n'était pas défini dans la classe. La façon dont il est actuellement, je suis en mesure de voir toutes les API et l'événement parfaitement dans le navigateur d'objets VB6 - tout semble comme il est là ... Je ne peux tout simplement pas le faire fonctionner réellement! Je suis sûr qu'il me manque quelque chose d'évident ou de faire quelque chose de stupide - mais je suis nouveau à l'ensemble de l'entreprise d'interopérabilité, donc c'est juste m'échapper complètement.

Aide!

+0

Avez-vous essayé de déclarer votre objet comme l'une des interfaces de source d'événement plutôt que comme interface de classe? –

+0

Je viens de me rendre compte que si j'utilise une classe et une interface entièrement séparées - une avec seulement des événements et aucune API implémentée, cela fonctionne. (De plus, je peux appeler cette classe séparée de la classe principale pour envoyer des événements - mais c'est assez joli kludgey Y a-t-il moyen d'avoir des événements et des APIs réguliers dans la même classe ou interface?) – EMon

+0

JP, merci pour la réponse rapide."Private WithEvents objSerial As ISerialEvent" génère "erreur de compilation: l'objet ne génère pas les événements d'automation" – EMon

Répondre

2

Votre message m'a cependant amené à la solution - merci!

Sans surprise, il s'est avéré être une faute de frappe.

/* Externally Accesssible Event API */ 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface ISerialEvent 
{ 
    [DispId(5)] 
    void DataEvent(); 
} 

devrait être

/* Externally Accesssible Event API */ 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface ISerialEvent 
{ 
    [DispId(5)] 
    void dEvent(); 
} 

je l'interface en utilisant la définition du délégué au lieu de l'événement

Encore une fois, merci pour l'aide!

5

Regardez cet article here. Plus précisément, il semble que vous manquiez une déclaration qui ressemble à ceci.

[Guid("9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E"), 
    ClassInterface(ClassInterfaceType.None), 
    ComSourceInterfaces(typeof(DBCOM_Events))] 
    public class DBCOM_Class : DBCOM_Interface 
    { 

Vous avez cette partie

// // Events interface Database_COMObjectEvents 
[Guid("47C976E0-C208-4740-AC42-41212D3C34F0"), 
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface DBCOM_Events 
{ 
} 

Mais sans le second et le vtable typelib de l'objet COM ne possède pas les Plans d'événements nécessaires pour travailler avec VB6 (ou autres) COM consommateurs.

Vous pouvez utiliser les termes de recherche Google "com event" C# et obtenir un tas d'autres bons résultats.

+0

Merci pour le message et pour le lien. Hmm, je pense que je l'ai dans ce qui précède. J'ai eu les propriétés dans l'ordre inverse, mais je pense que tout est là. Je n'ai pas l'ensemble Guid - je vais essayer ça, mais j'avais lu ailleurs que ce n'était pas nécessaire (ou, plutôt, serait généré automatiquement) – EMon

Questions connexes