TN014: Vlastní ovládací prvky
Tato poznámka popisuje podporu knihovny MFC pro automatické kreslení a vlastní ovládací prvky.Také popisuje dynamické vytváření podtříd a popisuje vztah mezi CWnd objekty a HWNDs.
Ukázková aplikace MFC CTRLTEST ukazuje, jak použít mnoho vlastních ovládacích prvků.Zobrazit zdrojový kód pro všeobecné knihovny MFC ukázkové CTRLTEST a nápovědu online.
Překreslování prvky/nabídky
Systém Windows poskytuje podporu pro vykreslování vlastníka ovládací prvky a nabídky pomocí zpráv systému Windows.Nabídku nebo ovládací prvek nadřazené okno obdrží tyto zprávy a volání funkce v reakci.Můžete přepsat tyto funkce přizpůsobit vzhled a chování ovládacího prvku překreslované nebo nabídky.
Knihovna MFC přímo podporuje vykreslování vlastníka s následující funkce:
Můžete přepsat tyto funkce do vašeho CWnd odvozené třídy implementovat chování vlastní kreslení.
Tento postup nevede k opakovaně použitelný kód.Pokud máte dva podobné ovládací prvky ve dvou různých CWnd třídy, musí implementovat chování vlastní ovládací prvek na dvou místech.Architektura vlastního výkresu podporovány knihovny MFC ovládacího prvku tento problém řeší.
Kreslit vlastní ovládací prvky a nabídky
Knihovna MFC poskytuje výchozí implementace (v CWnd a CMenu třídy) pro standardní překreslované zprávy.Tato implementace výchozí bude dekódovat parametrů vykreslování vlastníka a delegovat zprávy překreslované ovládací prvky nebo nabídky.Toto se nazývá Automatické kreslení protože výkresu kód je ve třídě ovládacího prvku nebo nabídky, ne v okně Vlastník.
Pomocí ovládacích prvků kreslit samostatně můžete vytvořit opakovaně použitelný ovládací prvek třídy, které slouží k zobrazení ovládacího prvku překreslované sémantiku.Kód pro vykreslení ovládacího prvku je ve třídě ovládacího prvku, nikoli nadřazeného objektu.Jedná se o objektově orientovaný přístup k programování vlastního ovládacího prvku.Přidejte vaše třídy nakreslit vlastní funkce v následujícím seznamu:
Automatické kreslení tlačítka:
CButton:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw this button
Kreslit vlastní nabídky:
CMenu:MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this menu CMenu:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this menu
Pro kreslení vlastní seznamy:
CListBox:MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this list box CListBox:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this list box CListBox:CompareItem(LPCOMPAREITEMSTRUCT); // insert code to compare two items in this list box if LBS_SORT CListBox:DeleteItem(LPDELETEITEMSTRUCT); // insert code to delete an item from this list box
Pro kreslení vlastního pole se seznamem:
CComboBox:MeasureItem(LPMEASUREITEMSTRUCT); // insert code to measure the size of an item in this combo box CComboBox:DrawItem(LPDRAWITEMSTRUCT); // insert code to draw an item in this combo box CComboBox:CompareItem(LPCOMPAREITEMSTRUCT); // insert code to compare two items in this combo box if CBS_SORT CComboBox:DeleteItem(LPDELETEITEMSTRUCT); // insert code to delete an item from this combo box
Podrobnosti o vykreslování vlastníka struktur (DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT, a DELETEITEMSTRUCT) naleznete v dokumentaci knihovny MFC k CWnd::OnDrawItem, CWnd::OnMeasureItem, CWnd::OnCompareItem, a CWnd::OnDeleteItem v uvedeném pořadí.
Pomocí kreslení vlastní ovládací prvky a nabídky
Kreslit vlastní nabídky, je nutné přepsat i OnMeasureItem a OnDrawItem metody.
Pro automatické kreslení seznamů a polí se seznamem, musí přepsat OnMeasureItem a OnDrawItem.Je nutné zadat LBS_OWNERDRAWVARIABLE stylu pro seznamy nebo CBS_OWNERDRAWVARIABLE styl pro pole se seznamem polí v dialogovém okně šablony.OWNERDRAWFIXED Styl nebude fungovat s nakreslit vlastní položky, protože položku Pevná výška je určena před nakreslit vlastní ovládací prvky jsou připojeny k seznamu. (Můžete použít metody CListBox::SetItemHeight a CComboBox::SetItemHeight k překonání tohoto omezení.)
Přepnutí OWNERDRAWVARIABLE styl způsobí, že systém použije pro NOINTEGRALHEIGHT styl ovládacího prvku.Vzhledem k tomu, že ovládací prvek nelze vypočítat integrální výšky s proměnnou velikostí položky, výchozí styl INTEGRALHEIGHT je ignorován a vždy je ovládací prvek NOINTEGRALHEIGHT.Pokud vaše položky jsou pevné výšky, můžete zabránit částečných položek je taženo určující velikost ovládacího prvku celé číslo násobek velikosti položky.
Pro automatické kreslení seznamů a polí se seznamem s LBS_SORT nebo CBS_SORT , je nutné změnit styl OnCompareItem metody.
Pro automatické kreslení seznamů a polí se seznamem, OnDeleteItem obvykle není přepsána.Můžete přepsat OnDeleteItem Pokud chcete provést zvláštní zpracování.Jeden případ, kdy by to bylo použitelné při další paměti či jiných prostředků, které jsou uloženy s každou položkou seznamu nebo pole se seznamem pole.
Příklady výkresu vlastní ovládací prvky a nabídky
Vzorek knihovny MFC Obecné CTRLTEST poskytuje ukázky nakreslit vlastní nabídky a nakreslit vlastní seznam.
Nejtypičtější příklad vlastního kreslení tlačítko je tlačítko rastrový obrázek.Rastrový obrázek tlačítko je tlačítko, které zobrazí jeden, dva nebo tři bitmapové obrazy v různých státech.Příkladem je součástí třídy MFC CBitmapButton.
Dynamické vytváření podtříd.
Někdy budete chtít změnit funkčnost objektu, který již existuje.V předchozích příkladech potřeba přizpůsobit ovládací prvky předtím, než v jakém byly vytvořeny.Dynamické vytváření podtříd umožňuje přizpůsobit ovládací prvek, který již byl vytvořen.
Vytváření podtříd je termín Windows pro nahrazování WndProc okna s přizpůsobeným WndProc a volání na staré WndProc pro výchozí funkce.
Tento model nelze zaměňovat s odvození třídy jazyka C++.Pro vyjasnění podmínek C++ základní třída a odvozené třídy jsou obdobou nadřazené třídy a podtřídy v objektovém modelu systému Windows.C++ odvození s vytváření podtříd MFC a Windows jsou funkčně podobné s tím rozdílem, C++ nepodporuje dynamické vytváření podtříd.
CWnd Třída poskytuje spojení mezi objekt jazyka C++ (odvozené z CWnd) a objekt okna systému Windows (označované jako HWND).
Existují tři běžné způsoby, které se týkají:
CWndvytvoří HWND.Můžete změnit chování v odvozené třídě vytvořením třídy odvozené z CWnd.HWND Je vytvořen, pokud aplikace volá CWnd::Create.
Přikládá žádost CWnd na stávající HWND.Chování existující okno nebude změněn.To je případ delegování a je umožněno tím, že volá CWnd::Attach alias existující HWND k CWnd objektu.
CWndje připojen ke stávajícímu HWND a mohou změnit chování v odvozené třídě.Toto se nazývá dynamické subclassing, protože jsme se mění chování a proto třídu objektu v době spuštění systému Windows.
Dynamické vytváření podtříd lze dosáhnout pomocí metody CWnd::SubclassWindow aCWnd::SubclassDlgItem.
Připojte oba rutin CWnd k existujícímu objektu HWND.SubclassWindowbere HWND přímo.SubclassDlgItemje pomocná funkce, která přijímá ID ovládacího prvku a nadřazené okno.SubclassDlgItemje určen pro připojení k dialogové okno Ovládací prvky vytvořené z dialogového okna šablony objektů jazyka C++.
Najdete CTRLTEST příklad pro několik příkladů použití SubclassWindow a SubclassDlgItem.