Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
När en kontroll instrueras att dra sig in i en enhetskontext som tillhandahålls av en container väljer den vanligtvis GDI-objekt (till exempel pennor, penslar och teckensnitt) i enhetskontexten, utför sina ritningsåtgärder och återställer de tidigare GDI-objekten. Om containern har flera kontroller som ska dras in i samma enhetskontext och varje kontroll väljer de GDI-objekt som krävs kan tiden sparas om kontrollerna inte återställer tidigare markerade objekt individuellt. När alla kontroller har ritats kan containern automatiskt återställa de ursprungliga objekten.
För att identifiera om en container stöder den här tekniken kan en kontroll anropa medlemsfunktionen COleControl::IsOptimizedDraw . Om den här funktionen returnerar TRUE kan kontrollen hoppa över det normala steget för att återställa de tidigare markerade objekten.
Överväg en kontroll som har följande (ej optimerade) OnDraw funktion:
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);
}
Pennan och penseln i det här exemplet är lokala variabler, vilket innebär att deras destruktorer anropas när de hamnar utanför omfånget OnDraw (när funktionen slutar). Destruktorerna kommer att försöka ta bort de motsvarande GDI-objekten. Men de bör inte tas bort om du planerar att lämna dem valda i enhetskontexten när du återvänder från OnDraw.
Om du vill förhindra att CPen - och CBrush-objekten förstörs när OnDraw de är slutförda lagrar du dem i medlemsvariabler i stället för lokala variabler. I kontrollens klassdeklaration lägger du till deklarationer för två nya medlemsvariabler:
class CMyAxOptCtrl : public COleControl
{
CPen m_pen;
CBrush m_brush;
};
OnDraw Sedan kan funktionen skrivas om på följande sätt:
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);
}
Med det här tillvägagångssättet undviker du att skapa pennan och penseln varje gång OnDraw anropas. Hastighetsförbättringen sker på bekostnad av att underhålla ytterligare instansdata.
Om egenskapen ForeColor eller BackColor ändras måste pennan eller penseln skapas igen. Det gör du genom att åsidosätta medlemsfunktionerna OnForeColorChanged och OnBackColorChanged :
void CMyAxOptCtrl::OnForeColorChanged()
{
m_pen.DeleteObject();
}
void CMyAxOptCtrl::OnBackColorChanged()
{
m_brush.DeleteObject();
}
Slutligen, för att eliminera onödiga SelectObject anrop, ändra OnDraw på följande sätt:
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);
}
}
Se även
MFC ActiveX-kontroller: Optimering
COleControl-klass
MFC ActiveX-kontroller
MFC ActiveX-kontrollguiden
MFC ActiveX-kontroller: Måla en ActiveX-kontroll