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
fonctionAjout 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
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
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 laCPolyCtl
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)
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’instructionshort 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
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
Ajoutez la déclaration de
CalcPoints
laIPolyCtl
section publique de laCPolyCtl
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);
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
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
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 ligneTRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT );
parTRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz );
et la ligneTRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) );
parTRACE( "Source Text: %s\n", bstrSourceLineText );
.
Pour les erreurs impliquantHMONITOR
, ouvrez StdAfx.h dans leTCProps
projet et remplacez :#ifndef WINVER #define WINVER 0x0400 #endif
par
#ifndef WINVER #define WINVER 0x0500 #define _WIN32_WINNT 0x0500 #endif
Dans le conteneur de test, dans le menu Modifier , cliquez sur Insérer un nouveau contrôle.
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
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.
Sélectionnez la version PropPut de la propriété Sides dans la zone de liste déroulante Nom de la méthode.
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
Mettez à jour PolyCtl.cpp en ajoutant l’appel à
FireViewChange
laput_Sides
méthode. Lorsque vous avez terminé, laput_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 FireViewChange
et 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