Étape 4: Modifier le Code de dessin

Dans le code de dessin que vous allez utiliser les fonctions sin et cos pour calculer les points du polygone, ajoutez inclure math.h dans le haut de PolyCtl.h:

# include lt;math.h >
# include « resource.h » / / principaux symboles

&Note pour libération construit seulementnbsp ;  Lorsque ATL COM AppWizard génère le projet par défaut, il définit la macro _ATL_MIN_CRT. Cette macro est définie de sorte que vous n'apportez la bibliothèque Runtime C dans votre code si vous n'avez pas ce. Le contrôle polygon besoin le code de démarrage C Run-Time Library pour initialiser les fonctions en virgule flottante. Par conséquent, vous devez supprimer la macro _ATL_MIN_CRT si vous souhaitez créer une version Release. Pour supprimer la macro, cliquez sur paramètres dans le menu projet . Dans la paramètres pour : drop-down list, choisissez Plusieurs Configurations. Sélectionnez le projet configuration(s) à modifier boîte de dialogue qui apparaît, cliquez sur les cases à cocher pour tous les quatre versions, puis cliquez sur OK. Dans l'onglet C/C++ , choisissez la catégorie générale , puis supprimer _ATL_MIN_CRT de la zone d'édition de définitions de préprocesseur.

Une fois les points du polygone sont calculés, vous stockez les points en ajoutant un tableau de type POINT à la fin de la définition de classe de PolyCtl.h:

   M_clrFillColor à l'aide OLE_COLOR ;
   m_nSides courtes ;
   M_arrPoint POINT [100]

Maintenant changer la OnDraw fonction dans PolyCtl.h pour correspondre à celle ci-dessous. Notez que vous supprimez les appels aux fonctions Rectangle et DrawText. Aussi explicitement, vous obtenez et sélectionnez un stylo noir et blanc brosse. Vous devez pour ce faire, dans le cas où votre commande est en cours d'exécution sans fenêtre. Si vous n'avez pas votre propre fenêtre, vous ne pouvez pas d'hypothèses sur le contexte de périphérique, que vous pourrez tirer.

La OnDraw ressemble à ceci:

HRESULT CPolyCtl::OnDraw(ATL_DRAWINFOamp; di)
{
   RECT & CR = *(RECT*)di.prcBounds;
   HDC hdc = di.hdcDraw ;

COLORREF colFore ;
   HBRUSH hOldBrush, hBrush ;
   HPEN hOldPen, hPen ;

/ / M_colFore se traduisent un type COLORREF
   OleTranslateColor (m_clrFillColor à l'aide, NULL, & colFore) ;

/ Créer et de sélectionner les couleurs pour dessiner le cercle
   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) ;

/ / Créer et sélectionnez le pinceau qui est utilisé pour combler le polygone
   hBrush = CreateSolidBrush(colFore) ;
   SelectObject (hdc, hBrush) ;

CalcPoints(rc) ;
   Polygone (hdc, & m_arrPoint [0], m_nSides) ;

/ / Select dos le vieux stylo et brosse et supprimer le pinceau, nous avons créé
   SelectObject (hdc, hOldPen) ;
   SelectObject (hdc, hOldBrush) ;
   DeleteObject(hBrush) ;

return S_OK ;
}

Vous devez mai&ntenant ajouter une fonction, appelée CalcPoints , qui va calculer les coordonnées de ligne intersections.nbsp ; Ces calculs se baseront sur la variable RECT qui est transmise à la fonction.  Tout d'abord, vous devez ajouter la définition de CalcPoints à la section publique de la classe IPolyCtl dans PolyCtl.h:

voidnbsp ;   CalcPoints (RECT const & rc)

La section publique de la classe IPolyCtl doit maintenant ressembler à ceci:

/ / IPolyCtl
public :
   STDMETHOD(get_Sides) (/ * [out, retval] * / court * newVal) ;
   STDMETHOD(put_Sides) (/ * [en] * / short newVal) ;
   voidnbsp ;   CalcPoints (RECT const & rc)

Ensuite, ajoutez la mise en œuvre de la CalcPoints fonction à la fin du fichier PolyCtl.cpp:

vOID CPolyCtl::CalcPoints (const RECTamp; rc)
{
   const pi double = 3.14159265358979 ;
   POINT de ptCenter ;
   double dblRadiusx = (rc.right - rc.left) / 2 ;
   double dblRadiusy = (rc.bottom - rc.top) / 2 ;
   double dblAngle = 3 * pi / 2 ;          / / Démarrer en haut
   double dblDiff = 2 * pi / m_nSides ;   / / Angle de chaque côté fera
   ptCenter.x = (rc.left + rc.right) / 2 ;
   ptCenter.y = (rc.top + rc.bottom) / 2 ;

/ / Calcul des points pour chaque côté
   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 ;
   }
}

Maintenant, initialiser m_clrFillColor . Choisissez vert comme la couleur par défaut et ajoutez cette ligne à la CPolyCtl constructeur dans PolyCtl.h:

   m_clrFillColor à l'aide = RGB (0, 0xFF, 0)

Le constructeur maintenant ressemble à ceci:

CPolyCtl()
{
   m_nSides = 3 ;
   m_clrFillColor à l'aide = RGB (0, 0xFF, 0) ;
}

Maintenant reconstruire le contrôle et essayez de nouveau. Ouvrez ActiveX Control Test Container et insérez le contrôle. Vous devriez voir un triangle vert dans un cercle. Essayez de modifier le nombre de côtés en suivant les étapes ci-dessous. Pour modifier les propriétés sur une interface double de dans le Conteneur de Test, utilisez Les méthodes invoquer:

  1. Dans Test Container, cliquez sur Appeler des méthodes sur le menu de contrôle .
    La Méthode à appeler la boîte de dialogue.

  2. Cliquez sur la version PropPut de la propriété des côtés du Nom de la méthode.

  3. 5 Dans la zone d'édition de La valeur du paramètre de type, cliquez sur Mettre la valeur et cliquez sur appeler.

Notez que le contrôle ne change pas. Qu'est-ce qui ne va pas? Même si vous avez modifié le nombre de côtés en interne en définissant le m_nSides variable, vous n'a pas que le contrôle se repeigne. Si vous basculez vers une autre application et puis rebasculez vers le Conteneur de Test , vous trouverez que le contrôle est repeinte et a maintenant le nombre correct de côtés.

Pour corriger ce problème, vous devez ajouter un appel à la fonction FireViewChange , qui est définie dans IViewObjectExImpl, après avoir défini le nombre de côtés. Si le contrôle est exécuté dans sa propre fenêtre, FireViewChange appellera InvalidateRect API directement. Si le contrôle est exécuté sans fenêtre, appellera la méthode InvalidateRect sur l'interface du site du conteneur. Cela force le contrôle se repeigne lui-même.

Le nouveau put_Sides méthode est comme suit:

STDMETHODIMP CPolyCtl::put_Sides(short newVal)
{
   Si (newVal gt; 2 & & newVal < 101)
   {
      m_nSides = newVal ;
      FireViewChange() ;
      return S_OK ;
   }
   autre
      erreur (_T ("forme doit avoir entre 3 et 100")) ;
}

Après que vous avez ajouté FireViewChange, reconstruire et réessayez la commande. Cette fois, lorsque vous modifiez le nombre de côtés et cliquez sur Invoke, vous devriez voir le contrôle change immédiatement.

Ensuite, vous allez ajouter un événement au contrôle.

Retour à l'étape 3 |nbsp ; Passer à l'étape 5

Index