2009-06-14 12 views
3

J'essaye de créer un composant COM en utilisant ATL, et je voudrais soulever des événements pour mon client VB. J'ai trouvé de nombreux tutoriels, qui semblent tous varier dans les détails, et aucun d'eux ne semble générer une solution de travail. Voici ce que je fais:Impossible d'obtenir des points de connexion ATL fonctionnant

(Utilisation de Visual Studio 2008):

  1. Créer une nouvelle ATL projet DLL. Je l'ai appelé ATLEventTest.
  2. Class View: Clic droit sur ATLEventTest, Ajout d'une nouvelle classe ATL Simple Object. J'ai appelé ce MyObject, qui a généré CMyObject, IMyObject, etc ...
  3. Cet objet a été créé avec: a) Appartement Threading b) agrégation c) Interface double d) ISupportErrorInfo e) Les points de connexion

  4. faites un clic droit sur CProxy_IMyObjectEvents<T>, cliqué sur 'Ajouter une fonction'

  5. la fonction est de type de retour vide, nommé someEvent, et prend un int testParam.
  6. Reconstruire.
    (À ce stade, je devrais être capable de voir un 'Mettre en place un point de connexion' quelque part .. Je ne ...)
  7. Clic droit sur CMyObject. 'Ajouter un point de connexion'
  8. Déplacé '_IMyObjectEvents' dans la liste.
  9. A fait un code de recherche dans ma solution. Impossible de trouver someEvent n'importe où!
  10. Ajout de la fonction someEvent. Maintenant, il se trouve dans ATLEventTest_i.h
  11. Doit pouvoir appeler fire_someEvent(...) dans mon code, mais ne peut pas.

Cela m'a rendu fou en essayant de faire fonctionner cela. Si quelqu'un peut voir ce que je fais mal, j'apprécierais toutes les corrections, astuces, hacks, etc

À ce stade, je suis tenté de dire que vis les assistants, et juste essayer de modifier le C++ et IDL directement, mais j'ai le sentiment que peut-être pas juste beaucoup mieux :(

+1

Je vous encourage personnellement à le faire sans ATL. Voici un article que j'ai écrit sur ce sujet pour les contrôles ActiveX et JavaScript. Les interfaces et le concept sont essentiellement les mêmes. http://jeffcode.blogspot.com/2008/02/how-to-create-activex-control-that.html –

Répondre

5

Essayez d'utiliser la méthode décrite à cet endroit:

Adding an Event (ATL) @ MSDN

Avec les noms des exemples que vous avez donnés ci-dessus, votre fichier MyObject.idl, vous devriez voir une déclaration pour votre sortant, même sous la section pour dispinterface _IMyObjectEvents. clic droit sur CProxy_IMyObjectEvents <T> et pas sur _IMyObjectEvents sous la bibliothèque, votre IDL est probablement manquant la définition. Le fichier _IMyObjectEvents_CP.h généré automatiquement doit être présent dans vos fichiers d'en-tête de projet et doit contenir la méthode Fire_someEvent() suite à l'ajout correct de la méthode. Si ce n'est pas le cas, vous pouvez constater qu'il vient de créer une méthode nommée someEvent() à la place.

Voici un aperçu que vous pouvez essayer dans un projet de test.

  1. Créer un nouveau projet DLL ATL. Je l'ai appelé ATLEventTest1.
  2. Projet de construction.
  3. Class View: clic droit sur ATLEventTest1, ajout d'une nouvelle classe ATL Simple Object. Appelez-le MyObject.
  4. Créez la définition avec a) Appartement Filetage b) Double interface c) Points de connexion et tout ce dont vous avez besoin.
  5. Reconstruction du projet.
  6. Vue Class: Localisez la bibliothèque ATLEventTest1Lib, cliquez avec le bouton droit sur _MyObjectEvents et "Add Method".
  7. La méthode est de type void return, appelée someEvent, et prend un int testParam avec l'attribut de paramètre [in].
  8. Vous devriez voir "[in] int testParam" à la suite de l'ajout du paramètre.
  9. Dans l'onglet Attributs IDL, modifiez l'ID si nécessaire. Cliquez sur Terminer.
  10. Vue Class: Cliquez avec le bouton droit sur CMyObject, allez dans Ajouter ..., allez à Implémenter le point de connexion.
  11. Sélectionnez _IMyObjectEvents et cliquez sur ">" pour le déplacer vers la liste des points de connexion implémentés. Cliquez sur Terminer.
  12. Reconstruire.
  13. Maintenant, dans votre classe CMyObject, vous devriez pouvoir appeler Fire_someEvent(). Vous verrez une nouvelle méthode dans votre fichier ATLEventTest1.idl sous la dispinterface _IMyObjectEvents; le fichier d'en-tête _IMyObjectEvents_CP.h sera créé et créera le code de diffusion de Fire_someEvent().
+0

+1: Fonctionne un régal pour moi. Merci. – Rob

+2

(En raison du BUG dans Visual Studio 2012/2010/maybe2008) 11.pre NE PAS utiliser l'élément 'Embedded IDL' par défaut pour 'libraires de type Avaliable', vous devez sélectionner le typelib du projet manuellement. – Raymond

+1

Qu'est-ce que cela signifie Raymond? Je peux voir que cela ne fonctionne pas dans VS2012, un clic droit sur l'interface de l'événement en sélectionnant Ajouter une méthode et en complétant l'assistant n'ajoute pas l'événement à l'IDL. Mais que voulez-vous dire par «vous devez sélectionner le typelib du projet manuellement»? Sélectionnez-le où !! – Neutrino

1

Avez-vous une implémentation de IProvideClassInfo/IProvideClassInfo2? Si je me souviens pour les objets non-contrôle, VB l'exige pour localiser l'interface de source d'événement.

Essayez ceci:

public IProvideClassInfo2Impl<&CLSID_MyClass NULL, &LIBID_ATLEventTest, 1, 0>, 

puis sur la carte d'interface

COM_INTERFACE_ENTRY(IProvideClassInfo) 
COM_INTERFACE_ENTRY(IProvideClassInfo2) 
+0

IProvideClassInfo/IProvideClassInfo2 est le point clé. J'ai perdu des jours, et après avoir comparé mon code avec le code du tutoriel MSDN, j'ai trouvé la différence. – Raymond

0

Peut-être que vous avez un problème avec le filetage de l'appartement. Ecrivez-vous une application console sur VB? Une pompe à message classique doit fonctionner correctement (par exemple, une application Windows classique). Essayez le mode d'appartement différent sur votre objet COM (MTA).

0

Ok. Donc, après une nouvelle reconstruction du système, j'ai installé Visual Studio 2005 et Visual Studio 2008. Je peux parfaitement travailler en 2005. Je n'arrive toujours pas à le faire fonctionner en 2008. On dirait que je vais devoir travailler sur VS2005 pour mes trucs ATL ...

Merci encore à tous ceux qui ont aidé.

0

J'avais le même problème. Garder la lecture des documents MSDN et recherché en ligne. Finalement, je l'ai compris.

La principale chose que l'assistant ne fait pas est de mettre la déclaration dans le fichier IDL. Je l'ai ajouté manuellement, et dans ma classe, il y a un "Fire_".

J'espère que cela vous aide.

0

J'ai été en mesure de résoudre un problème similaire en supprimant toutes les références _I *** Events des contrôles.h fichier