Partager via


Optimiser le dessin de contrôle

Lorsqu'un contrôle est chargé pour dessiner elle-même dans un contexte conteneur-fourni de périphérique, il en général sélectionne des objets de GDI (tels que les stylets, les pinceaux, et des polices) dans le contexte de périphérique, exécute ses opérations de dessin, et restaure les objets précédents GDI.Si le conteneur a plusieurs contrôles qui doivent être dessinés dans le même contexte de périphérique, et chaque contrôle sélectionne les objets GDI dont il a besoin, le temps peut être stocké si les contrôles ne restaurez pas individuellement les objets sélectionnés précédemment.Une fois tous les contrôles ont été dessinés, le conteneur peuvent automatiquement restaurer les objets d'origine.

Pour déterminer si un conteneur prend en charge cette technique, un contrôle peut appeler la fonction membre de COleControl::IsOptimizedDraw .Si cette fonction retourne TRUE, le contrôle peut ignorer l'étape normale de restaurer les objets sélectionnés précédemment.

Considérez un contrôle doté d'une fonction (non optimisée) suivante d' OnDraw :

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   CBrush brush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&pen);
   CBrush* pBrushSave = pdc->SelectObject(&brush);
   pdc->Rectangle(rcBounds);
   pdc->SelectObject(pPenSave);
   pdc->SelectObject(pBrushSave);
}

Le stylet et le pinceau dans cet exemple sont des variables locales, ce qui signifie que leurs destructeurs sont appelés lorsqu'ils sont hors de portée (lorsque la fonction de OnDraw se termine).Les destructeurs tenteront de supprimer les objets correspondants GDI.Mais ils ne doivent pas être supprimés si vous envisagez de les laisser sélectionnés dans le contexte de périphérique en retournant d' OnDraw.

Pour empêcher les objets de CPen et de CBrush soit détruite pendant OnDraw se termine, stockez -les dans les variables membres au lieu des variables locales.Dans la déclaration de classe du contrôle, ajoutez les déclarations pour deux nouvelles variables membres :

class CMyAxOptCtrl : public COleControl
{


...


   CPen m_pen;
   CBrush m_brush;
};

Ensuite, la fonction d' OnDraw peut être réécrite comme suit :

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   CBrush brush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&pen);
   CBrush* pBrushSave = pdc->SelectObject(&brush);
   pdc->Rectangle(rcBounds);
   pdc->SelectObject(pPenSave);
   pdc->SelectObject(pBrushSave);
}

Cette approche évite la conception du stylet et du pinceau chaque fois qu' OnDraw est appelé.L'amélioration de la rapidité provient au prix de gérer des données supplémentaires d'instance.

Si la propriété ForeColor ou BackColor change, le stylet ou le pinceau doit être créé à nouveau.Pour ce faire, substituer les fonctions membres d' OnForeColorChanged et d' OnBackColorChanged :

void CMyAxOptCtrl::OnForeColorChanged()
{
   m_pen.DeleteObject();
}

void CMyAxOptCtrl::OnBackColorChanged()
{
   m_brush.DeleteObject();
}

Enfin, pour éliminer les appels inutiles d' SelectObject , modifiez OnDraw comme suit :

void CMyAxOptCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (m_pen.m_hObject == NULL)
      m_pen.CreatePen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   if (m_brush.m_hObject == NULL)
      m_brush.CreateSolidBrush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&m_pen);
   CBrush* pBrushSave = pdc->SelectObject(&m_brush);
   pdc->Rectangle(rcBounds);
   if (! IsOptimizedDraw())
   {
      pdc->SelectObject(pPenSave);
      pdc->SelectObject(pBrushSave);
   }
}

Voir aussi

Référence

COleControl, classe

Contrôle ActiveX MFC (Assistant)

Concepts

Contrôles ActiveX MFC : optimisation

Contrôles ActiveX MFC

Contrôles ActiveX MFC

Contrôles ActiveX MFC : peinture d'un contrôle ActiveX