Numéro d'article: 194179 - Dernière mise à jour: jeudi 2 juin 2005 - Version: 4.0

AtlEvnt.exe exemple montre comment crée des récepteurs d'ATL en utilisant les classes ATL IDispEventImpl et IDispEventSimpleImpl

A noterCet article s'applique à un système d'exploitation différent de celui que vous utilisez. Le contenu de l'article qui ne vous concerne peut-être pas est désactivé.
Microsoft Visual C++ .NET (2002) et Microsoft Visual C++ .NET (2003) prennent en charge le modèle de code managé qui est fourni par le .NET Framework et le modèle de code Windows natif non managé. Les informations contenues dans cet article s'appliquent au code de Visual C++ non managé uniquement.

Sommaire

Agrandir tout | Réduire tout

Résumé

AtlEvnt.exe montre comment implémenter un récepteur d'événements à l'aide des classes ATL IDispEventImpl et IDispEventSimpleImpl. Pour les contrôles composites ou les dialogues ATL, l'Assistant insère IDispEventImpl dans la liste d'héritage pour configurer le récepteur. L'objectif de cet exemple consiste à créer des récepteurs d'autres types d'objets COM et les clients. Cela n'est applicable qu'aux interfaces de source de type dispinterface.

Utilisez IDispEventImpl lorsque vous avez accès à une bibliothèque de type. Utilisez IDispEventSimpleImpl si vous n'avez pas accès à la bibliothèque de type ou lorsque vous voulez être plus efficace en chargeant ne pas de la bibliothèque de type.

Outre un lien vers l'exemple, la section plus d'informations de cet article inclut une vue d'ensemble des projet et des informations sur la façon de mettre en place de chaque classe.

Plus d'informations

Les fichiers suivants sont disponibles au téléchargement à partir du centre de téléchargement Microsoft :

Visual C++ 6.0

Réduire cette imageAgrandir cette image
Download
Download Atlevnt.exe now (http://download.microsoft.com/download/vc60pro/sample7/1/win98/en-us/atlevnt.exe)
Pour plus d'informations sur la façon de télécharger des fichiers de support technique Microsoft, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
119591  (http://support.microsoft.com/kb/119591/ ) Comment faire pour obtenir des fichiers de prise en charge de Microsoft à partir de services en ligne
Microsoft a analysé ce fichier pour les virus. Microsoft utilisé les logiciels de détection de virus les plus récentes ne sont associé à la date à laquelle le fichier a été validé. Le fichier est stocké sur des serveurs sécurisés qui empêchent toute modification non autorisée dans le fichier.

Visual C++ .NET

Réduire cette imageAgrandir cette image
Download
Download Atlevntvcnet.exe now (http://download.microsoft.com/download/visualstudionet/sample/1.11/win98mexp/en-us/atlevntvcnet.exe)
Date de publication : 25 juin 2002

Pour plus d'informations sur la façon de télécharger des fichiers de support technique Microsoft, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
119591  (http://support.microsoft.com/kb/119591/ ) Comment faire pour obtenir des fichiers de prise en charge de Microsoft à partir de services en ligne
Microsoft a analysé ce fichier pour les virus. Microsoft utilisé les logiciels de détection de virus les plus récentes ne sont associé à la date à laquelle le fichier a été validé. Le fichier est stocké sur des serveurs sécurisés qui empêchent toute modification non autorisée dans le fichier. L'espace de travail ATLEVNT se compose de deux projets, AtlEvnt et EventSrc. Utilisez l'option-d lorsque vous exécutez AtlEvnt.exe :
AtlEvnt.exe -d

Vue d'ensemble du projet

L'espace de travail AtlEvnt se compose de deux projets, AtlEvnt et EventSrc.

Le projet EventSrc est une valeur par défaut projet ATL DLL avec un «objet simple». L'objet simple ne possède pas de méthodes et a été modifié pour prendre en charge les points de connexion et l'interface IPersist. L'objet COM expose une interface source par défaut (ci-dessous) qui est une méthode simple appelée Tick. Le COM objet appelle cette méthode sur tous les objets récepteurs connectés, basé sur un minuteur :
   dispinterface _EventSink
   {

      properties:
      methods:
      [id(1), helpstring("method Tick")] HRESULT Tick([in] long tckcnt);

   }

				
AltEvnt le projet est un projet ATL EXE. Une classe ATL CDialogImpl a été ajoutée pour transformer le projet en une application simple boîte de dialogue. Quatre récepteurs ont été ajoutés au projet (deux à l'aide de IDispEventImpl et deux à l'aide de IDispEventSimpleImpl). Chaque récepteur illustre un moyen différent de fourniture d'un objet récepteur à gérer l'événement Tick déclenché par l'objet COM EventSrc.

La boîte de dialogue a quatre boutons et un bouton permet de connexion du récepteur correspondant à l'objet COM EventSrc. La zone de liste affiche une chaîne du formulaire «Sinkn : reçue d'événements Tick - x» chaque fois Tick Gestionnaire d'événements dans le récepteur est appelé. Une fois que la connexion est établie, le bouton est désactivé. Si un problème pour établir la connexion le texte du bouton est remplacé par une chaîne sous la forme «Connect Err-hr"où"h"représente la valeur HRESULT d'échec. Utilisez l'outil de «Recherche d'erreur» fourni avec Visual C++, version 6.0 pour obtenir une explication de l'erreur.

Pour exécuter cet exemple, il convient d'abord d'en générer le projet EventSrc et de l'assurer que l'objet EventSrc est inscrit avec succès. Ensuite, générez le projet AtlEvnt et exécutez-le. Une boîte de dialogue comportant quatre boutons (à l'exception des OK et Annuler) et une zone de liste s'affiche. Les quatre boutons représentent les récepteurs de quatre. En cliquant sur un bouton, le récepteur connecte à la source. Une fois la connexion est établie, chaînes sont ajoutées à la zone de liste chaque fois qu'un gestionnaire est appelé.

Étapes pour mettre en ?uvre de IDispEventImpl

  1. Créer une nouvelle classe dérivée à partir de IDispEventImpl. Vous pouvez cliquer sur Nouvelle classe dans le menu Insertion pour générer une nouvelle classe. Pour chaque récepteur différent, ajouter une classe de IDispEventImpl à la liste d'héritage avec un ID unique en tant que premier paramètre. La classe de récepteur peut être un objet COM (comme dans un contrôle composite) ou une classe qui dérive simplement de IdispEventImpl :
    // Just a sink.
          class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj>
          {
             ...
          }
    - ou -
    // COM object that also implements a sink (as in a composite
          // control).
          class ATL_NO_VTABLE CSinkObj :
             public CComObjectRootEx<CComSingleThreadModel>,
             public CComCoClass<CSinkObj, &CLSID_SinkObj>,
             public IDispatchImpl<ISinkObj, &IID_ISinkObj, &LIBID_SINKPROJLib>,
             public IDispEventImpl<IDC_SRCOBJ, CSinkObj>
          {
             ...
          }
  2. Vous pouvez spécifiez l'ID de l'interface source, les ID du type de bibliothèque, les numéros de version principale et secondaire de la bibliothèque de type contenant l'interface source explicitement en tant que paramètres de IdispEventImpl ou utilisez le AtlGetObjectSourceInterface() pour extraire ces informations à partir de la bibliothèque de type. Utilisation de AtlGetObjectSourceInterface() nécessite que l'objet COM déclenche l'événement implémente IProvideClassInfo2 ou IPersist *:
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj>
          {
             ...
          }
    - ou -
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj,
             &DIID__EventSink, // Source interface GUID.
             &LIBID_COMOBJLib, // typelib ID containing source interface.
             1,                // Major version # of LIBID_COMOBJLib.
             0>                // Minor version # of LIBID_COMOBJLib.
          {
             ...
          }
  3. Ajouter une table de récepteur à la classe ci-dessus et une entrée de récepteur correspondant à chaque événement d'une interface de source que vous souhaitez gérer. Utilisez SINK_ENTRY_EX() lorsque l'interface source est spécifié comme un paramètre dans IDispEventImpl, dans le cas contraire, utilisez SINK_ENTRY() :
    class CSinkObj : public IDispEventImpl<IDC_SRCOBJ, CSinkObj>
          {
          public:
             BEGIN_SINK_MAP(CSinkObj)
                SINK_ENTRY(IDC_SRCOBJ, 1 /*DISPID*/, OnTick /*Event Handler*/)
             END_SINK_MAP()
             ...
          }
    - ou -
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj,
                                  &DIID__EventSink, &LIBID_COMOBJLib, 1, 0>
          {
          public:
             BEGIN_SINK_MAP(CSinkObj)
                SINK_ENTRY_EX(IDC_SRCOBJ, DIID__EventSink, 1, OnTick)
             END_SINK_MAP()
             ...
          }
  4. Ajouter des méthodes de gestionnaire d'événements à votre classe. Vérifiez qu'ils disposent de la convention d'appel __stdcall :
    class CSinkObj : public IDispEventImpl<IDC_SRCOBJ, CSinkObj3>
          {
          public:
             BEGIN_SINK_MAP(CSinkObj)
                SINK_ENTRY(IDC_SRCOBJ, 1 , OnTick)
             END_SINK_MAP()
    
    
             // event handler for event defined in idl as
             // [id(1)] HRESULT Tick([in] long tckcnt);
             HRESULT __stdcall OnTick(long tickcnt)
             {
                ATLTRACE("CSinkObj::OnTick\n");
                return S_OK;
             }
             ...
          }
  5. Connecter le récepteur à l'objet COM en appelant DispEventAdvise(). Si l'interface source est spécifiée en tant que paramètre à IDispEventImpl puis appeler :
    // pUnk is the IUnknown pointer of the COM object that fires events.
       // pSinkObj is an instance of the CSinkObj class.
          pSinkObj->DispEventAdvise(pUnk);
    ou autre appel :
    // Make sure the COM object corresponding to pUnk implements
          // IProvideClassInfo2 or IPersist*.
          // Call this method to extract info about source type library if you
          // specified only two parameters to IdispEventImpl.
          AtlGetObjectSourceInterface(pUnk, &pSinkObj->m_libid,
             &pSinkObj->m_iid, &pSinkObj->m_wMajorVerNum,
             &pSinkObj->m_wMinorVerNum);
    
          hr = pSinkObj->DispEventAdvise(pUnk, &pSinkObj->m_iid);
  6. Déconnectez le récepteur en appelant DispEventUnadvise() :
    pSinkObj->DispEventUnadvise(pUnk);

Étapes pour mettre en ?uvre de IDispEventSimpleImpl

  1. Créez une classe dérivée à partir de IDispEventSimpleImpl. L'interface source doit être spécifié.
  2. Suivez étape 3 ci-dessus, à l'exception d'Ajouter SINK_ENTRY_INFO() pour chaque méthode d'une interface de source que vous souhaitez gérer. IDispEventSimpleImpl n'ayant pas accès à la bibliothèque de type, vous devez fournir des informations sur chaque gestionnaire d'événements à une structure _ATL_FUNC_INFO, un pour chaque gestionnaire d'événements.

    Au lieu de préciser une structure _ATL_FUNC_INFO dans SINK_ENTRY_INFO(), vous pouvez utiliser le SINK_ENTRY_EX() macro et override la fonction virtuelle GetFuncInfoFromId() pour renseigner la _ATL_FUNC_INFO strictement, comme indiqué dans le code suivant.
  3. Suivez les étapes 4 à 6 ci-dessus :
    static _ATL_FUNC_INFO OnTickInfo = {
             CC_STDCALL,   // Calling convention.
             VT_I4,        // Return type.
             1,            // Number of arguments.
             {VT_I4}       // Argument types.
          };
    
          class CSinkObj :
             public IDispEventSimpleImpl<IDC_SRCOBJ, CSinkObj,
                    &DIID__EventSink>
          {
          public:
          BEGIN_SINK_MAP(CSinkObj)
             SINK_ENTRY_INFO(IDC_SRCOBJ, DIID__EventSink, 1, OnTick,
                             &OnTickInfo)
          END_SINK_MAP()
    
             HRESULT __stdcall OnTick(long tickcnt)
             {
                ATLTRACE("CSinkObj::OnTick\n");
                return S_OK;
             }
             ...
    
          }
    - ou -
    class CSinkObj :
             public IDispEventSimpleImpl<IDC_SRCOBJ, CSinkObj,
                    &DIID__EventSink>
          {
          public:
          BEGIN_SINK_MAP(CSinkObj4)
             SINK_ENTRY_EX(IDC_SRCOBJ, DIID__EventSink, 1, OnTick)
             // Equivalent to:
             // SINK_ENTRY_INFO(IDC_SRCOBJ, DIID__EventSink, 1, OnTick, NULL)
          END_SINK_MAP()
    
             HRESULT GetFuncInfoFromId(const IID& iid, DISPID dispidMember,
                LCID lcid, _ATL_FUNC_INFO& info)
             {
                if (InlineIsEqualGUID(iid, DIID__EventSink))
                {
                   info.cc = CC_STDCALL;
                   switch(dispidMember)
                   {
                      case 1:
                         info.vtReturn = VT_I4;
                         info.nParams = 1;
                         info.pVarTypes[0] =  VT_I4;
                         return S_OK;
    
                      default:
                         return E_FAIL;
                   }
                }
                return E_FAIL;
             }
    
             HRESULT __stdcall OnTick(long tickcnt)
             {
                ATLTRACE("CSinkObj::OnTick\n");
                return S_OK;
             }
             ...
          }

Références

Pour plus d'informations, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
181277  (http://support.microsoft.com/kb/181277/ ) AtlSink utilise ATL pour créer un récepteur de dispinterface

Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft ActiveX Template Library 3.0 sur le système suivant
    • Microsoft Visual C++ 6.0 Édition Entreprise
    • Microsoft Visual C++ 6.0 Édition Professionnelle
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
    • Microsoft Visual C++ .NET 2002 Initiation
    • Microsoft Visual C++ .NET 2003 Initiation
Mots-clés : 
kbmt kbtshoot kbdownload kbactivexevents kbconnpts kbfaq kbfile kbhowto kbsample KB194179 KbMtfr
Traduction automatiqueTraduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 194179  (http://support.microsoft.com/kb/194179/en-us/ )
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.