... masz przeżywać życie, a nie je opisywać.
bottom) ; if (GetWindowLong (hwnd, 0)) MoveToEx (hdc, 0, 0, NULL) ; LineTo (hdc, rect.right, rect.bottom) ; MoveToEx (hdc, 0, rect.bottom, NULL) LineTo (hdc, rect.right, 0) ; EndPaint (hwnd, &ps) ; return 0 ; ) return OefWindowProc (hwnd, message, wParam, lParam) ; Rysunek 7-7. Program CHECKER3 Program CHECKER3 posiada dwie funkcje okna o nazwach WndProc oraz Chil- dWndProc. Pierwsza z nich w dalszym ci¹gu wykorzystywana jest przez g³ówne okno programu (okno nadrzêdne). Z kolei ChildWndProc jest funkcj¹ okna dla 25 okien potomnych. Obie funkcj,e musz¹ zostaæ zdefiniowane jako CALLBACK. Poniewa¿ procedura okna zwi¹zana jest z jedn¹, szczególn¹ struktur¹ klasy okna, któr¹ rejestrujesz za pomoc¹ funkcji RegisterClass, program CHECKER3 wymaga zarejestrowania dwóch klas. Klasa pierwszego okna przeznaczona jest dla okna g³ównego i nosi nazwê "Checker3". Natomiast nazwa drugiej klasy to "Chec- ker3 Child". Wybrane nazwy nie musz¹ spe³niaæ jakichœ istotnych kryteriów. CHECKER3 rejestruje obie klasy okna w funkcji WinMain. Po zarejestrowaniu pierwszej, wykorzystuje tê sam¹ strukturê wndclass w trakcie rejestracji drugiej. Wszystkie jej pola, za wyj¹tkiem czterech przedstawionych ni¿ej, nie s¹ modyfi- kowane: 6 Rozdzia³ 7: Mysz ; ù Polu lpfnWndProc przypisywana jest procedura okna potomnego ChiIdWnd- ' Proc. ù Polu cbWndExtra zostaje nadana wartoœæ 4, a dok³adniej siezeof(long). Zawar- toœæ tego pola nakazuje systemowi Windows zarezerwowanie dodatkowych 4 bajtów na wewnêtrzne dane, dostêpne dla ka¿dego okna, które zostanie stwo- rzone na podstawie tej klasy. Nie bêd¹ to jednak wspólne dane okien: ka¿de z nich mo¿e przechowywaæ w tym obszarze swoje w³asne informacje. ù Pole hlcon zostaje ustawione na NULL, poniewa¿ takie okna potomne, jakie wykorzystane zosta³y w programie CHECKER3, nie potrzebuj¹ ikon. ù Polu pszClassName nadany zostaje ³añcuch "Checker3 Child" bêd¹cy nazw¹ klasy. Funkcja CreateWindow na podstawie klasy Checker3 tworzy okno g³ówne progra- mu wywo³ane w WinMain. Ten fragment programu niczym nie ró¿ni siê od po- przednich. Jednak gdy funkcja WinProc otrzyma komunikat WM CREATE, wy- wo³uje CreateWindow 25 razy, aby w oparciu o klasê Checker3 Child, utworzyæ 25 okien potomnych. W poni¿szej tabeli porównane zosta³y parametry przeka- zywane do funkcji CreateWindow wywo³ywanej w WinMain oraz w WndProc. Parametr Okno g³ówne Okno potomne klasa okna "Checker3" "Checker3 Child" nag³ówek okna "Checker3 .... NULL styl okna WM OVERLAPPEDWINDOW WS CHILDWINDOW I WS VISIBLE po³o¿enie w pionie CW USEDEFAULT 0 po³o¿enie w poziomie CW USEDEFAULT 0 ' szerokoœæ CW USEDEFAULT 0 wysokoœæ CW USEDEFAULT 0 ! uchwyt okna nadrzêdnego NULL hwnd uchwyt menu/ NULL (HMENU)(y ® 8 I x) identyfikator potomka uchwyt realizacji hInstance (HINSTANCE) GetWindowLong (hwnd, GWL HINSTANCE) dodatkowe parametry NULL NULL Zwykle okna potomne wymagaj¹ podania parametrów okreœlaj¹cych ich wiel- koœæ oraz po³o¿enie. Jednak w programie CHECKER s¹ one odpowiednio roz- mieszczane w oknie nadrzêdnym w dalszej czêœci funkcji WndProc. W przypad- ku okna g³ównego uchwyt okna nadrzêdnego ma wartoœæ NULL, poniewa¿ w³a- œnie to okno jest oknem nadrzêdnym. Z kolei parametr ten jest obowi¹zkowy w przypadku wywo³ania funkcji CreateWindow tworz¹cej okno potomne. Okno g³ówne nie ma menu, dlatego odpowiadaj¹cy mu parametr ma wartoœæ NULL. W przypadku okien potomnych ten sam parametr nosi nazwê "identyfi- kator potomka" (ang. child ID) lub "identyfikator okna potomnego" (ang. child window ID). Jest to liczba, dziêki której mo¿liwa jest jednoznaczna identyfikacja okna potomnego. Identyfikator ten ma wiêksze znaczenie, gdy pracujesz z kon- . 280 Czêœæ I. Podstawy trolkami umieszczonymi w oknie dialogowym, o czym przekonasz siê w rozdziale 11. W programie CHECKER3 zdecydowa³em, ¿e identyfikatorem tym bêdzie liczba wynikaj¹ca ze wspó³rzêdnych x i y, które okreœlaj¹ po³o¿enie ka¿dego okna w ta- blicy o 5 wierszach i 5 kolumnach w oknie g³ównym. Funkcja CreateWindow wymaga podamia uchwytu instancji (realizacji). W funkcji Win- Main uchwyt ten jest bardzo ³atwo dostêpny, poniewa¿ jest jej parametrem. Gdy z kolei tworzone jest okno potomne, CHECKEIZ3 musi pos³u¿yæ siê funkcj¹ GetWindowLong, która umo¿liwia pobranie wartoœci hlnstance ze struktury, któr¹ Windows przecho- wuje dla ka¿dego okna. (Zamiast wy'wo³ywania GetWindowLong móg³bym zdefinio- waæ po prostu zmienn¹ globaln¹ i korzystaæ bezpoœrednio z jej zawartoœci). Ka¿de z okien potomnych ma swój w³asny uchwyt, który przechowywany jest w tablicy hwndChild. Gdy funkcja WndProc odbierze komurukat WMþSIZE, dla ka¿dego z 25 okien potomnych wywo³ana zostanie funkcja MoveWindow. Para- metry tej funkcji pozwalaj¹ na okreœlenie lewego górnego rogu okna potomnego wzglêdem obszaru roboczego okna g³ównego, a tak¿e jego wysokoœci i szeroko- œci. Mo¿esz równie¿ okreœliæ, czy zawartoœæ okna potomnego powinna zostaæ od- œwie¿ona. Przyjrzyjmy siê teraz ChildWndProc - funkcji okna potomnego. Jest ona odpowie- dzialna za przetwarzanie komunikatów docieraj¹cych do ka¿dego z 25 okien potomnych. Przekazywany do niej parametr hwnd jest uchwytem okna potom- nego, które odebra³o komunikat. Gdy ChildWndProc przetwarza komunikat WMþCREATE (co odbywa siê 25 razy, poniewa¿ tyle jest okien potomnych), wy- wo³uje funkcjê SetWindowWord, umieszczaj¹c w obszarze danych okna wartoœæ 0. (Jak z pewnoœci¹ pamiêtasz, zarezerwowaliœmy ten obszar, korzystaj¹c z pola cbWndExtra struktury definiuj¹cej klasê okna). Funkcja ChildWndProc poshxguje siê t¹ wartoœci¹, aby przechowaæ aktualny stan prostok¹ta (zaznaczony lub nie). Po klikniêciu okna potomnego, w ramach obshzgi komunikatu WMþLBUTTON- DOWN zmieniana jest po prostu wartoœæ tej flagi (z 0 na 1 lub z 1 na 0), a nastêp- nie uniewa¿niony zostaje ca³y obszar okna. Obshzga komunikatu WM PAINT jest tym razem trywialna, poniewa¿ wielkoœæ prostok¹ta, który nale¿y narysowaæ, jest dok³adnie taka sama jak wielkoœæ obszaru roboczego. Poniewa¿ zarówno plik z kodem Ÿród³owym, jak i z programem s¹ wiêksze ni¿ w przypadku programu CHECKERl, nie bêdê nawet próbowa³ przekonaæ ciê, ¿e CHECKER3 jest "prostszy". Zwróæ jednak uwagê, ¿e nie musimy ju¿ wykony- waæ ¿adnych testów na trafienie! Je¿eli okno potomne w programie CHECKER3 otrzyma jakikolwiek komunikat WM LBUTTONDOWN, oznacza to, ¿e zosta³o wybrane i nic wiêcej nie musi ono wiedzieæ. Okna potomne a klawiatura Wydaje siê, ¿e dodanie do CHECKER3 interfejsu klawiatury bêdzie ostatni¹ lo- giczn¹ rzecz¹, któr¹ bêdziemy mogli zrobiæ