Sdílet prostřednictvím


O třídách oken (v kontextu programování)

Každá třída okna má přidruženou proceduru okna sdílenou všemi okny stejné třídy. Procedura okna zpracovává zprávy pro všechna okna této třídy, a proto řídí jejich chování a vzhled. Další informace naleznete v tématu Procedury okna.

Proces musí zaregistrovat třídu okna, než může vytvořit okno této třídy. Registrace třídy okna přidruží proceduru okna, styly tříd a další atributy třídy k názvu třídy. Když proces určuje název třídy ve funkci CreateWindow nebo CreateWindowEx , systém vytvoří okno s procedurou okna, styly a další atributy spojené s tímto názvem třídy.

Tato část popisuje následující témata.

Typy tříd oken

Existují tři typy tříd oken:

Tyto typy se liší v oboru a v tom, kdy a jak jsou registrovány a zničeny.

Systémové třídy

Systémová třída je třída okna registrovaná systémem. Mnoho systémových tříd je k dispozici pro všechny procesy, které se mají použít, zatímco ostatní jsou používány pouze interně systémem. Protože systém tyto třídy registruje, proces je nemůže zničit.

Systém zaregistruje systémové třídy pro proces při prvním volání jednoho z jeho vláken uživatele nebo rozhraní GDI (Windows Graphics Device Interface).

Každá aplikace obdrží vlastní kopii systémových tříd. Všechny 16bitové aplikace založené na Windows ve stejném VDM sdílejí systémové třídy, stejně jako na 16bitovém Windows.

Následující tabulka popisuje systémové třídy, které jsou k dispozici pro použití všemi procesy.

Třída Popis
Knoflík Třída pro tlačítko.
Kombinované pole Třída pro kombinované pole.
Upravit Třída pro ovládací prvek úpravy.
ListBox Třída pro seznamový rámeček.
MDIClient Třída pro okno klienta MDI.
Posuvník Třída pro posuvník.
Statický. Třída statického ovládacího prvku.

 

Následující tabulka popisuje systémové třídy, které jsou k dispozici pouze pro použití systémem. Jsou zde uvedeny pro úplnost.

Třída Popis
kombinované seznamové pole Třída seznamového pole obsažená v kombinovaném poli.
DDEMLEvent Třída pro události DDEML (Dynamic Data Exchange Management Library).
Zpráva Třída pro okno pouze se zprávou.
#32768 Třída pro nabídku.
#32769 Třída pro okno plochy.
#32770 Třída dialogového okna.
#32771 Třída pro okno přepínače úloh.
#32772 Třída pro názvy ikon.

 

Globální třídy aplikací

Globální třída aplikace je třída okna registrovaná spustitelným souborem nebo knihovnou DLL, která je k dispozici pro všechny ostatní moduly v procesu. Například .dll může volat funkci RegisterClassEx k registraci třídy okna, která definuje vlastní ovládací prvek jako globální třídu aplikace, aby proces, který načte .dll může vytvářet instance vlastního ovládacího prvku.

Chcete-li vytvořit třídu, kterou lze použít v každém procesu, vytvořte třídu pro okno v .dll a načtěte .dll v každém procesu. Pokud chcete načíst .dll v každém procesu, přidejte jeho název do hodnoty AppInit_DLLs v následujícím klíči registru.

\ HKEY_LOCAL_MACHINESoftware\Microsoft\Windows NT\CurrentVersion\Windows

Při každém spuštění procesu systém načte zadané .dll v kontextu nově spuštěného procesu před voláním funkce vstupního bodu. .dll musí během inicializační procedury zaregistrovat třídu a musí určit styl CS_GLOBALCLASS . Další informace naleznete v tématu Styly tříd.

Pokud chcete odebrat globální třídu aplikace a uvolnit úložiště přidružené k ní, použijte funkci UnregisterClass .

Místní třídy aplikace

Místní třída aplikace je libovolná třída okna, kterou spustitelný soubor nebo .dll registruje k jeho výhradnímu použití. I když můžete zaregistrovat libovolný počet místních tříd, obvykle se zaregistruje jenom jedna. Tato třída okna podporuje proceduru okna hlavního okna aplikace.

Systém zničí místní třídu, když se modul, který ho zaregistroval, zavře. Aplikace může také použít funkci UnregisterClass k odebrání místní třídy a uvolnění úložiště přidruženého k ní.

Jak systém vyhledá třídu okna

Systém udržuje seznam struktur pro každý ze tří typů tříd oken. Když aplikace volá CreateWindow nebo CreateWindowEx funkce k vytvoření okna se zadanou třídou, systém pomocí následujícího postupu vyhledá třídu.

  1. Vyhledejte v seznamu místních tříd aplikace třídu se zadaným názvem, jehož popisovač instance odpovídá popisovači instance modulu. (Stejný název může použít několik modulů k registraci místních tříd ve stejném procesu.)
  2. Pokud název není v seznamu místních tříd aplikace, vyhledejte seznam globálních tříd aplikace.
  3. Pokud název není v globálním seznamu tříd aplikace, vyhledejte seznam systémových tříd.

Všechna okna vytvořená aplikací používají tento postup, včetně oken vytvořených systémem jménem aplikace, jako jsou dialogová okna. Systémové třídy je možné přepsat, aniž by to mělo vliv na jiné aplikace. To znamená, že aplikace může zaregistrovat místní třídu aplikace se stejným názvem jako systémová třída. Tím se nahradí systémová třída v kontextu aplikace, ale nebrání jiným aplikacím v používání systémové třídy.

Registrace třídy okna

Třída okna definuje atributy okna, jako je jeho styl, ikona, kurzor, nabídka a procedura okna. Prvním krokem při registraci třídy okna je vyplnění struktury WNDCLASSEX informacemi o třídě okna. Další informace naleznete v části Prvky třídy okna. Dále předejte strukturu funkci RegisterClassEx . Další informace naleznete v tématu Použití tříd oken.

Chcete-li zaregistrovat globální třídu aplikace, zadejte styl CS_GLOBALCLASS ve členu stylu ve struktuře WNDCLASSEX. Při registraci místní třídy aplikace nezadávejte styl CS_GLOBALCLASS .

Pokud zaregistrujete třídu okna pomocí ANSI verze RegisterClassEx, RegisterClassExA, aplikace požaduje, aby systém předal textové parametry zpráv do oken vytvořené třídy pomocí znakové sady ANSI; Pokud zaregistrujete třídu pomocí unicode verze RegisterClassEx, RegisterClassExW, aplikace požaduje, aby systém předal textové parametry zpráv do oken vytvořené třídy pomocí znakové sady Unicode. Funkce IsWindowUnicode umožňuje aplikacím dotazovat povahu každého okna. Další informace o funkcích ANSI a Unicode najdete v tématu Konvence prototypů funkcí.

Spustitelný soubor nebo knihovna DLL, která zaregistrovala třídu, je vlastníkem třídy. Systém určuje vlastnictví třídy ze členu hInstance struktury WNDCLASSEX předané funkci RegisterClassEx při registraci třídy. U knihoven DLL musí být člen hInstance popisovačem instance .dll.

Třída není zničena, když je .dll, která ji vlastní, uvolněna. Pokud systém vyvolá proceduru okna pro okno této třídy, způsobí to porušení přístupu, protože .dll obsahující proceduru okna již není v paměti. Proces musí zničit všechna okna používající třídu před uvolněním .dll a volání funkce UnregisterClass .

Prvky třídy okna

Prvky třídy okna definují výchozí chování oken patřících do třídy. Aplikace, která registruje třídu okna přiřadí elementy ke třídě nastavením odpovídajících členů ve struktuře WNDCLASSEX a předání struktury funkci RegisterClassEx . Funkce GetClassInfoEx a GetClassLong načítají informace o dané třídě okna. Funkce SetClassLong změní prvky místní nebo globální třídy, které aplikace již zaregistrovala.

I když se úplná třída okna skládá z mnoha prvků, systém vyžaduje pouze, aby aplikace zadá název třídy, adresu window-procedure a popisovač instance. Pomocí dalších prvků definujte výchozí atributy pro okna třídy, například tvar kurzoru a obsah nabídky okna. Je nutné inicializovat všechny nepoužívané členy struktury WNDCLASSEX na nulu nebo NULL. Prvky třídy okna jsou znázorněny v následující tabulce.

prvek Účel
název třídy Rozlišuje třídu od jiných registrovaných tříd.
Adresa procedury okna Ukazatel na funkci, která zpracovává všechny zprávy odeslané do oken ve třídě a definuje chování okna.
Popisovač instance Identifikuje aplikaci nebo .dll, která třídu zaregistrovala.
Kurzor třídy Definuje kurzor myši, který systém zobrazí pro okno třídy.
ikony tříd Definuje velkou ikonu a malou ikonu.
Štětec pro pozadí třídy Definuje barvu a vzor, které vyplňují klientskou oblast při otevření nebo malování okna.
Menu Třídy Určuje výchozí nabídku pro okna, která explicitně nedefinují nabídku.
Styly tříd Definuje, jak aktualizovat okno po přesunutí nebo změně jeho velikosti, jak zpracovat dvojité kliknutí myši, jak přidělit prostor pro kontext zařízení a další aspekty okna.
Paměť extra třídy Určuje množství dodatečné paměti v bajtech, které by měl systém rezervovat pro třídu. Všechna okna ve třídě sdílejí dodatečnou paměť a mohou ji použít pro jakýkoliv účel definovaný aplikací. Systém inicializuje tuto paměť na nulu.
Dodatečná paměť pro okna Určuje množství paměti navíc v bajtech, které by měl systém rezervovat pro každé okno patřící do třídy. Dodatečnou paměť lze použít pro libovolný účel definovaný aplikací. Systém inicializuje tuto paměť na nulu.

 

Název třídy

Každá třída okna potřebuje název třídy k rozlišení jedné třídy od druhé. Přiřaďte název třídy nastavením členu lpszClassName struktury WNDCLASSEX na adresu řetězce ukončeného nulou, který určuje jméno. Vzhledem k tomu, že třídy oken jsou specifické pro procesy, musí být názvy tříd oken jedinečné pouze v rámci stejného procesu. Protože názvy tříd zabírají místo v tabulce privátních atomů systému, měli byste zachovat řetězce názvů tříd co nejkratší.

Funkce GetClassName načte název třídy, do které dané okno patří.

Adresa procedury okna rozhraní

Každá třída potřebuje adresu procedury okna, která definuje vstupní bod procedury okna sloužící ke zpracování všech zpráv pro okna ve třídě. Systém předá do procedury zprávy, když vyžaduje, aby okno provádělo úkoly, jako je například malování klientské oblasti nebo reakce na vstup od uživatele. Proces přiřadí proceduru okna třídě tím, že zkopíruje její adresu do člena lpfnWndProc struktury WNDCLASSEX. Další informace naleznete v tématu Procedury okna.

Popisovač instance

Každá třída okna vyžaduje popisovač instance k identifikaci aplikace nebo .dll, která třídu zaregistrovala. Systém vyžaduje, aby obslužné rutiny instance sledovaly všechny moduly. Systém přiřadí popisovač každé kopii spuštěného spustitelného souboru nebo .dll.

Systém předá identifikátor instance funkci vstupního bodu každého spustitelného (viz WinMain) a .dll (viz DllMain). Spustitelný soubor nebo komponenta označená jako .dll přiřadí tento popisovač instance třídě tím, že jej zkopíruje do členu hInstance struktury WNDCLASSEX.

Kurzor třídy

Kurzor třídy definuje tvar kurzoru, když je v klientské oblasti okna ve třídě. Systém automaticky nastaví kurzor na daný obrazec, když kurzor přejde do klientské oblasti okna a zajistí, aby tento obrazec zůstal v klientské oblasti. Pokud chcete přiřadit tvar kurzoru ke třídě okna, načtěte předdefinovaný tvar kurzoru pomocí funkce LoadCursor a pak přiřaďte vrácený handle kurzoru členu hCursor struktury WNDCLASSEX. Případně zadejte vlastní prostředek kurzoru a pomocí funkce LoadCursor ji načtěte z prostředků aplikace.

Systém nevyžaduje kurzor pro třídy. Pokud aplikace nastaví člena hCursor struktury WNDCLASSEX na NULL, není definován žádný kurzor třídy. Systém předpokládá, že okno nastaví obrazec kurzoru pokaždé, když se kurzor přesune do okna. Okno může nastavit obrazec kurzoru voláním Funkce SetCursor vždy, když okno obdrží WM_MOUSEMOVE zprávu. Další informace o kurzorech naleznete v tématu Kurzory.

Ikony tříd

Ikona třídy je obrázek, který systém používá k reprezentaci okna konkrétní třídy. Aplikace může mít dvě ikony tříd – jednu velkou a jednu malou. Systém zobrazuje ikonu třídy okna v okně přepínače úloh, které se objeví při stisku kláves ALT+TAB, a v zobrazení velkých ikon na hlavním panelu a v Průzkumníku. Malá ikona třídy se zobrazí v titulku okna a v malých zobrazeních ikon na hlavním panelu a v Průzkumníku.

Pokud chcete přiřadit velkou a malou ikonu ke třídě okna, zadejte úchyty ikon v hIcon a hIconSm členů struktury WNDCLASSEX . Rozměry ikon musí odpovídat požadovaným rozměrům pro velké a malé ikony tříd. U ikony velké třídy můžete určit požadované rozměry zadáním hodnot SM_CXICON a SM_CYICON ve volání funkce GetSystemMetrics . U malé ikony třídy zadejte SM_CXSMICON a SM_CYSMICON hodnoty. Informace najdete v tématu Ikony.

Pokud aplikace nastaví členy hIcon a hIconSm struktury WNDCLASSEX na HODNOTU NULL, systém použije výchozí ikonu aplikace jako velké a malé ikony třídy pro třídu okna. Pokud zadáte ikonu velké třídy, ale ne malou, systém vytvoří malou ikonu třídy založenou na velké třídě. Pokud však zadáte malou ikonu třídy, ale ne velkou, systém použije výchozí ikonu aplikace jako ikonu velké třídy a zadanou ikonu jako malou ikonu třídy.

Pro konkrétní okno můžete přepsat velkou nebo malou ikonu třídy pomocí zprávy WM_SETICON. Načíst aktuální velkou nebo malou ikonu třídy můžete pomocí zprávy WM_GETICON.

Štětec na pozadí pro třídu

Štětka pozadí třídy připraví oblast klienta okna pro následné vykreslování aplikací. Systém pomocí štětce vyplní klientskou oblast plnou barvou nebo vzorem, čímž odebere všechny předchozí obrázky z tohoto umístění bez ohledu na to, jestli patří do okna, nebo ne. Systém upozorní okno, že jeho pozadí by mělo být malováno odesláním WM_ERASEBKGND zprávy do okna. Další informace naleznete v tématu Štětce.

Pokud chcete přiřadit štětec na pozadí ke třídě, vytvořte štětec pomocí příslušných funkcí GDI a přiřaďte úchyt vráceného štětce členu hbrBackground ve struktuře WNDCLASSEX.

Místo vytvoření štětce může aplikace nastavit člen hbrBackground na jednu ze standardních hodnot barev systému. Seznam standardních systémových barevných hodnot naleznete v tématu SetSysColors.

Pokud chcete použít standardní systémovou barvu, musí aplikace zvýšit hodnotu barvy pozadí o jednu. Například COLOR_BACKGROUND + 1 je barva pozadí systému. Alternativně můžete pomocí funkce GetSysColorBrush načíst úchyt na štětec, který odpovídá standardní systémové barvě, a pak určit popisovač v hbrBackground členu WNDCLASSEX struktury.

Systém nevyžaduje, aby třída okna měla výchozí barvu pozadí třídy. Pokud je tento parametr nastaven na hodnotu NULL, okno musí při přijetí zprávy WM_ERASEBKGND nakreslit vlastní pozadí.

Nabídka Třídy

Nabídka třídy definuje výchozí nabídku, kterou mají používat okna ve třídě, pokud není při vytváření oken uvedena žádná explicitní nabídka. Nabídka je seznam příkazů, ze kterých si uživatel může vybrat akce, které má aplikace provést.

Nabídku můžete přiřadit ke třídě nastavením člena lpszMenuName struktury WNDCLASSEX na adresu řetězce ukončeného znakem null, který specifikuje název prostředku nabídky. V dané aplikaci se předpokládá, že nabídka (menu) je prostředkem. Systém automaticky načte nabídku v případě potřeby. Pokud je resurs nabídky identifikován celým číslem, nikoli názvem, může aplikace nastavit člen lpszMenuName na toto celé číslo použitím makra MAKEINTRESOURCE před přiřazením této hodnoty.

Systém nevyžaduje nabídku pro třídy. Pokud aplikace nastaví člena lpszMenuName struktury WNDCLASSEX na NULL, okna ve třídě nemají žádné menu lišty. I když není zadána žádná nabídka třídy, může aplikace při vytváření okna definovat lištu nabídek pro okno.

Pokud je pro třídu uvedena nabídka a vytvoří se podřízené okno této třídy, bude nabídka ignorována. Pro více informací se podívejte na Nabídky.

Styly tříd

Styly tříd definují další prvky třídy okna. Dva nebo více stylů lze kombinovat pomocí bitového operátoru OR (|). Chcete-li přiřadit styl ke třídě okna, přiřaďte styl členu styluWNDCLASSEX struktury. Seznam stylů tříd najdete v tématu Styly tříd okna.

Třídy a kontexty zařízení

Kontext zařízení je speciální sada hodnot, které aplikace používají pro kreslení v klientské oblasti jejich oken. Systém vyžaduje kontext zařízení pro každé okno na displeji, ale umožňuje určitou flexibilitu v tom, jak systém ukládá a zpracovává tento kontext zařízení.

Pokud není explicitně uveden žádný styl kontextu zařízení, systém předpokládá, že každé okno používá kontext zařízení načtený z fondu kontextů udržovaných systémem. V takových případech musí každé okno načíst a inicializovat kontext zařízení před malováním a uvolnit ho po malování.

Aby se zabránilo načtení kontextu zařízení pokaždé, když potřebuje malovat v okně, může aplikace zadat CS_OWNDC styl třídy okna. Tento styl třídy směruje systém k vytvoření soukromého kontextu zařízení – to znamená přidělení jedinečného kontextu zařízení pro každé okno třídy. Aplikace potřebuje pouze jednou načíst kontext a pak ho použít pro všechny následné obrazy.

Paměť extra třídy

Systém udržuje strukturu WNDCLASSEX interně pro každou třídu oken v systému. Když aplikace zaregistruje třídu okna, může směrovat systém k přidělení a připojení řady dalších bajtů paměti na konec struktury WNDCLASSEX . Tato paměť se nazývá paměť extra třídy a je sdílena všemi okny patřícími do třídy. Paměť třídy navíc slouží k uložení jakýchkoli informací týkajících se třídy.

Vzhledem k tomu, že je z místní haldy systému přidělena dodatečná paměť, měla by aplikace střídmě používat zvláštní paměť třídy. Funkce RegisterClassEx selže, pokud je požadovaná velikost paměti extra třídy větší než 40 bajtů. Pokud aplikace vyžaduje více než 40 bajtů, měla by přidělit vlastní paměť a uložit ukazatel na paměť v paměti extra třídy.

Funkce SetClassWord a SetClassLong zkopírují hodnotu do paměti extra třídy. K načtení hodnoty z paměti extra třídy použijte funkce GetClassWord a GetClassLong . CbClsExtra člen struktury WNDCLASSEX určuje množství paměti extra třídy, která se má přidělit. Aplikace, která nepoužívá paměť extra třídy musí inicializovat cbClsExtra člen na nulu.

Dodatečná paměť pro okna

Systém udržuje interní datovou strukturu pro každé okno. Při registraci třídy okna může aplikace určit řadu dalších bajtů paměti, označované jako dodatečná paměť okna. Při vytváření okna třídy systém přidělí a připojí k konci struktury okna zadanou velikost paměti okna navíc. Aplikace může tuto paměť použít k ukládání dat specifických pro okna.

Vzhledem k tomu, že je z místní haldy systému alokována dodatečná paměť, měla by aplikace střídmě využívat dodatečnou paměť pro okno. Funkce RegisterClassEx selže, pokud je požadovaná velikost paměti okna větší než 40 bajtů. Pokud aplikace vyžaduje více než 40 bajtů, měla by přidělit vlastní paměť a uložit ukazatel na paměť v dodatečné paměti okna.

Funkce SetWindowLong zkopíruje hodnotu do dodatečné paměti. Funkce GetWindowLong načte hodnotu z dodatečné paměti. Člen cbWndExtra struktury WNDCLASSEX určuje množství dodatečné paměti pro okno, které se má přidělit. Aplikace, která nepoužívá paměť, musí inicializovat cbWndExtra na nulu.