Udostępnij za pośrednictwem


Klasy okien — informacje

Każda klasa okien ma skojarzoną procedurę okna współużytkowaną przez wszystkie okna tej samej klasy. Procedura okna przetwarza komunikaty dla wszystkich okien tej klasy i w związku z tym kontroluje ich zachowanie i wygląd. Aby uzyskać więcej informacji, zobacz Procedury okien.

Aby można było utworzyć okno tej klasy, proces musi zarejestrować klasę okien. Zarejestrowanie klasy okna kojarzy procedurę okna, style klas i inne atrybuty klasy z nazwą klasy. Gdy proces określa nazwę klasy w CreateWindow lub createWindowEx funkcji, system tworzy okno z procedurą okna, stylami i innymi atrybutami skojarzonymi z tą nazwą klasy.

W tej sekcji omówiono następujące tematy.

Typy klas okien

Istnieją trzy typy klas okien:

Te typy różnią się zakresem i sposobem ich rejestrowania i niszczenia.

Klasy systemowe

Klasa systemowa jest klasą okien zarejestrowaną przez system. Wiele klas systemowych jest dostępnych dla wszystkich procesów do użycia, podczas gdy inne są używane tylko wewnętrznie przez system. Ponieważ system rejestruje te klasy, proces nie może ich zniszczyć.

System rejestruje klasy systemowe dla procesu po raz pierwszy jeden z jego wątków wywołuje funkcję User lub Windows Graphics Device Interface (GDI).

Każda aplikacja otrzymuje własną kopię klas systemowych. Wszystkie 16-bitowe aplikacje oparte na systemie Windows w tej samej maszynie wirtualnej współużytkują klasy systemowe, podobnie jak w 16-bitowym systemie Windows.

W poniższej tabeli opisano klasy systemowe, które są dostępne do użycia przez wszystkie procesy.

Klasa Opis
Guzik Klasa przycisku.
Pole kombi Klasa pola kombi.
Redagować Klasa kontrolki edycji.
Pole listy Klasa pola listy.
MDIClient Klasa okna klienta MDI.
Pasek przewijania Klasa paska przewijania.
Statyczny Klasa dla kontrolki statycznej.

 

W poniższej tabeli opisano klasy systemowe, które są dostępne tylko do użycia przez system. Są one wymienione tutaj ze względu na kompletność.

Klasa Opis
ComboLBox Klasa pola listy zawartego w polu kombi.
DDEMLEvent Klasa zdarzeń dynamicznej biblioteki zarządzania exchange danych (DDEML).
Komunikat Klasa okna tylko dla komunikatów.
#32768 Klasa menu.
#32769 Klasa okna pulpitu.
#32770 Klasa okna dialogowego.
#32771 Klasa okna przełącznika zadań.
#32772 Klasa tytułów ikon.

 

Klasy globalne aplikacji

Klasa globalna aplikacji to klasa okien zarejestrowana przez plik wykonywalny lub bibliotekę DLL dostępną dla wszystkich innych modułów w procesie. Na przykład .dll może wywołać funkcję RegisterClassEx, aby zarejestrować klasę okien definiującą niestandardową kontrolkę jako klasę globalną aplikacji, aby proces, który ładuje .dll, może tworzyć wystąpienia kontrolki niestandardowej.

Aby utworzyć klasę, która może być używana w każdym procesie, utwórz klasę okien w .dll i załaduj .dll w każdym procesie. Aby załadować .dll w każdym procesie, dodaj jego nazwę do wartości AppInit_DLLs w następującym kluczu rejestru:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows

Za każdym razem, gdy rozpocznie się proces, system ładuje określone .dll w kontekście nowo uruchomionego procesu przed wywołaniem funkcji punktu wejścia. .dll musi zarejestrować klasę podczas procedury inicjowania i musi określać styl CS_GLOBALCLASS. Aby uzyskać więcej informacji, zobacz Style klas.

Aby usunąć klasę globalną aplikacji i zwolnić skojarzony z nią magazyn, użyj funkcji UnregisterClass.

Klasy lokalne aplikacji

Klasa lokalna aplikacji jest dowolną klasą okien, którą plik wykonywalny lub .dll rejestruje się do wyłącznego użytku. Chociaż można zarejestrować dowolną liczbę klas lokalnych, zwykle rejestruje się tylko jeden. Ta klasa okien obsługuje procedurę okna głównego okna aplikacji.

System niszczy klasę lokalną, gdy moduł, który go zarejestrował, zostanie zamknięty. Aplikacja może również użyć funkcji UnregisterClass, aby usunąć klasę lokalną i zwolnić skojarzony z nim magazyn.

Jak system lokalizuje klasę okien

System utrzymuje listę struktur dla każdego z trzech typów klas okien. Gdy aplikacja wywołuje funkcję CreateWindow lub CreateWindowEx w celu utworzenia okna z określoną klasą, system używa następującej procedury do zlokalizowania klasy.

  1. Przeszukaj listę klas lokalnych aplikacji dla klasy o określonej nazwie, której dojście wystąpienia pasuje do uchwytu wystąpienia modułu. (Kilka modułów może używać tej samej nazwy do rejestrowania klas lokalnych w tym samym procesie).
  2. Jeśli nazwa nie znajduje się na liście klas lokalnych aplikacji, wyszukaj listę klas globalnych aplikacji.
  3. Jeśli nazwa nie znajduje się na liście klas globalnych aplikacji, wyszukaj listę klas systemowych.

Wszystkie okna utworzone przez aplikację używają tej procedury, w tym okien utworzonych przez system w imieniu aplikacji, takich jak okna dialogowe. Istnieje możliwość zastąpienia klas systemowych bez wpływu na inne aplikacje. Oznacza to, że aplikacja może zarejestrować klasę lokalną aplikacji o takiej samej nazwie jak klasa systemowa. Spowoduje to zastąpienie klasy systemowej w kontekście aplikacji, ale nie uniemożliwia innym aplikacjom korzystania z klasy systemowej.

Rejestrowanie klasy okien

Klasa okna definiuje atrybuty okna, takie jak jego styl, ikona, kursor, menu i procedura okna. Pierwszym krokiem rejestrowania klasy okna jest wypełnienie struktury WNDCLASSEX informacjami o klasie okien. Aby uzyskać więcej informacji, zobacz Elementy klasy okien. Następnie przekaż strukturę do funkcji RegisterClassEx. Aby uzyskać więcej informacji, zobacz Using Window Classes.

Aby zarejestrować klasę globalną aplikacji, określ styl CS_GLOBALCLASS w stylu składowej struktury WNDCLASSEX. Podczas rejestrowania klasy lokalnej aplikacji nie należy określać stylu CS_GLOBALCLASS.

Jeśli zarejestrujesz klasę okien przy użyciu wersji ANSI RegisterClassEx, RegisterClassExA, aplikacja żąda, aby system przekazał parametry tekstowe komunikatów do okien utworzonej klasy przy użyciu zestawu znaków ANSI; Jeśli zarejestrujesz klasę przy użyciu wersji Unicode RegisterClassEx, RegisterClassExW, aplikacja żąda, aby system przekazał parametry tekstowe komunikatów do okien utworzonej klasy przy użyciu zestawu znaków Unicode. Funkcja IsWindowUnicode umożliwia aplikacjom wykonywanie zapytań dotyczących charakteru każdego okna. Aby uzyskać więcej informacji na temat funkcji ANSI i Unicode, zobacz Conventions for Function Prototypes.

Plik wykonywalny lub biblioteka DLL, która zarejestrowała klasę, jest właścicielem klasy. System określa własność klasy z hInstance składowej WNDCLASSEX przekazanej do funkcji RegisterClassEx po zarejestrowaniu klasy. W przypadku bibliotek DLL element członkowski hInstance musi być dojściem do wystąpienia .dll.

Klasa nie jest niszczona, gdy .dll, która jest właścicielem, jest rozładowana. W związku z tym jeśli system wywołuje procedurę okna dla okna tej klasy, spowoduje naruszenie dostępu, ponieważ .dll zawierające procedurę okna nie jest już w pamięci. Proces musi zniszczyć wszystkie okna używające klasy przed zwolnieniem .dll i wywołać funkcję UnregisterClass.

Elementy klasy okna

Elementy klasy okna definiują domyślne zachowanie okien należących do klasy. Aplikacja, która rejestruje klasę okien, przypisuje elementy do klasy, ustawiając odpowiednie elementy członkowskie w strukturze WNDCLASSEX i przekazując strukturę do funkcji RegisterClassEx. Funkcje GetClassInfoEx i GetClassLong pobierają informacje o danej klasie okien. Funkcja SetClassLong zmienia elementy lokalnej lub globalnej klasy, którą aplikacja już zarejestrowała.

Mimo że kompletna klasa okien składa się z wielu elementów, system wymaga tylko, aby aplikacja podać nazwę klasy, adres procedury okna i uchwyt wystąpienia. Użyj innych elementów, aby zdefiniować atrybuty domyślne dla okien klasy, takie jak kształt kursora i zawartość menu okna. Należy zainicjować wszystkie nieużywane elementy członkowskie struktury WNDCLASSEX do zera lub null. Elementy klasy okna są pokazane w poniższej tabeli.

Pierwiastek Cel
nazwa klasy Rozróżnia klasę od innych zarejestrowanych klas.
adres procedury okna Wskaźnik do funkcji, która przetwarza wszystkie komunikaty wysyłane do okien w klasie i definiuje zachowanie okna.
Dojście wystąpienia Identyfikuje aplikację lub .dll, która zarejestrowała klasę.
kursora klasy Definiuje kursor myszy wyświetlany przez system dla okna klasy.
ikony klas Definiuje dużą ikonę i małą ikonę.
pędzla tła klasy Definiuje kolor i wzorzec, który wypełnia obszar klienta podczas otwierania lub malowania okna.
menu klas Określa domyślne menu dla okien, które nie definiują jawnie menu.
style klas Definiuje sposób aktualizowania okna po przeniesieniu lub zmianie jego rozmiaru, jak przetwarzać dwukrotne kliknięcia myszy, jak przydzielić miejsce dla kontekstu urządzenia i inne aspekty okna.
pamięci klasy dodatkowej Określa ilość dodatkowej pamięci w bajtach, które system powinien zarezerwować dla klasy. Wszystkie okna w klasie współdzielą dodatkową pamięć i mogą jej używać do dowolnego celu zdefiniowanego przez aplikację. System inicjuje tę pamięć do zera.
dodatkowe pamięci okna Określa ilość dodatkowej pamięci w bajtach, które system powinien zarezerwować dla każdego okna należącego do klasy. Dodatkową pamięć można używać do dowolnego celu zdefiniowanego przez aplikację. System inicjuje tę pamięć do zera.

 

Nazwa klasy

Każda klasa okien wymaga nazwa klasy, aby odróżnić jedną klasę od innej. Przypisz nazwę klasy, ustawiając lpszClassName składową struktury WNDCLASSEX na adres ciągu zakończonego wartością null, który określa nazwę. Ponieważ klasy okien są specyficzne dla procesu, nazwy klas okien muszą być unikatowe tylko w ramach tego samego procesu. Ponadto, ponieważ nazwy klas zajmują miejsce w prywatnej tabeli atomów systemu, należy zachować ciągi nazw klas tak krótko, jak to możliwe.

Funkcja GetClassName pobiera nazwę klasy, do której należy dane okno.

Adres procedury okna

Każda klasa potrzebuje adresu procedury okna, aby zdefiniować punkt wejścia procedury okna używanej do przetwarzania wszystkich komunikatów dla okien w klasie. System przekazuje komunikaty do procedury, gdy wymaga okna do wykonywania zadań, takich jak malowanie obszaru klienta lub reagowanie na dane wejściowe od użytkownika. Proces przypisuje procedurę okna do klasy, kopiując jej adres do lpfnWndPro c elementu członkowskiego WNDCLASSEX. Aby uzyskać więcej informacji, zobacz Procedury okien.

Uchwyt wystąpienia

Każda klasa okien wymaga dojścia wystąpienia w celu zidentyfikowania aplikacji lub .dll, które zarejestrowały klasę. System wymaga obsługi wystąpień, aby śledzić wszystkie moduły. System przypisuje dojście do każdej kopii uruchomionego pliku wykonywalnego lub .dll.

System przekazuje dojście wystąpienia do funkcji punktu wejścia każdego pliku wykonywalnego (zobacz WinMain) i .dll (zobacz DllMain). Plik wykonywalny lub .dll przypisuje do klasy obsługę tego wystąpienia, kopiując go do hInstance składowej struktury WNDCLASSEX.

Kursor klasy

Kursor klasy definiuje kształt kursora, gdy znajduje się on w obszarze klienta okna w klasie . System automatycznie ustawia kursor na dany kształt, gdy kursor przechodzi do obszaru klienta okna i zapewnia, że zachowuje ten kształt, gdy pozostaje w obszarze klienta. Aby przypisać kształt kursora do klasy okna, załaduj wstępnie zdefiniowany kształt kursora przy użyciu funkcji LoadCursor, a następnie przypisz zwrócony uchwyt kursora do elementu członkowskiegoWNDCLASSEX struktury. Alternatywnie podaj niestandardowy zasób kursora i użyj funkcji LoadCursor, aby załadować ją z zasobów aplikacji.

System nie wymaga kursora klasy. Jeśli aplikacja ustawia hCursor składową struktury WNDCLASSEX w celu null, nie zdefiniowano kursora klasy. System zakłada, że okno ustawia kształt kursora za każdym razem, gdy kursor przechodzi do okna. Okno może ustawić kształt kursora, wywołując funkcję SetCursor za każdym razem, gdy okno odbiera komunikat WM_MOUSEMOVE. Aby uzyskać więcej informacji na temat kursorów, zobacz Kursory.

Ikony klas

Ikona klasy jest obrazem używanym przez system do reprezentowania okna określonej klasy. Aplikacja może mieć dwie ikony klasy — jedną dużą i jedną małą. System wyświetla okno dużą ikonę klasy w oknie przełącznika zadań, które jest wyświetlane, gdy użytkownik naciska alt+TAB, a w dużych widokach ikon paska zadań i eksploratora. Ikona małej klasy jest wyświetlana na pasku tytułu okna i w małych widokach ikon paska zadań i eksploratora.

Aby przypisać dużą i małą ikonę do klasy okien, określ uchwyty ikon w strukturze hIcon i hIconSm składowych WNDCLASSEX. Wymiary ikon muszą być zgodne z wymaganymi wymiarami dla ikon dużych i małych klas. Dla dużej ikony klasy można określić wymagane wymiary, określając wartości SM_CXICON i SM_CYICON w wywołaniu funkcji GetSystemMetrics. Dla małej ikony klasy określ wartości SM_CXSMICON i SM_CYSMICON. Aby uzyskać więcej informacji, zobacz Ikony.

Jeśli aplikacja ustawia hIcon i hIconSm składowych struktury WNDCLASSEX, aby NULL, system używa domyślnej ikony aplikacji jako dużych i małych ikon klasy dla klasy okna. Jeśli określisz ikonę dużej klasy, ale nie małą, system utworzy małą ikonę klasy na podstawie dużej. Jeśli jednak określisz małą ikonę klasy, ale nie dużą, system używa domyślnej ikony aplikacji jako ikony dużej klasy i określonej ikony jako ikony małej klasy.

Możesz zastąpić ikonę dużej lub małej klasy dla określonego okna przy użyciu komunikatu WM_SETICON. Możesz pobrać bieżącą ikonę dużej lub małej klasy przy użyciu komunikatu WM_GETICON.

Szczotka tła klasy

Szczotka tła klasy przygotowuje obszar klienta okna do późniejszego rysowania przez aplikację. System używa pędzla, aby wypełnić obszar klienta stałym kolorem lub wzorcem, usuwając w ten sposób wszystkie poprzednie obrazy z tej lokalizacji, niezależnie od tego, czy należą do okna, czy nie. System powiadamia okno, że jego tło powinno zostać malowane przez wysłanie komunikatu WM_ERASEBKGND do okna. Aby uzyskać więcej informacji, zobacz Brushes.

Aby przypisać szczotkę tła do klasy, utwórz szczotkę przy użyciu odpowiednich funkcji GDI i przypisz zwrócony uchwyt pędzla do hbrBackground składowej struktury WNDCLASSEX.

Zamiast tworzyć szczotkę, aplikacja może ustawić element hbrBackground na jedną ze standardowych wartości kolorów systemu. Aby uzyskać listę standardowych wartości kolorów systemowych, zobacz SetSysColors.

Aby użyć standardowego koloru systemu, aplikacja musi zwiększyć wartość koloru tła o jeden. Na przykład COLOR_BACKGROUND + 1 jest kolorem tła systemu. Alternatywnie można użyć funkcji GetSysColorBrush, aby pobrać uchwyt do pędzla, który odpowiada standardowemu kolorowi systemu, a następnie określić uchwyt w hbrBackground składowej WNDCLASSEX struktury.

System nie wymaga, aby klasa okien miała szczotkę tła klasy. Jeśli ten parametr ma wartość null, okno musi malować własne tło za każdym razem, gdy otrzyma komunikat WM_ERASEBKGND.

Menu Klasy

Menu klasy definiuje domyślne menu, które ma być używane przez okna w klasie, jeśli nie zostanie podane jawne menu podczas tworzenia okien. Menu to lista poleceń, z których użytkownik może wybrać akcje do wykonania przez aplikację.

Menu można przypisać do klasy, ustawiając lpszMenuName składowej WNDCLASSEX na adres ciągu zakończonego wartością null, który określa nazwę zasobu menu. Przyjmuje się, że menu jest zasobem w danej aplikacji. System automatycznie ładuje menu w razie potrzeby. Jeśli zasób menu jest identyfikowany przez liczbę całkowitą, a nie przez nazwę, aplikacja może ustawić element członkowski lpszMenuName do tej liczby całkowitej, stosując makra MAKEINTRESOURCE przed przypisaniem wartości.

System nie wymaga menu klasy. Jeśli aplikacja ustawia lpszMenuName elementu członkowskiego WNDCLASSEX struktury NULL, okna w klasie nie mają pasków menu. Nawet jeśli nie podano menu klasy, aplikacja nadal może zdefiniować pasek menu dla okna podczas tworzenia okna.

Jeśli dla klasy zostanie podane menu i zostanie utworzone okno podrzędne tej klasy, menu zostanie zignorowane. Aby uzyskać więcej informacji, zobacz Menu.

Style klas

Style klasy definiują dodatkowe elementy klasy okna. Dwa lub więcej stylów można połączyć za pomocą operatora bitowego OR (|). Aby przypisać styl do klasy okna, przypisz styl do stylu składowej struktury WNDCLASSEX. Aby uzyskać listę stylów klas, zobacz Style klas okien.

Klasy i konteksty urządzeń

Kontekst urządzenia to specjalny zestaw wartości używanych przez aplikacje do rysowania w obszarze klienta okien. System wymaga kontekstu urządzenia dla każdego okna na ekranie, ale umożliwia pewną elastyczność w sposobie przechowywania i traktowania tego kontekstu urządzenia.

Jeśli nie podano jawnie stylu kontekstu urządzenia, system zakłada, że każde okno używa kontekstu urządzenia pobranego z puli kontekstów obsługiwanych przez system. W takich przypadkach każde okno musi pobrać i zainicjować kontekst urządzenia przed obrazem i zwolnić go po malowaniu.

Aby uniknąć pobierania kontekstu urządzenia za każdym razem, gdy trzeba go malować w oknie, aplikacja może określić styl CS_OWNDC dla klasy okna. Ten styl klasy kieruje system do utworzenia kontekstu urządzenia prywatnego — czyli przydzielenia unikatowego kontekstu urządzenia dla każdego okna w klasie. Aplikacja musi pobrać kontekst tylko raz, a następnie użyć go do wszystkich kolejnych obrazów.

Dodatkowa pamięć klasy

System utrzymuje wewnętrznie strukturę WNDCLASSEX dla każdej klasy okien w systemie. Gdy aplikacja rejestruje klasę okien, może kierować system do przydzielenia i dołączenia kilku dodatkowych bajtów pamięci na końcu struktury WNDCLASSEX. Ta pamięć jest nazywana pamięci dodatkowej klasy i jest współużytkowany przez wszystkie okna należące do klasy. Użyj dodatkowej pamięci klasy, aby przechowywać wszelkie informacje dotyczące klasy.

Ponieważ dodatkowa pamięć jest przydzielana z lokalnego sterta systemu, aplikacja powinna używać dodatkowej pamięci klasy oszczędnie. Funkcja RegisterClassEx kończy się niepowodzeniem, jeśli żądana ilość dodatkowej pamięci klasy jest większa niż 40 bajtów. Jeśli aplikacja wymaga więcej niż 40 bajtów, powinna przydzielić własną pamięć i zapisać wskaźnik do pamięci w pamięci dodatkowej klasy.

Funkcje SetClassWord i SetClassLong kopiują wartość do pamięci dodatkowej klasy. Aby pobrać wartość z pamięci dodatkowej klasy, użyj funkcji GetClassWord i GetClassLong. cbClsExtra składowej struktury WNDCLASSEX określa ilość dodatkowej pamięci klasy do przydzielenia. Aplikacja, która nie używa dodatkowej pamięci klasy, musi zainicjować cbClsExtra składowej do zera.

Dodatkowa pamięć okna

System utrzymuje wewnętrzną strukturę danych dla każdego okna. Podczas rejestrowania klasy okien aplikacja może określić kilka dodatkowych bajtów pamięci o nazwie dodatkowej pamięci okna. Podczas tworzenia okna klasy system przydziela i dołącza określoną ilość dodatkowej pamięci okna na końcu struktury okna. Aplikacja może używać tej pamięci do przechowywania danych specyficznych dla okna.

Ponieważ dodatkowa pamięć jest przydzielana z lokalnego sterta systemu, aplikacja powinna używać dodatkowej pamięci okna oszczędnie. Funkcja RegisterClassEx kończy się niepowodzeniem, jeśli żądana ilość dodatkowej pamięci okna jest większa niż 40 bajtów. Jeśli aplikacja wymaga więcej niż 40 bajtów, powinna przydzielić własną pamięć i zapisać wskaźnik do pamięci w dodatkowej pamięci okna.

Funkcja SetWindowLong kopiuje wartość do dodatkowej pamięci. Funkcja GetWindowLong pobiera wartość z dodatkowej pamięci. Struktura cbWndExtraWNDCLASS EX określa ilość dodatkowej pamięci okna do przydzielenia. Aplikacja, która nie używa pamięci, musi zainicjować cbWndExtra do zera.