Optimalizace vykreslování ovládacích prvků
Při ovládacího prvku je pokyn k nakreslení sebe sama do kontextu zařízení dodávané kontejneru, je obvykle vybere objekty GDI (například pera, stopy a písma) do kontextu zařízení, provádí své operace kreslení a obnoví předchozí objektů GDI.Pokud kontejner má více ovládacích prvků, které mají být vyvozeny do stejného kontextu zařízení a objekty GDI, který potřebuje vybere každý ovládací prvek, lze uložit čas Pokud ovládacích prvků není individuálně obnovit dříve vybrané objekty.Po čerpají všechny ovládací prvky kontejneru automaticky obnovit původní objekty.
Chcete-li zjistit, zda je kontejner podporuje tento postup, můžete zavolat ovládací prvek COleControl::IsOptimizedDraw členské funkce.Pokud tato funkce vrátí TRUE, normální krok obnovení dříve vybrané objekty můžete přeskočit ovládací prvek.
Zvažte ovládací prvek, který má následující (neoptimalizované) OnDraw funkce:
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);
}
Pero a štětec v tomto příkladu jsou lokální proměnné, což znamená, pokud přesahují rozsah platnosti, bude mít název jejich destruktory (když OnDraw funkce končí).Destruktory pokusí odstranit příslušné objekty GDI.Ale neměla být odstraněna pokud plánujete nechat vybrané do kontextu zařízení při návratu z OnDraw.
Chcete-li zabránit CPen a CBrush objekty z zničen při OnDraw povrchové úpravy, uložit je v členské proměnné namísto místní proměnné.V deklaraci třídy ovládacího prvku přidejte dvě nové členské proměnné deklarace:
class CMyAxOptCtrl : public COleControl
{
...
CPen m_pen;
CBrush m_brush;
};
Pak, OnDraw funkce může být přepsán takto:
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);
}
Tento přístup zabraňuje vytváření pero a štětec pokaždé, když OnDraw se nazývá.Zlepšení rychlosti je dodávána na úkor zachování dat další instance.
Pokud vlastnost Barva popředí a barva pozadí se změní, pero a štětec musí být vytvořen znovu.Provedete to přepsat OnForeColorChanged a OnBackColorChanged členské funkce:
void CMyAxOptCtrl::OnForeColorChanged()
{
m_pen.DeleteObject();
}
void CMyAxOptCtrl::OnBackColorChanged()
{
m_brush.DeleteObject();
}
Nakonec k odstranění zbytečných SelectObject hovorů, úprava OnDraw takto:
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);
}
}
Viz také
Referenční dokumentace
Průvodce ovládacím prvkem ActiveX v prostředí MFC
Koncepty
MFC – ovládací prvky ActiveX: Optimalizace
MFC – ovládací prvky ActiveX: Vykreslování ovládacího prvku ActiveX