Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Lorsqu’un contrôle est invité à se dessiner dans un contexte d’appareil fourni par un conteneur, il sélectionne généralement des objets GDI (tels que des stylos, des pinceaux et des polices) dans le contexte de l’appareil, effectue ses opérations de dessin et restaure les objets GDI précédents. Si le conteneur a plusieurs contrôles à dessiner dans le même contexte de périphérique et que chaque contrôle sélectionne les objets GDI dont il a besoin, le temps peut être gagné si les contrôles ne restaurent pas individuellement les objets précédemment sélectionnés. Une fois tous les contrôles dessinés, le conteneur peut restaurer automatiquement les objets d’origine.
Pour détecter si un conteneur prend en charge cette technique, un contrôle peut appeler la fonction membre COleControl ::IsOptimizedDraw . Si cette fonction retourne TRUE, le contrôle peut ignorer l’étape normale de restauration des objets précédemment sélectionnés.
Considérez un contrôle qui a la fonction suivante (non optimisée) 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 stylo et le pinceau de cet exemple sont des variables locales, ce qui signifie que leurs destructeurs sont appelés lorsqu'ils sortent de leur portée (lorsque la fonction OnDraw se termine). Les destructeurs tenteront de supprimer les objets GDI correspondants. Mais ils ne doivent pas être supprimés si vous envisagez de les laisser sélectionnés dans le contexte de l’appareil lors du retour à partir de OnDraw.
Pour empêcher les objets CPen et CBrush d’être détruits une fois OnDraw terminés, stockez-les dans des variables membres au lieu de variables locales. Dans la déclaration de classe du contrôle, ajoutez des déclarations pour deux nouvelles variables membres :
class CMyAxOptCtrl : public COleControl
{
CPen m_pen;
CBrush m_brush;
};
Ensuite, la OnDraw fonction 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 création d'un stylo et d'un pinceau chaque fois que OnDraw est appelé. L'amélioration de la vitesse se fait au prix de la gestion des données d'instance supplémentaires.
Si la propriété ForeColor ou BackColor change, le crayon ou le pinceau doit être recréé. Pour ce faire, remplacez les fonctions membres OnForeColorChanged et OnBackColorChanged :
void CMyAxOptCtrl::OnForeColorChanged()
{
m_pen.DeleteObject();
}
void CMyAxOptCtrl::OnBackColorChanged()
{
m_brush.DeleteObject();
}
Enfin, pour éliminer les appels inutiles 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
Contrôles ActiveX MFC : Optimisation
Classe COleControl
Contrôles ActiveX MFC
Contrôle ActiveX MFC, Assistant
Contrôles ActiveX MFC : Peinture d’un contrôle ActiveX