Optimieren der Steuerzeichnung

Wenn ein Steuerelement angewiesen wird, die in einen Container-angegebenen Gerätekontext gezeichnet wird, wählt er in der Regel GDI-Objekte (z. B. Schriftart, Stifte und Pinsel) auf den Gerätekontext, führt die Zeichenvorgänge aus und stellt die vorherigen GDI-Objekte wieder her.Wenn der Container mehrere Steuerelemente, die in gezeichnet werden sollen, derselbe Gerätekontext und jedes Steuerelement die GDI-Objekte auswählt, die erfordert, kann Zeit gespeichert werden, wenn die Steuerelemente nicht einzeln zuvor ausgewählte Objekte wiederhergestellt werden.Nachdem alle Steuerelemente, die Container können die ursprünglichen Objekte automatisch wiederhergestellt wurde angehalten.

Um zu ermitteln, ob ein Container dieses Verfahren unterstützt, kann ein Steuerelement die COleControl::IsOptimizedDraw-Memberfunktion aufrufen.Wenn diese Funktion TRUE zurückgibt, kann das Steuerelement den normalen schrittweise Wiederherstellung der zuvor ausgewählten Objekte überspringen.

Betrachten Sie ein Steuerelement, das die Funktion OnDraw ) nicht optimiertem (folgt:

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);
}

Der Stift und der Pinsel in diesem Beispiel sind die lokalen Variablen. Dies bedeutet, dass ihre Destruktoren bezeichnet werden, wenn sie den Gültigkeitsbereich verlassen (sofern die Funktion beendet OnDraw ).Die Destruktoren versuchen, auf die entsprechenden GDI-Objekte zu löschen.Aber es sollten nicht gelöscht werden, wenn Sie planen, sie kann in den Gerätekontext nach der Rückgabe von OnDraw.

Um die CPen und zerstört Objekte an CBrush zu verhindern OnDraw beendet, wenn speichern Sie sie in die Membervariablen anstelle der lokalen Variablen.In der Klassendeklaration des Steuerelements fügen Sie zwei neue Deklarationen für Membervariablen hinzu:

class CMyAxOptCtrl : public COleControl
{


...


   CPen m_pen;
   CBrush m_brush;
};

Anschließend kann die Funktion OnDraw neu geschrieben werden, wie folgt:

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);
}

Diese Vorgehensweise vermeidet Erstellung des Stifts und des Pinsels jedes Mal, wenn OnDraw aufgerufen wird.Die beschleunigt verbesserung kommt auf Kosten für die Verwaltung von zusätzlichen Instanzdaten.

Wenn die Eigenschaft ForeColor oder BackColor ändert, muss der Stift oder der Pinsel erneut erstellt werden.Hierzu überschreiben Sie die OnForeColorChanged und OnBackColorChanged-Memberfunktionen:

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

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

Schließlich SelectObject unnötige Aufrufe zu vermeiden, ändern Sie OnDraw wie folgt:

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);
   }
}

Siehe auch

Referenz

COleControl-Klasse

MFC ActiveX Control Wizard

Konzepte

MFC-ActiveX-Steuerelemente: Optimierung

MFC-ActiveX-Steuerelemente

MFC-ActiveX-Steuerelemente

MFC-ActiveX-Steuerelemente: Zeichnen eines ActiveX-Steuerelements