Partager via


Changement du code de dessin (Didacticiel ATL, partie 4)

Par défaut, le code de dessin du contrôle affiche un carré et le texte PolyCtl. Dans cette étape, vous allez modifier le code pour afficher quelque chose de plus intéressant. Les tâches suivantes sont impliquées :

  • Modification du fichier d’en-tête

  • Modification de la OnDraw fonction

  • Ajout d’une méthode pour calculer les points de polygones

  • Initialisation de la couleur de remplissage

Modification du fichier d’en-tête

Commencez par ajouter la prise en charge des fonctions sin mathématiques et cos, qui seront utilisées pour calculer les points de polygone, et en créant un tableau pour stocker des positions.

Pour modifier le fichier d’en-tête

  1. Ajoutez la ligne #include <math.h> en haut de PolyCtl.h. Le haut du fichier doit ressembler à ceci :

    #include <math.h>
    #include "resource.h"       // main symbols
    
  2. Implémentez l’interface IProvideClassInfo pour fournir des informations de méthode pour le contrôle, en ajoutant le code suivant à PolyCtl.h. Dans la classe, remplacez la CPolyCtl ligne :

    public CComControl<CPolyCtl>
    

    par

    public CComControl<CPolyCtl>,
    public IProvideClassInfo2Impl<&CLSID_PolyCtl, &DIID__IPolyCtlEvents, &LIBID_PolygonLib>
    

    et dans BEGIN_COM_MAP(CPolyCtl), ajoutez les lignes :

    COM_INTERFACE_ENTRY(IProvideClassInfo)
    COM_INTERFACE_ENTRY(IProvideClassInfo2)
    
  3. Une fois que les points de polygones sont calculés, ils sont stockés dans un tableau de type POINT. Ajoutez le tableau après l’instruction short m_nSides; de définition dans PolyCtl.h :

    POINT m_arrPoint[100];
    

Modification de la méthode OnDraw

Vous devez maintenant modifier la OnDraw méthode dans PolyCtl.h. Le code que vous allez ajouter crée un stylet et un pinceau avec lesquels dessiner votre polygone, puis appelle les Ellipse fonctions d’API Win32 pour Polygon effectuer le dessin réel.

Pour modifier la fonction OnDraw

  1. Remplacez la méthode existante OnDraw dans PolyCtl.h par le code suivant :

    HRESULT CPolyCtl::OnDraw(ATL_DRAWINFO& di)
    {
       RECT& rc = *(RECT*)di.prcBounds;
       HDC hdc  = di.hdcDraw;
    
       COLORREF    colFore;
       HBRUSH      hOldBrush, hBrush;
       HPEN        hOldPen, hPen;
    
       // Translate m_colFore into a COLORREF type
       OleTranslateColor(m_clrFillColor, NULL, &colFore);
    
       // Create and select the colors to draw the circle
       hPen = (HPEN)GetStockObject(BLACK_PEN);
       hOldPen = (HPEN)SelectObject(hdc, hPen);
       hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
       hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
    
       Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom);
    
       // Create and select the brush that will be used to fill the polygon
       hBrush    = CreateSolidBrush(colFore);
       SelectObject(hdc, hBrush);
    
       CalcPoints(rc);
       Polygon(hdc, &m_arrPoint[0], m_nSides);
    
       // Select back the old pen and brush and delete the brush we created
       SelectObject(hdc, hOldPen);
       SelectObject(hdc, hOldBrush);
       DeleteObject(hBrush);
    
       return S_OK;
    }
    

Ajout d’une méthode pour calculer les points de polygones

Ajoutez une méthode appelée CalcPoints, qui calculera les coordonnées des points qui composent le périmètre du polygone. Ces calculs sont basés sur la variable RECT passée dans la fonction.

Pour ajouter la méthode CalcPoints

  1. Ajoutez la déclaration de CalcPoints la IPolyCtl section publique de la CPolyCtl classe dans PolyCtl.h :

    void CalcPoints(const RECT& rc);
    

    La dernière partie de la section publique de la CPolyCtl classe se présente comme suit :

       void FinalRelease()
       {
       }
    public:
       void CalcPoints(const RECT& rc);
    
  2. Ajoutez cette implémentation de la CalcPoints fonction à la fin de PolyCtl.cpp :

    void CPolyCtl::CalcPoints(const RECT& rc)
    {
       const double pi = 3.14159265358979;
       POINT   ptCenter;
       double  dblRadiusx = (rc.right - rc.left) / 2;
       double  dblRadiusy = (rc.bottom - rc.top) / 2;
       double  dblAngle = 3 * pi / 2;          // Start at the top
       double  dblDiff  = 2 * pi / m_nSides;   // Angle each side will make
       ptCenter.x = (rc.left + rc.right) / 2;
       ptCenter.y = (rc.top + rc.bottom) / 2;
    
       // Calculate the points for each side
       for (int i = 0; i < m_nSides; i++)
       {
          m_arrPoint[i].x = (long)(dblRadiusx * cos(dblAngle) + ptCenter.x + 0.5);
          m_arrPoint[i].y = (long)(dblRadiusy * sin(dblAngle) + ptCenter.y + 0.5);
          dblAngle += dblDiff;
       }
    }
    

Initialisation de la couleur de remplissage

Initialiser m_clrFillColor avec une couleur par défaut.

Pour initialiser la couleur de remplissage

  1. Utilisez le vert comme couleur par défaut en ajoutant cette ligne au CPolyCtl constructeur dans PolyCtl.h :

    m_clrFillColor = RGB(0, 0xFF, 0);
    

Le constructeur ressemble maintenant à ceci :

CPolyCtl()
{
   m_nSides = 3;
   m_clrFillColor = RGB(0, 0xFF, 0);
}

Création et test du contrôle

Regénérer le contrôle. Vérifiez que le fichier PolyCtl.htm est fermé s’il est toujours ouvert, puis cliquez sur Build Polygon dans le menu Générer . Vous pouvez afficher à nouveau le contrôle à partir de la page PolyCtl.htm, mais cette fois-ci, utilisez le conteneur de test ActiveX Control.

Pour utiliser le conteneur de test ActiveX Control

  1. Générez et démarrez le conteneur de test de contrôle ActiveX. L’exemple TSTCON : Conteneur de test de contrôle ActiveX est disponible sur GitHub.

    Remarque

    Pour les erreurs impliquant ATL::CW2AEX, dans Script.Cpp, remplacez la ligne TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT ); par TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz );et la ligne TRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) ); par TRACE( "Source Text: %s\n", bstrSourceLineText );.
    Pour les erreurs impliquant HMONITOR, ouvrez StdAfx.h dans le TCProps projet et remplacez :

    #ifndef WINVER
    #define WINVER 0x0400
    #endif
    

    par

    #ifndef WINVER
    #define WINVER 0x0500
    #define _WIN32_WINNT 0x0500
    #endif
    
  2. Dans le conteneur de test, dans le menu Modifier , cliquez sur Insérer un nouveau contrôle.

  3. Recherchez votre contrôle, qui sera appelé PolyCtl class, puis cliquez sur OK. Vous verrez un triangle vert dans un cercle.

Essayez de modifier le nombre de côtés en suivant la procédure suivante. Pour modifier des propriétés sur une double interface à partir du conteneur de test, utilisez Invoke Methods.

Pour modifier la propriété d’un contrôle à partir du conteneur de test

  1. Dans le conteneur de test, cliquez sur Appeler des méthodes dans le menu Contrôle .

    La boîte de dialogue Appeler la méthode s’affiche.

  2. Sélectionnez la version PropPut de la propriété Sides dans la zone de liste déroulante Nom de la méthode.

  3. Tapez 5 la zone Valeur du paramètre, cliquez sur Définir la valeur, puis sur Appeler.

Notez que le contrôle ne change pas. Même si vous avez modifié le nombre de côtés en interne en définissant la m_nSides variable, cela n’a pas pour conséquence que le contrôle soit repeint. Si vous basculez vers une autre application, puis revenez au conteneur de test, vous constaterez que le contrôle a recréé et a le nombre correct de côtés.

Pour corriger ce problème, ajoutez un appel à la FireViewChange fonction, défini dans IViewObjectExImpl, après avoir défini le nombre de côtés. Si le contrôle s’exécute dans sa propre fenêtre, FireViewChange appelle la InvalidateRect méthode directement. Si le contrôle s’exécute sans fenêtre, la InvalidateRect méthode est appelée sur l’interface de site du conteneur. Cela force le contrôle à se repeindre lui-même.

Pour ajouter un appel à FireViewChange

  1. Mettez à jour PolyCtl.cpp en ajoutant l’appel à FireViewChange la put_Sides méthode. Lorsque vous avez terminé, la put_Sides méthode doit ressembler à ceci :

    STDMETHODIMP CPolyCtl::put_Sides(short newVal)
    {
       if (2 < newVal && newVal < 101)
       {
          m_nSides = newVal;
          FireViewChange();
          return S_OK;
       }
       else
       {
          return Error(_T("Shape must have between 3 and 100 sides"));
       }
    }
    

Après avoir ajouté, regénérer FireViewChangeet réessayer le contrôle dans le conteneur de test de contrôle ActiveX. Cette fois que vous modifiez le nombre de côtés et cliquez dessus Invoke, vous devez voir le contrôle changer immédiatement.

À l’étape suivante, vous allez ajouter un événement.

Retour à l’étape 3 | à l’étape 5

Voir aussi

Didacticiel
Test des propriétés et des événements avec le conteneur de test