Partager via


Ajout d'un événement (Didacticiel ATL, Partie 5)

Dans cette étape, vous allez ajouter un événement et un ClickIn ClickOut événement à votre contrôle ATL. Vous déclenchez l’événement ClickIn si l’utilisateur clique dans le polygone et se déclenche ClickOut si l’utilisateur clique en dehors. Les tâches à ajouter un événement sont les suivantes :

  • Ajout des méthodes et ClickOut des ClickIn méthodes

  • Génération de la bibliothèque de types

  • Implémentation des interfaces de point d’Connecter ion

Ajout des méthodes ClickIn et ClickOut

Lorsque vous avez créé le contrôle ATL à l’étape 2, vous avez sélectionné la zone case activée points d’Connecter ion. Cela a créé l’interface _IPolyCtlEvents dans le fichier Polygon.idl. Notez que le nom de l’interface commence par un trait de soulignement. Il s’agit d’une convention qui indique que l’interface est une interface interne. Ainsi, les programmes qui vous permettent de parcourir des objets COM peuvent choisir de ne pas afficher l’interface à l’utilisateur. Notez également que la sélection de points d’Connecter ion a ajouté la ligne suivante dans le fichier Polygon.idl pour indiquer qu’il _IPolyCtlEvents s’agit de l’interface source par défaut :

[default, source] dispinterface _IPolyCtlEvents;

L’attribut source indique que le contrôle est la source des notifications. Il appelle donc cette interface sur le conteneur.

Ajoutez maintenant les méthodes et ClickOut les ClickIn méthodes à l’interface_IPolyCtlEvents.

Pour ajouter les méthodes ClickIn et ClickOut

  1. Dans Explorateur de solutions, ouvrez Polygon.idl et ajoutez le code suivant sous methods: la déclaration de la dispInterface_IPolyCtlEvents bibliothèque PolygonLib :

    [id(1), helpstring("method ClickIn")] void ClickIn([in] LONG x,[in] LONG y);
    [id(2), helpstring("method ClickOut")] void ClickOut([in] LONG x,[in] LONG y);
    

Les ClickIn méthodes prennent ClickOut les coordonnées x et y du point cliqué en tant que paramètres.

Génération de la bibliothèque de types

Générez la bibliothèque de types à ce stade, car le projet l’utilisera pour obtenir les informations dont il a besoin pour construire une interface de point de connexion et une interface conteneur de point de connexion pour votre contrôle.

Pour générer la bibliothèque de types

  1. Régénérez votre projet.

    -ou-

  2. Cliquez avec le bouton droit sur le fichier Polygon.idl dans Explorateur de solutions, puis cliquez sur Compiler dans le menu contextuel.

Cela crée le fichier Polygon.tlb, qui est votre bibliothèque de types. Le fichier Polygon.tlb n’est pas visible à partir de Explorateur de solutions, car il s’agit d’un fichier binaire et ne peut pas être affiché ou modifié directement.

Implémentation des interfaces de point d’Connecter ion

Implémentez une interface de point de connexion et une interface conteneur de point de connexion pour votre contrôle. Dans COM, les événements sont implémentés via le mécanisme des points de connexion. Pour recevoir des événements à partir d’un objet COM, un conteneur établit une connexion de conseil au point de connexion implémenté par l’objet COM. Étant donné qu’un objet COM peut avoir plusieurs points de connexion, l’objet COM implémente également une interface conteneur de point de connexion. Grâce à cette interface, le conteneur peut déterminer quels points de connexion sont pris en charge.

L’interface qui implémente un point de connexion est appelée IConnectionPointet l’interface qui implémente un conteneur de points de connexion est appelée IConnectionPointContainer.

Pour faciliter l’implémentationIConnectionPoint, vous allez utiliser l’Assistant Implémenter Connecter ion Point. Cet Assistant génère l’interface IConnectionPoint en lisant votre bibliothèque de types et en implémentant une fonction pour chaque événement pouvant être déclenché.

Pour implémenter les points de connexion

  1. Dans Explorateur de solutions, ouvrez _IPolyCtlEvents_CP.h et ajoutez le code suivant sous l’instruction public: de la CProxy_IPolyCtlEvents classe :

    VOID Fire_ClickIn(LONG x, LONG y)
    {
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        CComVariant* pvars = new CComVariant[2];
        int nConnections = m_vec.GetSize();
    
        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                pvars[1].vt = VT_I4;
                pvars[1].lVal = x;
                pvars[0].vt = VT_I4;
                pvars[0].lVal = y;
                DISPPARAMS disp = { pvars, NULL, 2, 0 };
                pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
            }
        }
        delete[] pvars;
    
    }
    VOID Fire_ClickOut(LONG x, LONG y)
    {
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        CComVariant* pvars = new CComVariant[2];
        int nConnections = m_vec.GetSize();
    
        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                pvars[1].vt = VT_I4;
                pvars[1].lVal = x;
                pvars[0].vt = VT_I4;
                pvars[0].lVal = y;
                DISPPARAMS disp = { pvars, NULL, 2, 0 };
                pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
            }
        }
        delete[] pvars;
    
    }
    

Vous verrez que ce fichier a une classe appelée CProxy_IPolyCtlEvents qui dérive de IConnectionPointImpl. _IPolyCtlEvents_CP.h définit désormais les deux méthodes Fire_ClickIn et Fire_ClickOut, qui prennent les deux paramètres de coordonnées. Vous appelez ces méthodes lorsque vous souhaitez déclencher un événement à partir de votre contrôle.

En créant le contrôle avec l’option points d’Connecter ion sélectionnée, le fichier _IPolyCtlEvents_CP.h a été généré pour vous. Il a également ajouté CProxy_PolyEvents et IConnectionPointContainerImpl à la liste d’héritage multiples de votre contrôle et l’expose IConnectionPointContainer pour vous en ajoutant des entrées appropriées à la carte COM.

Vous avez terminé l’implémentation du code pour prendre en charge les événements. À présent, ajoutez du code pour déclencher les événements au moment approprié. N’oubliez pas que vous allez déclencher un ClickIn ou ClickOut un événement lorsque l’utilisateur clique sur le bouton gauche de la souris dans le contrôle. Pour savoir quand l’utilisateur clique sur le bouton, ajoutez un gestionnaire pour le WM_LBUTTONDOWN message.

Pour ajouter un gestionnaire pour le message WM_LBUTTONDOWN

  1. En mode Classe, cliquez avec le bouton droit sur la CPolyCtl classe, puis cliquez sur Propriétés dans le menu contextuel.

  2. Dans la fenêtre Propriétés , cliquez sur l’icône Messages , puis cliquez WM_LBUTTONDOWN dans la liste à gauche.

  3. Dans la liste déroulante qui s’affiche, cliquez sur <Ajouter> OnLButtonDown. La OnLButtonDown déclaration de gestionnaire sera ajoutée à PolyCtl.h, et l’implémentation du gestionnaire sera ajoutée à PolyCtl.cpp.

Ensuite, modifiez le gestionnaire.

Pour modifier la méthode OnLButtonDown

  1. Modifiez le code qui comprend la OnLButtonDown méthode dans PolyCtl.cpp (supprimant tout code placé par l’Assistant) afin qu’il ressemble à ceci :

    LRESULT CPolyCtl::OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, 
       BOOL& /*bHandled*/)
    {
       HRGN hRgn;
       WORD xPos = LOWORD(lParam);  // horizontal position of cursor
       WORD yPos = HIWORD(lParam);  // vertical position of cursor
    
       CalcPoints(m_rcPos);
    
       // Create a region from our list of points
       hRgn = CreatePolygonRgn(&m_arrPoint[0], m_nSides, WINDING);
    
       // If the clicked point is in our polygon then fire the ClickIn
       //  event otherwise we fire the ClickOut event
       if (PtInRegion(hRgn, xPos, yPos))
          Fire_ClickIn(xPos, yPos);
       else
          Fire_ClickOut(xPos, yPos);
    
       // Delete the region that we created
       DeleteObject(hRgn);
       return 0;
    }
    

Ce code utilise les points calculés dans la OnDraw fonction pour créer une région qui détecte les clics de souris de l’utilisateur avec l’appel à PtInRegion.

Le paramètre uMsg est l’ID du message Windows géré. Cela vous permet d’avoir une fonction qui gère une plage de messages. Les paramètres wParam et lParam sont les valeurs standard du message géré. Le paramètre bHandled vous permet de spécifier si la fonction a géré le message ou non. Par défaut, la valeur est définie sur TRUE pour indiquer que la fonction a géré le message, mais vous pouvez la définir sur FALSE. Cela entraîne la poursuite de la recherche d’une autre fonction de gestionnaire de messages à laquelle ATL doit envoyer le message.

Création et test du contrôle

Essayez maintenant vos événements. Générez le contrôle et démarrez à nouveau le conteneur de test de contrôle ActiveX. Cette fois, affichez la fenêtre du journal des événements. Pour router les événements vers la fenêtre de sortie, cliquez sur Journalisation dans le menu Options , puis sélectionnez Journal vers la fenêtre de sortie. Insérez le contrôle et essayez de cliquer dans la fenêtre. Notez qu’il ClickIn est déclenché si vous cliquez dans le polygone rempli et ClickOut qu’il est déclenché lorsque vous cliquez en dehors de celui-ci.

Ensuite, vous allez ajouter une page de propriétés.

Retour à l’étape 4 | à l’étape 6

Voir aussi

Didacticiel