Sdílet prostřednictvím


MFC – ovládací prvky ActiveX: Malování ovládacího prvku ActiveX

Tento článek popisuje proces malování ovládacích prvků ActiveX a způsob, jak můžete změnit kód malování pro optimalizaci procesu. (Viz Optimalizace kreslení ovládacích prvků pro techniky, jak optimalizovat kreslení tím, že ovládací prvky neobnovují individuálně dříve vybrané GDI objekty. Po nakreslení všech ovládacích prvků může kontejner automaticky obnovit původní objekty.)

Důležité

ActiveX je starší technologie, která by se neměla používat pro nový vývoj. Další informace o moderních technologiích, které nahrazují ovládací prvky ActiveX, naleznete v tématu Ovládací prvky ActiveX.

Příklady v tomto článku pocházejí z ovládacího prvku vytvořeného průvodcem ovládacím prvku ActiveX MFC s výchozím nastavením. Další informace o vytvoření základní aplikace ovládacího prvku pomocí Průvodce ovládacími prvky MFC ActiveX naleznete v článku Průvodce ovládacími prvky MFC ActiveX.

Probíráme následující témata:

Proces malování ovládacího prvku ActiveX

Když jsou ovládací prvky ActiveX zpočátku zobrazeny nebo překreslovány, následují proces malování podobný jiným aplikacím vyvinutým pomocí mfc, a to s jedním důležitým rozdílem: Ovládací prvky ActiveX mohou být v aktivním nebo neaktivním stavu.

V kontejneru ovládacího prvku ActiveX je aktivní ovládací prvek reprezentován podřízeným oknem. Stejně jako ostatní okna, odpovídá za vlastní vykreslení při přijetí zprávy WM_PAINT. Základní třída ovládacího prvku COleControl zpracovává tuto zprávu ve své OnPaint funkci. Výchozí implementace volá funkci OnDraw ve vašem ovládacím 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 zprávu pro vykreslení. Místo toho kontejner ovládacího prvku přímo volá OnDraw funkci ovládacího prvku. To se liší od procesu vykreslování aktivního ovládacího prvku v tom, že členská funkce OnPaint není nikdy volána.

Jak je popsáno v předchozích odstavcích, způsob aktualizace ovládacího prvku ActiveX závisí na stavu ovládacího prvku. Vzhledem k tomu, že framework volá členskou funkci OnDraw v obou případech, umístíte většinu kódu pro kreslení do této členské funkce.

Funkce OnDraw zpracovává vykreslování ovládacích prvků. Pokud není ovládací prvek aktivní, kontejner ovládacího prvku volá OnDraw, předává kontext zařízení kontejneru ovládacího prvku a souřadnice obdélníkové oblasti obsazené ovládacím prvkem.

Obdélník předaný rámcem členské funkci OnDraw obsahuje oblast obsazenou ovládacím prvkem. Pokud je ovládací prvek aktivní, levý horní roh ovládacího prvku je na souřadnicích (0, 0) a předaný kontext zařízení je určený pro podřízené okno, které obsahuje 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, kterou poskytuje Průvodce ovládacími prvky ActiveX MFC 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í elipsu 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 vykreslování ovládacího prvku byste neměli dělat předpoklady o stavu kontextu zařízení, který je funkci předáván jako parametr pdc. 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 kreslení ovládacího prvku je dalším krokem optimalizovat funkci OnDraw.

Výchozí implementace ovládacích prvků ActiveX 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ího prvku pomocí metasouborů

Ve většině případů parametr pdc 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 kontext zařízení přijatý pro vykreslování speciálním typem označovaným jako "metasouborový kontext zařízení". 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 mohou také rozhodnout vykreslit řídící obrázek pomocí DC 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 metasouborové DC předáno jako jeden z parametrů, architektura MFC provede volání COleControl::OnDrawMetafile. Vzhledem k tomu, že se jedná o virtuální členskou funkci, přepište tuto funkci v ovládací třídě, aby prováděla jakékoli 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 v kontextu zařízení metasouboru, musíte použít pouze členské funkce, které jsou podporovány v obou těchto kontextech. 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á funkci ovládacího prvku OnDraw, použijte pouze členské funkce, které jsou vhodné jak pro metasoubor, tak pro 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řídě CDC v referenčním dokumentu MFC.

Oblouk 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 metasouborovém DC. 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 metasouborový DC není ve skutečnosti přidružený k zařízení, nemůžete použít SetDIBits, GetDIBits a CreateDIBitmap s metasouborovým 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í DC 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

  1. V nabídce Upravit testovací kontejner klepněte na příkaz Vložit nový ovládací prvek.

  2. 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.

  3. 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.

Viz také

MFC – ovládací prvky ActiveX