MFC – ovládací prvky ActiveX: Vykreslování ovládacího prvku ActiveX
Tento článek popisuje technologie ActiveX řízení procesu malování a jak můžete změnit kód malování pro optimalizaci procesu. (Viz Optimalizace výkresu ovládacího prvku pro techniky optimalizace výkresu tím, že nemá ovládací prvky jednotlivě obnovit dříve vybrané objekty GDI. Po nakreslení všech ovládacích prvků může kontejner automaticky obnovit původní objekty.)
Důležité
technologie ActiveX je starší technologie, která by se neměla používat pro nový vývoj. Další informace o moderních technologiích, které nahrazují technologie ActiveX, najdete v tématu technologie ActiveX Ovládací prvky.
Příklady v tomto článku pocházejí z ovládacího prvku vytvořeného průvodcem ovládacího prvku MFC technologie ActiveX s výchozím nastavením. Další informace o vytvoření kostru řídicí aplikace pomocí průvodce ovládacím prvku MFC technologie ActiveX naleznete v článku MFC technologie ActiveX Průvodce ovládacími prvky.
Probírána jsou následující témata:
Proces Malování ovládacího prvku technologie ActiveX
Při počátečním zobrazení nebo překreslení ovládacích prvků technologie ActiveX se řídí procesem malování, který se podobá jiným aplikacím vyvinutým pomocí mfc, a to jedním důležitým rozdílem: technologie ActiveX ovládací prvky mohou být v aktivním nebo neaktivním stavu.
Aktivní ovládací prvek je reprezentován v kontejneru ovládacího prvku technologie ActiveX podřízeným oknem. Stejně jako ostatní okna je zodpovědná za malování sama při přijetí WM_PAINT zprávy. Základní třída ovládacího prvku COleControl zpracovává tuto zprávu ve své OnPaint
funkci. Tato výchozí implementace volá OnDraw
funkci vašeho ovládacího prvku.
Neaktivní ovládací prvek je malován odlišně. Pokud je ovládací prvek neaktivní, jeho okno je buď neviditelné nebo neexistující, takže nemůže přijmout malování zprávy. Místo toho kontejner ovládacího prvku přímo volá OnDraw
funkci ovládacího prvku. To se liší od procesu malování aktivního ovládacího prvku v tom, že OnPaint
členská funkce není nikdy volána.
Jak je popsáno v předchozích odstavcích, způsob aktualizace ovládacího prvku technologie ActiveX závisí na stavu ovládacího prvku. Vzhledem k tomu, že architektura volá OnDraw
členskou funkci v obou případech, přidáte do této členské funkce většinu kódu obrazu.
Členská OnDraw
funkce zpracovává ovládací obraz. Pokud je ovládací prvek neaktivní, volá OnDraw
kontejner ovládacího prvku , předává kontext zařízení kontejneru ovládacího prvku a souřadnice obdélníkové oblasti obsazené ovládacím prvku.
Obdélník předaný architekturou OnDraw
členské funkci obsahuje oblast obsazenou ovládacím prvku. Pokud je ovládací prvek aktivní, je v levém horním rohu (0, 0) a předaný kontext zařízení je určený pro podřízené okno obsahující ovládací prvek. Pokud je ovládací prvek neaktivní, levá horní souřadnice nemusí být nutně (0, 0) a předaný kontext zařízení je pro kontejner ovládacího prvku obsahující ovládací prvek.
Poznámka
Je důležité, aby OnDraw
vaše úpravy nezávisely na tom, že levý horní bod obdélníku je roven (0, 0) a že kreslete pouze uvnitř obdélníku předaného OnDraw
. K neočekávaným výsledkům může dojít, pokud kreslete mimo oblast obdélníku.
Výchozí implementace poskytovaná Průvodce ovládacími prvky MFC technologie ActiveX v souboru implementace ovládacího prvku (. CPP), jak je znázorněno níže, nakreslí obdélník bílým štětcem a vyplní tři tečky aktuální barvou pozadí.
void CMyAxUICtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
if (!pdc)
return;
// TODO: Replace the following code with your own drawing code.
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
}
Poznámka
Při malování ovládacího prvku byste neměli provádět předpoklady o stavu kontextu zařízení, který se předává jako parametr pdc funkci OnDraw
. V některých případech je kontext zařízení poskytován aplikací kontejneru a nemusí být nutně inicializován do výchozího stavu. Konkrétně explicitně vyberte pera, štětce, barvy, písma a další prostředky, na které váš kód kreslení závisí.
Optimalizace kódu Malování
Po úspěšném nakreslování ovládacího prvku je dalším krokem optimalizace OnDraw
funkce.
Výchozí implementace technologie ActiveX ovládacích prvků maluje celou oblast ovládacího prvku. To stačí pro jednoduché ovládací prvky, ale v mnoha případech by opětovné nakreslení ovládacího prvku bylo rychlejší, kdyby se místo celého ovládacího prvku překreslila jenom část, která potřebovala aktualizaci.
Funkce OnDraw
poskytuje snadnou metodu optimalizace předáním rcInvalid, obdélníkové oblasti ovládacího prvku, který potřebuje překreslit. Pomocí této oblasti, obvykle menší než celá řídicí oblast, urychlíte proces malování.
Malování ovládací prvek pomocí metasouborů
Ve většině případů primární parametr funkce OnDraw
odkazuje na kontext zařízení obrazovky (DC). Při tisku obrázků ovládacího prvku nebo během relace náhledu tisku je však řadič domény přijatý pro vykreslování speciálním typem označovaným jako "řadič domény metasouboru". Na rozdíl od řadiče domény obrazovky, který okamžitě zpracovává požadavky odeslané do něj, ukládá řadič domény metasouboru požadavky, které se mají přehrát později. Některé kontejnerové aplikace se také mohou rozhodnout vykreslit řídicí obrázek pomocí řadiče domény metasouboru v režimu návrhu.
Žádosti o kreslení metasouboru lze provést kontejnerem prostřednictvím dvou funkcí rozhraní: IViewObject::Draw
(tuto funkci lze také volat pro výkres jiného než metasouboru) a IDataObject::GetData
. Pokud je řadič domény metasouboru předán jako jeden z parametrů, architektura MFC provede volání COleControl::OnDrawMetafile. Vzhledem k tomu, že se jedná o virtuální členovou funkci, přepište tuto funkci ve třídě ovládacích prvků tak, aby všechna speciální zpracování. Výchozí chování volá COleControl::OnDraw
.
Abyste měli jistotu, že ovládací prvek lze kreslit v kontextu obrazovky i zařízení metasouboru, musíte použít pouze členské funkce, které jsou podporovány na obrazovce i v řadiči domény metasouboru. Mějte na paměti, že souřadnicový systém nemusí být měřen v pixelech.
Vzhledem k tomu, že výchozí implementace OnDrawMetafile
volání funkce ovládacího prvku OnDraw
, použijte pouze členské funkce, které jsou vhodné pro metasoubor i kontext zařízení obrazovky, pokud nepřepíšete OnDrawMetafile
. Následující seznam uvádí podmnožinu CDC
členských funkcí, které lze použít v metasouboru i kontextu zařízení obrazovky. Další informace o těchto funkcích naleznete v tématu CDC třídy v referenční dokumentaci MFC.
Arc | BibBlt | Akord |
---|---|---|
Ellipse |
Escape |
ExcludeClipRect |
ExtTextOut |
FloodFill |
IntersectClipRect |
LineTo |
MoveTo |
OffsetClipRgn |
OffsetViewportOrg |
OffsetWindowOrg |
PatBlt |
Pie |
Polygon |
Polyline |
PolyPolygon |
RealizePalette |
RestoreDC |
RoundRect |
SaveDC |
ScaleViewportExt |
ScaleWindowExt |
SelectClipRgn |
SelectObject |
SelectPalette |
SetBkColor |
SetBkMode |
SetMapMode |
SetMapperFlags |
SetPixel |
SetPolyFillMode |
SetROP2 |
SetStretchBltMode |
SetTextColor |
SetTextJustification |
SetViewportExt |
SetViewportOrg |
SetWindowExt |
SetWindowORg |
StretchBlt |
TextOut |
Kromě CDC
členských funkcí existuje několik dalších funkcí, které jsou kompatibilní v řadiči domény metasouboru. Patří mezi ně CPalette::AnimatePalette, CFont::CreateFontIndirect a tři členské funkce CBrush
: CreateBrushIndirect, CreateDIBPatternBrush a CreatePatternBrush.
Funkce, které nejsou zaznamenány v metasouboru: DrawFocusRect, DrawIcon, DrawText, ExcludeUpdateRgn, FillRect, FrameRect, GrayString, InvertRect, ScrollDC a TabbedTextOut. Vzhledem k tomu, že řadič domény metasouboru není ve skutečnosti přidružený k zařízení, nemůžete použít objekt SetDIBits, GetDIBits a CreateDIBitmap s metasouborem DC. Jako cíl můžete použít SetDIBitsToDevice a StretchDIBits s metasouborem DC. Objekty CreateCompatibleDC, CreateCompatibleBitmap a CreateDiscardableBitmap nemají význam pro řadič domény metasouboru.
Dalším bodem, který je třeba vzít v úvahu při použití řadiče domény metasouboru, je, že souřadnicový systém nemusí být měřen v pixelech. Z tohoto důvodu by měl být veškerý kód výkresu upraven tak, aby se vešl do OnDraw
obdélníku předaného do parametru rcBounds . To zabraňuje náhodnému malování mimo ovládací prvek, protože rcBounds představuje velikost okna ovládacího prvku.
Po implementaci vykreslování metasouboru pro ovládací prvek použijte testovací kontejner k otestování metasouboru. Informace o přístupu k testovacímu kontejneru najdete v tématu Testování vlastností a událostí s testovacím kontejnerem .
Testování metasouboru ovládacího prvku pomocí testovacího kontejneru
V nabídce Upravit testovací kontejner klepněte na příkaz Vložit nový ovládací prvek.
V dialogovém okně Vložit nový ovládací prvek vyberte ovládací prvek a klepněte na tlačítko OK.
Ovládací prvek se zobrazí v testovacím kontejneru.
V nabídce Ovládací prvek klepněte na příkaz Nakreslit metasoubor.
Zobrazí se samostatné okno, ve kterém se zobrazí metasoubor. Velikost tohoto okna můžete změnit, abyste viděli, jak škálování ovlivňuje metasoubor ovládacího prvku. Toto okno můžete kdykoli zavřít.