Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00306 008272 11001434 na godz. na dobę w sumie
Visual Studio 2005. Programowanie z Windows API w języku C++ - książka
Visual Studio 2005. Programowanie z Windows API w języku C++ - książka
Autor: Liczba stron: 728
Wydawca: Helion Język publikacji: polski
ISBN: 83-246-1567-9 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> visual c++ - programowanie
Porównaj ceny (książka, ebook, audiobook).
Napisz własne aplikacje dla systemu Windows

System operacyjny to nie tylko środowisko, w którym możemy uruchamiać zainstalowane programy - to także źródło zasobów dla programów tworzonych przez nas samych. Każda aplikacja dla systemu Windows, w której można znaleźć ikony, okna dialogowe, paski przewijania i inne powszechnie znane elementy, korzysta z bibliotek zwanych Windows API - zestawu funkcji ułatwiających zaprogramowanie określonych komponentów. Dzięki zastosowaniu Windows API możemy umieszczać w naszych aplikacjach typowe dla systemu operacyjnego składniki interfejsu użytkownika i moduły wykorzystujące urządzenia zewnętrzne.

Książka 'Visual Studio 2005. Programowanie z Windows API w języku C++' to podręcznik, dzięki któremu poznasz metody tworzenia programów dla systemu operacyjnego Windows. Nauczysz się korzystać z systemowego API w celu zaimplementowania w aplikacji mechanizmów interfejsu użytkownika, wyświetlania elementów graficznych i obsługiwania przetwarzania wielowątkowego. Dowiesz się, jak wykorzystywać zasoby programowe, budować biblioteki statyczne i biblioteki DLL, obsługiwać mysz i klawiaturę oraz mierzyć czas. Przeczytasz o tym, jak działają aplikacje dla systemu Windows, i zdobędziesz wiedzę niezbędną do tego, by tworzyć własne!

Poznaj techniki i metody tworzenia aplikacji dla systemu operacyjnego Windows.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Visual Studio 2005. Programowanie z Windows API w jŒzyku C++ Autor: Piotr Besta ISBN: 978-83-246-1567-4 Format: 158x235, stron: 728 Napisz w‡asne aplikacje dla systemu Windows (cid:149) Jak tworzy(cid:230) okna, menu i elementy graficzne? (cid:149) W jaki spos(cid:243)b zarz„dza(cid:230) zasobami aplikacji? (cid:149) Jak budowa(cid:230) aplikacje wielow„tkowe? System operacyjny to nie tylko (cid:156)rodowisko, w kt(cid:243)rym mo¿emy uruchamia(cid:230) zainstalowane programy (cid:150) to tak¿e (cid:159)r(cid:243)d‡o zasob(cid:243)w dla program(cid:243)w tworzonych przez nas samych. Ka¿da aplikacja dla systemu Windows, w kt(cid:243)rej mo¿na znale(cid:159)(cid:230) ikony, okna dialogowe, paski przewijania i inne powszechnie znane elementy, korzysta z bibliotek zwanych Windows API (cid:150) zestawu funkcji u‡atwiaj„cych zaprogramowanie okre(cid:156)lonych komponent(cid:243)w. DziŒki zastosowaniu Windows API mo¿emy umieszcza(cid:230) w naszych aplikacjach typowe dla systemu operacyjnego sk‡adniki interfejsu u¿ytkownika i modu‡y wykorzystuj„ce urz„dzenia zewnŒtrzne. Ksi„¿ka (cid:132)Visual Studio 2005. Programowanie z Windows API w jŒzyku C++(cid:148) to podrŒcznik, dziŒki kt(cid:243)remu poznasz metody tworzenia program(cid:243)w dla systemu operacyjnego Windows. Nauczysz siŒ korzysta(cid:230) z systemowego API w celu zaimplementowania w aplikacji mechanizm(cid:243)w interfejsu u¿ytkownika, wy(cid:156)wietlania element(cid:243)w graficznych i obs‡ugiwania przetwarzania wielow„tkowego. Dowiesz siŒ, jak wykorzystywa(cid:230) zasoby programowe, budowa(cid:230) biblioteki statyczne i biblioteki DLL, obs‡ugiwa(cid:230) mysz i klawiaturŒ oraz mierzy(cid:230) czas. Przeczytasz o tym, jak dzia‡aj„ aplikacje dla systemu Windows, i zdobŒdziesz wiedzŒ niezbŒdn„ do tego, by tworzy(cid:230) w‡asne! (cid:149) Tworzenie okien i umieszczanie w nich tekst(cid:243)w oraz element(cid:243)w graficznych (cid:149) Korzystanie z GDI (cid:149) Wy(cid:156)wietlanie map bitowych (cid:149) Tworzenie bibliotek statycznych (cid:149) Obs‡uga klawiatury i myszy (cid:149) Zarz„dzanie zasobami aplikacji (cid:149) Budowanie okien dialogowych (cid:149) Korzystanie z kontrolek (cid:149) Obs‡uga wielozadaniowo(cid:156)ci i wielow„tkowo(cid:156)ci Poznaj techniki i metody tworzenia aplikacji dla systemu operacyjnego Windows Wydawnictwo Helion ul. Ko(cid:156)ciuszki 1c 44-100 Gliwice tel. 032 230 98 63 e-mail: helion@helion.pl Spis treĈci Wstöp .............................................................................................. 9 Rozdziaä 1. WinMain — fundament aplikacji Windows ....................................... 11 1.1. Pierwszy program .................................................................................................. 11 1.1.1. Tworzymy projekt aplikacji ......................................................................... 12 1.1.2. Dodajemy do projektu plik kodu .................................................................. 16 1.1.3. Piszemy kod programu ................................................................................. 17 1.1.4. Funkcja MessageBox ................................................................................... 19 1.1.5. Kompilujemy kod i uruchamiamy program ................................................. 22 1.2. WiĊcej o Visual Studio .......................................................................................... 24 1.2.1. Konfiguracja Debug i Release ..................................................................... 24 1.2.2. Biblioteki statyczne ...................................................................................... 26 1.3. Tworzenie okna ..................................................................................................... 27 1.3.1. Klasa okna ................................................................................................... 28 1.3.2. Rejestracja klasy okna .................................................................................. 34 1.3.3. Jak wyrejestrowaü klasĊ okna? .................................................................... 35 1.3.4. Funkcja CreateWindowEx ........................................................................... 35 1.3.5. WyĞwietlanie okna ....................................................................................... 38 1.3.6. Procedura okna ............................................................................................ 39 1.3.7. Kolejka wiadomoĞci ..................................................................................... 40 1.3.8. PĊtla wiadomoĞci ......................................................................................... 40 1.3.9. Definicja procedury okna ............................................................................. 43 1.3.10. Przetwarzanie wiadomoĞci ......................................................................... 45 1.3.11. WiadomoĞci WM_CREATE i WM_DESTROY ....................................... 46 1.3.12. Projekt: Okno ............................................................................................. 47 Rozdziaä 2. Rysowanie w oknie ........................................................................ 51 2.1. WiadomoĞü WM_PAINT ...................................................................................... 51 2.1.1. Jak uniewaĪniü prostokątny fragment obszaru roboczego? .......................... 52 2.1.2. Jak zatwierdziü prostokątny fragment obszaru roboczego? ......................... 53 2.1.3. Obsáugiwanie wiadomoĞci WM_PAINT ..................................................... 53 2.2. Kontekst urządzenia ............................................................................................... 57 2.2.1. Czym jest kontekst urządzenia? ................................................................... 58 2.2.2. WáaĞciwoĞci kontekstu urządzenia ............................................................... 58 2.2.3. Pobieranie uchwytu kontekstu urządzenia ................................................... 64 2.2.4. Inne operacje na kontekĞcie urządzenia ....................................................... 65 2.3. WyĞwietlanie tekstu ............................................................................................... 66 2.3.1. Funkcja DrawText ....................................................................................... 67 2.3.2. WiadomoĞci WM_SYSCOMMAND i WM_CLOSE .................................. 68 2.3.3. Projekt: Tekst w oknie 01 ............................................................................ 71 2.3.4. Pobieranie informacji o czcionce ................................................................. 74 4 Visual Studio 2005. Programowanie z Windows API w jözyku C++ 2.3.5. Zmiana domyĞlnej czcionki ......................................................................... 77 2.3.6. Tworzenie nowej czcionki ........................................................................... 79 2.3.7. Funkcja TextOut .......................................................................................... 84 2.3.8. WiĊcej okien? .............................................................................................. 85 2.3.9. Niszczenie okna ........................................................................................... 85 2.3.10. Zmiana wáaĞciwoĞci okna .......................................................................... 86 2.3.11. WiadomoĞci WM_SETFOCUS, WM_KILLFOCUS i WM_ACTIVATE .................................................................................... 88 2.3.12. Projekt: Tekst w oknie 02 .......................................................................... 90 2.4. Rysowanie pikseli, linii, prostokątów, kóá, elips i wielokątów .............................. 99 2.4.1. Rysowanie pikseli ...................................................................................... 100 2.4.2. Rysowanie linii .......................................................................................... 101 2.4.3. Rysowanie prostokątów ............................................................................. 103 2.4.4. Rysowanie kóá i elips ................................................................................. 105 2.4.5. Rysowanie wielokątów .............................................................................. 106 2.5. Obiekty GDI ........................................................................................................ 107 2.5.1. Pióra ........................................................................................................... 108 2.5.2. PĊdzle ......................................................................................................... 113 2.5.3. Regiony ...................................................................................................... 118 2.5.4. Projekt: Malarz .......................................................................................... 129 2.5.5. Pobieranie aktualnego obiektu kontekstu urządzenia ................................. 140 2.6. Bitmapy ............................................................................................................... 141 2.6.1. Czym jest bitmapa? .................................................................................... 142 2.6.2. àadowanie bitmapy do pamiĊci operacyjnej .............................................. 143 2.6.3. Przykáad uĪycia funkcji LoadImage ........................................................... 146 2.6.4. Pobieranie informacji o zaáadowanej bitmapie .......................................... 147 2.6.5. Reprezentacja bitmapy w pamiĊci .............................................................. 148 2.6.6. WyĞwietlanie bitmapy ............................................................................... 149 2.6.7. Rysowanie po powierzchni bitmapy .......................................................... 164 2.6.8. Przenoszenie obrazu miĊdzy bitmapami .................................................... 167 2.6.9. Oczekiwanie na wiadomoĞü ....................................................................... 171 2.6.10. WiadomoĞci WM_MOVE i WM_SIZE ................................................... 176 2.6.11. Projekt: Gaz ............................................................................................. 177 2.6.12. Tworzenie wáasnych bitmap .................................................................... 196 2.6.13. Zapisywanie bitmapy do pliku BMP ........................................................ 200 2.6.14. Projekt: Spektrum barw ........................................................................... 217 2.7. Pobieranie informacji o ustawieniach systemu i kontekstu urządzenia ................ 228 2.7.1. Informacje o systemie ................................................................................ 228 2.7.2. Informacje o kontekĞcie urządzenia ........................................................... 231 2.7.3. Zamykanie i resetowanie systemu .............................................................. 232 2.7.4. Praca ze strukturami RECT ........................................................................ 234 Rozdziaä 3. Tworzenie i korzystanie z biblioteki statycznej ............................... 239 3.1. Czym jest biblioteka statyczna? ........................................................................... 239 3.2. Po co tworzymy biblioteki statyczne? .................................................................. 240 3.3. Przykáad utworzenia biblioteki ............................................................................ 241 3.3.1. Dodajemy do biblioteki funkcje matematyczne ......................................... 243 3.3.2. Dodajemy do biblioteki klasĊ CKot ........................................................... 245 3.3.3. Kompilacja biblioteki ................................................................................. 251 3.4. Testowanie biblioteki ........................................................................................... 252 3.4.1. Tworzymy aplikacjĊ konsolową ................................................................ 252 3.4.2. Dodajemy do aplikacji bibliotekĊ i pliki nagáówkowe ............................... 256 3.4.3. Piszemy kod programu testowego .............................................................. 258 3.5. Operatory new i delete ......................................................................................... 261 Spis treĈci 5 Rozdziaä 4. Klawiatura ................................................................................... 267 4.1. Jak to dziaáa w Windows? .................................................................................... 267 4.2. Wirtualne klawisze .............................................................................................. 268 4.3. WiadomoĞci WM_KEYDOWN i WM_KEYUP ................................................. 270 4.4. WiadomoĞü WM_CHAR ..................................................................................... 273 4.5. WiadomoĞci WM_SYSKEYDOWN i WM_SYSKEYUP ................................... 275 4.6. NiezaleĪne pobieranie informacji o stanie klawiszy ............................................ 276 4.7. Projekt: Klawiatura .............................................................................................. 277 Rozdziaä 5. Mysz ............................................................................................. 285 5.1. Mysz w Windows ................................................................................................ 285 5.2. Kursor myszy ....................................................................................................... 286 5.3. WiadomoĞci myszy .............................................................................................. 286 5.4. Obsáuga podwójnego klikniĊcia ........................................................................... 288 5.5. NiezaleĪne pobieranie i ustalanie pozycji kursora myszy .................................... 289 5.6. Przechwycenie myszy .......................................................................................... 290 5.7. Sterowanie wyĞwietlaniem kursora ...................................................................... 292 5.8. Projekt: Mysz ....................................................................................................... 293 Rozdziaä 6. Odmierzanie czasu ....................................................................... 301 6.1. Pobieranie systemowego czasu i daty z dokáadnoĞcią do milisekundy ................ 301 6.2. Systemowy licznik milisekund ............................................................................ 303 6.3. Korzystanie z zegara systemowego ..................................................................... 306 6.3.1. Tworzenie wáasnych zegarów .................................................................... 306 6.3.2. Techniki tworzenia zegara ......................................................................... 308 6.3.3. Definiowanie funkcji zegara ...................................................................... 309 6.3.4. UĞmiercanie zegarów ................................................................................. 309 6.4. Projekt: Minuta .................................................................................................... 310 6.4.1. Dokáadne wyznaczanie rozmiaru okna w oparciu o Īądany rozmiar obszaru roboczego ..................................................................................... 318 6.5. Specjalistyczne odmierzanie czasu ...................................................................... 320 6.6. Klasa CCzas ......................................................................................................... 323 6.7. Projekt: Stoper ..................................................................................................... 327 6.7.1. Odtwarzanie plików dĨwiĊkowych WAV za pomocą funkcji PlaySound .... 339 Rozdziaä 7. Zasoby aplikacji ........................................................................... 341 7.1. Zarządzanie zasobami .......................................................................................... 342 7.2. Projekt: Kursor i ikona ......................................................................................... 342 7.2.1. Kursory ...................................................................................................... 343 7.2.2. Ikony .......................................................................................................... 350 7.2.3. Odwoáywanie siĊ do zasobów .................................................................... 352 7.2.4. Piszemy kod dla projektu „Kursor i ikona” ................................................ 353 7.3. Zmiana i pobieranie ustawieĔ klasy okna ............................................................ 358 7.4. Projekt: Bitmapa i áaĔcuchy znaków .................................................................... 360 7.4.1. Bitmapy ...................................................................................................... 360 7.4.2. Tablice áaĔcuchów znakowych .................................................................. 362 7.4.3. Piszemy kod dla projektu Bitmapa i áaĔcuchy znaków .............................. 365 7.5. Wysyáanie wiadomoĞci do okna .......................................................................... 373 7.6. Projekt: Gáówne menu okna ................................................................................. 375 7.6.1. Jak zbudowane jest menu? ......................................................................... 375 7.6.2. Elementy menu .......................................................................................... 376 7.6.3. Tworzenie menu za pomocą edytora .......................................................... 376 7.6.4. àadowanie menu z zasobów i podáączanie do okna ................................... 381 7.6.5. Niszczenie menu ........................................................................................ 383 7.6.6. WiadomoĞci okna związane z menu .......................................................... 383 6 Visual Studio 2005. Programowanie z Windows API w jözyku C++ 7.6.7. Zaznaczanie elementów menu ................................................................... 386 7.6.8. Radiowe elementy menu ............................................................................ 388 7.6.9. Sterowanie dostĊpnoĞcią elementów menu ................................................ 389 7.6.10. Pobieranie uchwytu gáównego menu i uchwytów podmenu .................... 390 7.6.11. Pobieranie informacji o stanie elementu menu ......................................... 391 7.6.12. Piszemy kod dla projektu „Gáówne menu okna” ..................................... 393 7.6.13. Tworzenie menu w trakcie pracy programu ............................................. 401 7.6.14. Modyfikowanie menu w trakcie pracy programu ..................................... 405 7.6.15. WyĞwietlanie elementu menu za pomocą bitmapy .................................. 413 7.6.16. Zmieniamy bitmapĊ zaznaczenia elementu menu .................................... 415 7.6.17. Inne operacje przeprowadzane na elementach menu ................................ 416 7.7. Projekt: Menu kontekstowe i systemowe ............................................................. 418 7.7.1. Menu kontekstowe ..................................................................................... 418 7.7.2. Menu systemowe ....................................................................................... 422 7.7.3. Piszemy kod dla projektu „Menu kontekstowe i systemowe” .................... 424 7.8. Projekt: Skróty klawiaturowe ............................................................................... 431 7.8.1. Tworzenie tablicy skrótów klawiaturowych .............................................. 432 7.8.2. àadowanie tablicy skrótów klawiaturowych .............................................. 434 7.8.3. Tworzenie tablicy skrótów klawiaturowych w trakcie pracy programu ..... 435 7.8.4. Táumaczenie skrótów klawiaturowych na wiadomoĞci WM_COMMAND i WM_SYSCOMMAND ............................................ 437 7.8.5. Piszemy kod dla projektu „Skróty klawiaturowe” ..................................... 439 7.9. Projekt: Niestandardowe zasoby .......................................................................... 447 7.9.1. Tworzenie niestandardowych zasobów ...................................................... 448 7.9.2. àadowanie niestandardowych zasobów ..................................................... 450 7.9.3. Odczytywanie danych z niestandardowych zasobów ................................. 451 7.9.4. Piszemy kod dla projektu „Niestandardowe zasoby” ................................. 452 7.10. Biblioteka áączona dynamicznie jako zewnĊtrzne Ĩródáo zasobów i kodu ........... 456 7.10.1. Jak dziaáają biblioteki DLL? .................................................................... 456 7.10.2. Projekt: Pierwszy DLL ............................................................................. 457 7.10.3. DllMain — gáówna funkcja biblioteki DLL ............................................. 459 7.10.4. Dodajemy do biblioteki DLL funkcjĊ ...................................................... 461 7.10.5. Dodajemy do biblioteki DLL zmienne ..................................................... 466 7.10.6. Kompilacja i konsolidacja biblioteki DLL ............................................... 467 7.10.7. WspóáuĪytkowanie zmiennych biblioteki DLL przez wiele aplikacji ...... 467 7.10.8. àadowanie biblioteki DLL w trakcie pracy programu i pobieranie adresów funkcji ....................................................................................... 470 7.10.9. Umieszczanie zasobów w bibliotece DLL i ich wykorzystywanie .......... 472 7.10.10. Projekt: Test biblioteki DLL .................................................................. 473 7.11. Szerokie znaki — UNICODE .............................................................................. 478 7.11.1. Typ danych char ....................................................................................... 479 7.11.2. Typ danych wchar_t ................................................................................. 481 7.11.3. Ogólny znakowy typ danych .................................................................... 483 7.11.4. Szerokie znaki i funkcje ........................................................................... 485 Rozdziaä 8. Okna dialogowe ........................................................................... 489 8.1. Modalne okna dialogowe ..................................................................................... 491 8.2. Projekt: Modalne okno dialogowe ....................................................................... 491 8.2.1. Dodajemy do zasobów programu okno dialogowe .................................... 491 8.2.2. Procedura okna przetwarzająca wiadomoĞci okna dialogowego ................ 495 8.2.3. WiadomoĞü WM_INITDIALOG ............................................................... 497 8.2.4. Przesuwanie okna i pobieranie uchwytu okna nadrzĊdnego ...................... 498 8.2.5. Tworzenie, wyĞwietlanie i zamykanie modalnego okna dialogowego ....... 499 8.2.6. Piszemy kod dla projektu „Modalne okno dialogowe” .............................. 501 Spis treĈci 7 8.3. Niemodalne okna dialogowe ................................................................................ 508 8.4. Projekt: Niemodalne okno dialogowe .................................................................. 509 8.4.1. Tworzenie, wyĞwietlanie i zamykanie niemodalnego okna dialogowego ..... 509 8.4.2. Wysyáanie wiadomoĞci do niemodalnego okna dialogowego .................... 511 8.4.3. Piszemy kod dla projektu „Niemodalne okno dialogowe” ......................... 512 8.5. Predefiniowane okna dialogowe systemu ............................................................ 521 8.5.1. Otwieranie plików ...................................................................................... 522 8.5.2. Wskazywanie plików do zapisu ................................................................. 527 8.5.3. Wybieranie koloru ..................................................................................... 528 8.5.4. Tworzymy klasĊ CSystemoweDlg ............................................................. 530 8.5.5. Projekt: Systemowe okna dialogowe ......................................................... 534 Rozdziaä 9. Kontrolki ...................................................................................... 547 9.1. Jak dziaáają kontrolki? ......................................................................................... 547 9.2. Kontrolki klasy Button ......................................................................................... 549 9.2.1. Projekt: Prosty przycisk ............................................................................. 549 9.2.2. Typy i style przycisków ............................................................................. 555 9.2.3. Kody powiadomienia przycisków .............................................................. 562 9.2.4. WiadomoĞci kontrolne przycisków ............................................................ 562 9.2.5. Praca w edytorze okien dialogowych ......................................................... 564 9.2.6. Projekt: Przyciski ....................................................................................... 566 9.3. Kontrolki klasy Edit ............................................................................................. 583 9.3.1. Style pola edycji ......................................................................................... 583 9.3.2. Kody powiadomienia pola edycji ............................................................... 584 9.3.3. WiadomoĞci kontrolne pola edycji ............................................................. 585 9.3.4. Umieszczanie i pobieranie wartoĞci liczbowych z pola edycji ................... 587 9.3.5. Projekt: Pole edycji .................................................................................... 588 9.4. Kontrolki klasy Static .......................................................................................... 596 9.4.1. Style kontrolek statycznych ....................................................................... 596 9.4.2. WiadomoĞci kontrolne kontrolek statycznych ........................................... 597 9.5. Kontrolki klasy ComboBox ................................................................................. 597 9.5.1. Style kontrolki ComboBox ........................................................................ 598 9.5.2. Kody powiadomienia kontrolki ComboBox .............................................. 599 9.5.3. WiadomoĞci kontrolne ComboBox ............................................................ 599 9.5.4. Projekt: ComboBox ................................................................................... 603 9.6. Wygląd kontrolek w systemie Windows XP ........................................................ 612 9.6.1. Tworzenie manifestu .................................................................................. 613 9.6.2. Dodawanie manifestu do projektu aplikacji ............................................... 615 Rozdziaä 10. Paski przewijania ......................................................................... 617 10.1. Rozmiar pasków przewijania ............................................................................... 617 10.2. Budowa pasków przewijania ............................................................................... 618 10.3. WiadomoĞci WM_HSCROLL i WM_VSCROLL ............................................... 619 10.4. Pobieranie i ustawianie stanu pasków przewijania .............................................. 621 10.5. WyĞwietlanie, ukrywanie, wáączanie i wyáączanie pasków przewijania .............. 624 10.6. Przewijanie obszaru roboczego okna ................................................................... 625 10.7. Projekt: Ogromne bitmapy ................................................................................... 626 Rozdziaä 11. Procesy i wñtki ............................................................................ 641 11.1. WielozadaniowoĞü ............................................................................................... 641 11.1.1. Tworzenie nowego procesu ...................................................................... 643 11.1.2. Projekt: Nowy proces ............................................................................... 644 11.1.3. Natychmiastowe koĔczenie pracy aplikacji ............................................. 648 8 Visual Studio 2005. Programowanie z Windows API w jözyku C++ 11.2. WielowątkowoĞü .................................................................................................. 648 11.2.1. Kiedy korzystamy z dodatkowych wątków? ............................................ 649 11.2.2. Tworzenie wątków ................................................................................... 650 11.2.3. Funkcja wątku .......................................................................................... 652 11.2.4. KoĔczenie pracy wątków ......................................................................... 652 11.2.5. Usypianie wątków .................................................................................... 654 11.2.6. Projekt: Pierwszy wątek ........................................................................... 654 11.2.7. Projekt: WiĊcej wątków ........................................................................... 656 11.2.8. Zmienne globalne programu a zmienne automatyczne i statyczne wątków ................................................................................... 658 11.2.9. Zawieszanie i przywracanie pracy wątków .............................................. 658 11.2.10. Projekt: Zawieszanie wątku ................................................................... 659 11.2.11. Pobieranie uchwytu wątku ..................................................................... 661 11.2.12. Problemy z wątkami ............................................................................... 661 11.2.13. Metody synchronizacji pracy wątków .................................................... 662 11.2.14. Oczekiwanie na sygnalizowanie pojedynczego obiektu ......................... 662 11.2.15. Projekt: Oczekiwanie na koniec wątku .................................................. 663 11.2.16. Oczekiwanie na sygnalizowanie wielu obiektów ................................... 665 11.2.17. Projekt: Oczekiwanie na koniec wielu wątków ...................................... 666 11.2.18. Zdarzenia ............................................................................................... 668 11.2.19. Projekt: Zdarzenia .................................................................................. 669 11.2.20. Muteksy ................................................................................................. 674 11.2.21. Projekt: Muteks ...................................................................................... 675 11.2.22. Semafory ................................................................................................ 679 11.2.23. Projekt: Semafor .................................................................................... 681 Rozdziaä 12. Nie tylko Windows API ................................................................. 685 12.1. Biblioteka DirectX ............................................................................................... 685 12.2. Konfiguracja Visual Studio .................................................................................. 688 12.3. Obiekt Direct3D ................................................................................................... 689 12.3.1. Tworzenie obiektu Direct3D .................................................................... 690 12.3.2. Pobieranie informacji o karcie graficznej ................................................ 692 Dodatek A ...................................................................................................... 697 Kody ASCII .................................................................................................................. 697 Kody skaningowe klawiatury ....................................................................................... 699 Skorowidz .................................................................................... 701 Rozdziaä 4. Klawiatura Nadeszáa najwyĪsza pora, aby nauczyü siĊ posáugiwania klawiaturą. OczywiĞcie, mam tu na myĞli obsáugĊ związaną z czysto programistycznym punktem widzenia. ZacznĊ od szybkiego omówienia podstaw dziaáania klawiatury. NastĊpnie dowiesz siĊ, jak system Windows wspóápracuje z klawiaturą, jak tworzone są wiadomoĞci związane z zdarzeniami klawiatury oraz w jaki sposób są póĨniej wstawiane do kolejki wiadomoĞci aplikacji. Potem wyjaĞniĊ, czym jest wirtualny klawisz, i powiem, jak odbieraü wiadomoĞci z nim związane. Tu dowiesz siĊ teĪ, jak bez udziaáu procedury okna sprawdzaü stan poszcze- gólnych klawiszy klawiatury. Poznasz wiadomoĞü systemową związaną z obieraniem wyáącznie znaków tekstowych generowanych za pomocą klawiatury. Na zakoĔczenie rozdziaáu napiszĊ przykáadowy program, który bĊdzie przechwytywaá informacje o naci- ĞniĊtych klawiszach klawiatury, po czym bĊdzie je wyĞwietlaá w oknie. 4.1. Jak to dziaäa w Windows? Klawiatura to podstawowe urządzenie, za którego pomocą uĪytkownik komunikuje siĊ z systemem zainstalowanym na komputerze. Dzisiaj klawiatura tak mocno zakorzeniáa siĊ w naszym Īyciu, Īe dla sporej grupy ludzi stanowi codzienne, nieodáączne narzĊdzie pracy. Jednym sáowem, trudno wyobraziü sobie dzisiaj Ğwiat bez niej, ale jeszcze trudniej wyobraziü sobie alternatywne urządzenie, które mogáoby zastąpiü klawiaturĊ. Wydawaü siĊ moĪe, Īe nic nie zastąpi klawiszy nawet wtedy, gdy klawiatura bĊdzie páaska jak kartka papieru i przeĨroczysta jak powietrze. Spotykane dzisiaj klawiatury skáadają siĊ najczĊĞciej ze 101 lub 102 klawiszy. Są to tzw. klawiatury rozszerzone, gdyĪ niektóre klawisze zostaáy zdublowane, co — jak by nie patrzeü — bardzo uáatwia pracĊ. KaĪda klawiatura posiada wbudowany mikroprocesorowy ukáad kontrolujący kilkadzie- siąt razy w ciągu sekundy stan wszystkich klawiszy. Zebrane informacje są formowane w pakiety danych, wysyáane nastĊpnie do jednego z portów wejĞciowych komputera. 268 Visual Studio 2005. Programowanie z Windows API w jözyku C++ System Windows w odpowiedzi na przyciĞniĊcie lub zwolnienie klawisza generuje odpowiednią wiadomoĞü. Utworzona wiadomoĞü jest przypisywana zawsze do tego okna, które byáo aktywne w momencie zaistnienia zdarzenia związanego z klawiaturą. NastĊpnie wiadomoĞü jest wstawiana do systemowej kolejki wiadomoĞci. Skąd dalej trafia do kolejki wiadomoĞci wybranej aplikacji. NajwaĪniejsze jest to, abyĞ pamiĊtaá, Īe system nie umieszcza nastĊpnej wiadomoĞci związanej ze zdarzeniem klawiatury w kolejce wia- domoĞci aplikacji, dopóki poprzednia wiadomoĞü nie zostanie obsáuĪona. 4.2. Wirtualne klawisze Ukáad mikroprocesorowy klawiatury po wykryciu, Īe któryĞ z klawiszy zostaá naciĞniĊty, generuje i wysyáa do komputera tzw. kod skaningowy klawisza (kody skaningowe kla- wiszy zostaáy podane w dodatku A). Przykáadowo klawiszowi A odpowiada kod o war- toĞci 30. Gdy klawisz jest zwalniany, generowany jest ten sam kod skaningowy, z tą róĪ- nicą, Īe jego wartoĞü zostaje powiĊkszona o 128. Po zwolnieniu klawisza A otrzymujemy kod 158 (128+30). PamiĊtaj, aby nie myliü kodów skaningowych klawiszy (Original Equipment Manufac- turer — OEM) z kodem ASCII (American Standards Committee for Information Inter- change) i z kodami ANSI (American National Standards Institute). Kody ANSI i ASCII są budowane na podstawie kodu skaningowego, przy uwzglĊdnieniu dodatkowych czyn- ników mających wpáyw na stan klawiatury. Te czynniki to stan klawiszy Caps Lock (duĪe, maáe litery), Shift (górne znaki klawiszy) oraz Num Lock (aktywna, nieaktywna klawiatura numeryczna). MoĪemy rozróĪniü 256 kodów ANSI i ASCII (kody ASCII znajdują siĊ w dodatku A na koĔcu ksiąĪki). Jak widzisz, za pomocą pojedynczego kodu skaningowego nie jesteĞmy w stanie stwier- dziü, czy uĪytkownik chciaá napisaü duĪą literĊ, czy maáą. Aby poznaü tĊ informacjĊ, naleĪy kontrolowaü klawisze sterujące stanem klawiatury. Nie martw siĊ. Mam dla Ciebie bardzo dobrą wiadomoĞü. Nie bĊdziemy korzystali bezpoĞrednio z kodów ska- ningowych. Dlaczego? Kody skaningowe mają tĊ brzydką cechĊ, Īe są zaleĪne od sprzĊtu. Mimo ogólnie przyjĊtych na Ğwiecie standardów wyznaczających parametry produko- wanych klawiatur i ich ukáadów mikroprocesorowych, moĪemy spotkaü takie klawia- tury, które dla klawisza A wygenerują odmienny kod skaningowy. OczywiĞcie, są to sytuacje marginalne. Dzisiaj programiĞci Windows nie muszą siĊ w ogóle tym przejmo- waü. Byáo to jednak szczególnie irytujące dla twórców systemu Windows w jego wcze- snych latach „Īycia”. Aby rozwiązaü problem, postanowiono opracowaü niezaleĪne, oderwane od sprzĊtu kla- wisze wirtualne. Kody wirtualnych klawiszy, z wyjątkiem kodów klawiszy literowych i klawiszy numerycznych z podstawowej czĊĞci klawiatury (nienumerycznej), są odmienne od kodów skaningowych, kodów ASCII i ANSI. Wirtualne klawisze nie istnieją, są one wytworem swoistej interpretacji kodów skaningowych klawiszy przeprowadzonej przez system Windows. Rozdzia 4. i Klawiatura 269 Wszystkim wirtualnym klawiszom, z wyjątkiem klawiszy literowych i numerycznych podstawowej klawiatury, zostaá przypisany identyfikator. Identyfikatory rozpoczynają siĊ od przedrostka VK (ang. Virtual Key). Ich definicja znajduje siĊ w pliku nagáówkowym winuser.h. NajwaĪniejsze identyfikatory zebraáem w tabeli 4.1. Zwróü uwagĊ na to, Īe klawisze literowe i numeryczne posiadają jedynie kod wirtualnego klawisza. Tabela 4.1. Kod klawiszy wirtualnych Kod dziesiötnie Kod szesnastkowo Identyfikator Uwagi o wirtualnym klawiszu 8 9 13 16 17 18 20 27 32 33 34 35 36 37 38 39 40 44 45 46 0x08 0x09 0x0D 0x10 0x11 0x12 0x14 0x1B 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x2C 0x2D 0x2E 48 – 57 0x30 – 0x39 65 – 90 0x41 – 0x5A 91 92 93 145 112 113 114 115 0x5B 0x5C 0x5D 0x91 0x70 0x71 0x72 0x73 VK_BACK VK_TAB VK_RETURN VK_SHIFT Backspace Tab Jeden z klawiszy Enter Jeden z klawiszy Shift VK_CONTROL Jeden z klawiszy Ctrl VK_MENU Jeden z klawiszy Alt VK_CAPITAL Caps Lock VK_ESCAPE VK_SPACE VK_PRIOR VK_NEXT VK_END VK_HOME VK_LEFT VK_UP VK_RIGHT VK_DOWN Esc Spacja Page Up Page Down End Home Strzaáka w lewo Strzaáka w górĊ Strzaáka w prawo Strzaáka w dóá VK_SNAPSHOT Print Screen VK_INSERT VK_DELETE nie ma nie ma VK_LWIN VK_RWIN VK_APPS VK_SCROLL VK_F1 VK_F2 VK_F3 VK_F4 Insert Delete Klawisze numeryczne od 0 do 9 z podstawowej czĊĞci klawiatury Klawisze literowe od A do Z Lewy klawisz Windows Prawy klawisz Windows Klawisz aplikacji Scroll Lock Klawisz F1 Klawisz F2 Klawisz F3 Klawisz F4 270 Visual Studio 2005. Programowanie z Windows API w jözyku C++ Tabela 4.1. Kod klawiszy wirtualnych — ciąg dalszy Kod dziesiötnie Kod szesnastkowo Identyfikator Uwagi o wirtualnym klawiszu 116 117 118 119 120 121 122 123 0x74 0x75 0x76 0x77 0x78 0x79 0x7A 0x7B Kody klawiszy z klawiatury numerycznej VK_F5 VK_F6 VK_F7 VK_F8 VK_F9 VK_F10 VK_F11 VK_F12 Klawisz F5 Klawisz F6 Klawisz F7 Klawisz F8 Klawisz F9 Klawisz F10 Klawisz F11 Klawisz F12 144 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 0x90 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6A 0x6B 0x6C 0x6D 0x6E 0x6F VK_NUMLOCK Num Lock VK_NUMPAD0 VK_NUMPAD1 VK_NUMPAD2 VK_NUMPAD3 VK_NUMPAD4 VK_NUMPAD5 VK_NUMPAD6 VK_NUMPAD7 VK_NUMPAD8 VK_NUMPAD9 Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock Przy aktywnym Num Lock VK_MULTIPLY Klawisz mnoĪenia (*) VK_ADD Klawisz dodawania (+) VK_SEPARATOR Separator przy nieaktywnym NL (-) VK_SUBTRACT Klawisz odejmowania (-) VK_DECIMAL Klawisz kropki (,) VK_DIVIDE Klawisz dzielenia (/) 4.3. WiadomoĈci WM_KEYDOWN i WM_KEYUP Gdy naciskamy klawisz klawiatury, system generuje wiadomoĞü WM_KEYDOWN, oznacza- jącą wduszenie jakiegoĞ klawisza. Parametr wParam wiadomoĞci zawiera kod wciĞniĊtego wirtualnego klawisza. Przykáadowy fragment kodu procedury okna obsáugujący naciĞniĊ- cie klawisza F1 mógáby wyglądaü tak: Rozdzia 4. i Klawiatura 271 case WM_KEYDOWN: if(wParam == VK_F1) { // tutaj wstawimy kod wykonujacy jakies dzialanie // zwiazane z nacisnieciem klawisza F1 } return 0; Parametr lParam dostarcza nieco wiĊcej informacji na temat naciĞniĊtego klawisza. Jest to m.in. licznik powtórzeĔ klawisza, jego kod skaningowy i kilka mniej przydatnych informacji o stanie klawisza. Spójrz na rysunek 4.1, na którym przedstawiam znaczenie poszczególnych bitów parametru lParam. Rysunek 4.1. Znaczenie bitów parametru lParam dla wiadomoĞci WM_KEYDOWN Bity 0-15 Opis Máodsze sáowo parametru lParam, zawiera informacje o liczbie powtórzeĔ klawisza. NajczĊĞciej jego wartoĞü jest równa 1, gdyĪ uĪytkownik szybko uderza klawisz klawiatury, niemal jednoczeĞnie naciskając go i zwalniając. Jednak czasami moĪe siĊ zdarzyü sytuacja, w której uĪytkownik przytrzyma dany klawisz. Co siĊ wówczas dzieje? System z ustaloną czĊstotliwoĞcią caáy czas generuje wiadomoĞci WM_KEYDOWN. Do ich parametru wParam jest wstawiany wirtualny kod przytrzymanego klawisza. JeĪeli Windows zauwaĪy, Īe systemowa kolejka wiadomoĞci zapeánia siĊ wiadomoĞciami WM_KEYDOWN, dotyczącymi tego samego klawisza, jest to dla niego znak, Īe któraĞ z dziaáających aplikacji nie moĪe odpowiednio szybko przetwarzaü wiadomoĞci związanych z klawiaturą. àączy zatem grupĊ wiadomoĞci WM_KEYDOWN w jedną wiadomoĞü, ustawiając jej licznik powtórzeĔ na odpowiednią wartoĞü. Odczytanie liczby powtórzeĔ klawisza mogáoby byü zrealizowane w procedurze okna nastĊpująco: case WM_KEYDOWN: { unsigned short licznikPowtorzenKlawisza = 0; licznikPowtorzenKlawisza = LOWORD(lParam); } return 0; Dla wiadomoĞci WM_KEYUP wartoĞü licznika powtórzeĔ klawisza zawsze wynosi 1. 272 Visual Studio 2005. Programowanie z Windows API w jözyku C++ Bity Opis 16 – 23 8-bitowy kod skaningowy klawisza. MoĪemy go odczytaü nastĊpująco: case WM_KEYDOWN: { unsigned char kodSkaningowy = 0; kodSkaningowy = (lParam 0x00FF0000) 16; } return 0; 24 JeĪeli bit jest ustawiony, klawisz naleĪy do tzw. rozszerzonej grupy klawiszy klawiatury. Rozszerzone klawisze spotykamy przy klawiaturach 101- i 102-klawiszowych. InformacjĊ tĊ odczytujemy nastĊpująco: case WM_KEYDOWN: { bool czyRozszerzony = false; czyRozszerzony = lParam 0x01000000; if(czyRozszerzony) { // dzialanie zwiazane z wykryciem rozszerzonego klawisza } else { // dzialanie zwiazane z wykryciem zwyczajnego klawisza } } return 0; 25 – 28 Cztery nieuĪywane bity. 29 Kod kontekstu. Dla wiadomoĞci WM_KEYDOWN i WM_KEYUP ten bit jest zawsze wyzerowany. Natomiast dla wiadomoĞci WM_CHAR jest ustawiony wtedy, gdy podczas naciĞniĊcia klawisza zostaá przytrzymany klawisz Alt, w innym przypadku bit jest wyzerowany. InformacjĊ tĊ moĪemy odczytaü nastĊpująco: case WM_KEYDOWN: { bool czyKodKontekstu = false; czyKodKontekstu = lParam 0x20000000; if(czyKodKontekstu) { // dzialanie zwiazane z wykryciem ustawionego bitu kontekstu } else { // dzialanie zwiazane z niewykryciem // ustawionego bitu kontekstu } } return 0; 30 OkreĞla poprzedni stan klawisza. Dla wiadomoĞci WM_KEYDOWN i WM_CHAR bit jest ustawiony, gdy klawisz byá juĪ wciĞniĊty w chwili wygenerowania wiadomoĞci. JeĪeli klawisz nie byá wduszony, bit jest wyzerowany. Dla wiadomoĞci WM_KEYUP bit jest zawsze ustawiony. Ustawienie bitu moĪemy sprawdziü tak: Rozdzia 4. i Klawiatura 273 Bity Opis case WM_KEYDOWN: { bool czyBylWduszony = false; czyBylWduszony = lParam 0x40000000; if(czyBylWduszony) { // kod wykonywany, gdy klawisz byl juľ wcisniety } else { // kod wykonywany, gdy klawisz nie byđ wcisniety } } return 0; 31 Bit stanu przejĞciowego. Dla wiadomoĞci WM_KEYDOWN bit jest zawsze wyzerowany. Dla wiadomoĞci WM_KEYUP jest zawsze ustawiony. Natomiast dla wiadomoĞci WM_CHAR jest wyzerowany, gdy klawisz zostaá wduszony, a ustawiony, kiedy klawisz zostaá zwolniony. InformacjĊ o stanie przejĞciowym klawisza pobieramy nastĊpująco: case WM_KEYDOWN: { bool stanPrzejsciowy = false; stanPrzejsciowy = lParam 0x80000000; if(stanPrzejsciowy) { // kod wykonywany, gdy bit jest ustawiony } else { // kod wykonywany, gdy bit jest wyzerowany } } return 0; JeĪeli procedura okna przetworzy wiadomoĞü WM_KEYDOWN, powinna zwróciü do systemu wartoĞü zerową. Gdy zwalniamy klawisz klawiatury, system generuje wiadomoĞü WM_KEYUP. Parametr wParam wiadomoĞci zawiera kod zwolnionego wirtualnego klawisza, a parametr lPa- ram zawiera takie same dodatkowe informacje o klawiszu, jak wiadomoĞü WM_KEYDOWN. JeĪeli procedura okna przetwarza wiadomoĞü WM_KEYUP, powinna zwróciü do systemu wartoĞü zerową. 4.4. WiadomoĈè WM_CHAR PoznaáeĞ juĪ dwie wiadomoĞci związane z klawiaturą, WM_KEYDOWN i WM_KEYUP. Są to tzw. wiadomoĞci klawiszowe. Teraz poznasz jeszcze jedną wiadomoĞü — WM_CHAR — którą czĊsto nazywa siĊ wiadomoĞcią znakową. 274 Visual Studio 2005. Programowanie z Windows API w jözyku C++ WiadomoĞci klawiszowe nie pozwalają jednoznacznie okreĞliü, czy uĪytkownik nacisnąá duĪą, czy maáą literĊ. Aby to stwierdziü, naleĪaáoby kontrolowaü klawisze sterujące sta- nem klawiatury, czyli takie klawisze jak Caps Lock, Shift oraz Alt. Z uwzglĊdnieniem ich stanu kod skaningowy wciĞniĊtego klawisza powinien zostaü przeksztaácony na odpo- wiadający mu kod znaku z zestawu znaków aktualnie wybranego w systemie. System Windows dostarcza funkcjĊ, za której pomocą moĪemy automatycznie dokonaü tego przeksztaácenia. Jest nią TranslateMessage, wywoáujemy ją najczĊĞciej wewnątrz pĊtli wiadomoĞci aplikacji. Funkcja TranslateMessage przeksztaáca wiadomoĞü klawi- szową (WM_KEYDWON i WM_KEYUP) na wiadomoĞü znakową (WM_CHAR). Niech Ci siĊ nie wy- daje, Īe wiadomoĞü klawiszowa jest zastĊpowana wiadomoĞcią znakową. Funkcja Trans- lateMessage tworzy nową wiadomoĞü i umieszcza ją w kolejce wiadomoĞci aplikacji w taki sposób, Īe zostanie ona pobrana przez funkcjĊ GetMessage lub PeekMessage podczas kolejnego przebiegu pĊtli wiadomoĞü. Gdy w naturalny sposób uderzamy w klawisz klawiatury oznaczony symbolem A (naci- skamy go i zaraz puszczamy), system wygeneruje nastĊpującą sekwencjĊ wiadomoĞci. OczywiĞcie zakáadamy, Īe pĊtla wiadomoĞci aplikacji jest wyposaĪona w funkcjĊ Trans- lateMessage oraz klawisz Caps Lock jest wyáączony, a klawisz Shift nie jest przytrzy- mywany.  WM_KEYDOWN — (kod naciskanego wirtualnego klawisza A: 0x41, dziesiĊtnie 65)  WM_CHAR — (kod ANSI znaku a: 0x61, dziesiĊtnie 97)  WM_KEYUP — (kod zwalnianego wirtualnego klawisza: 0x41, dziesiĊtnie 65) Gdy wáączymy klawisz Caps Lock i naciĞniemy klawisz A lub przytrzymamy klawisz Shift i naciĞniemy klawisz A, zostanie wygenerowana nastĊpująca sekwencja wiadomoĞci. Wybraáem drugą opcjĊ.  WM_KEYDOWN — (kod naciskanego wirtualnego klawisza Shift: 0x10, dziesiĊtnie 16)  WM_KEYDOWN — (kod naciskanego wirtualnego klawisza A: 0x41, dziesiĊtnie 65)  WM_CHAR — (kod ANSI znaku A: 0x41, dziesiĊtnie 65)  WM_KEYUP — (kod zwalnianego wirtualnego klawisza A: 0x41, dziesiĊtnie 65)  WM_KEYUP — (kod zwalnianego wirtualnego klawisza Shift: 0x10, dziesiĊtnie 16) ZauwaĪ, Īe klawisz Shift nie generuje wiadomoĞci WM_CHAR. Dlaczego? To proste, bo nie generuje samodzielnie Īadnego tekstowego znaku. Robią to natomiast klawisze Tab, Enter oraz Backspace. Rodzi siĊ wiĊc pytanie, jak identyfikowaü te znaki? Z pewnoĞcią wiesz, Īe klawiszowi Tab odpowiada znak (kod) sterujący , klawiszowi Enter — , a klawiszowi Backspace — znak  . UĪywamy ich tak samo jak zwykáych kla- wiszy literowych. Nie musimy jednak koniecznie przechwytywaü zdarzenia naciĞniĊcia wyĪej wymienio- nych trzech klawiszy za pomocą wiadomoĞci WM_CHAR, moĪemy to równie dobrze zrobiü, korzystając z wiadomoĞci WM_KEYDWON i identyfikatorów klawiszy wirtualnych VK_TAB, VK_RETURN i VK_BACK. Rozdzia 4. i Klawiatura 275 Parametr wParam wiadomoĞci WM_CHAR nie zawiera kodu wirtualnego klawisza, jest w nim umieszczony kod ANSI znaku, pochodzący z aktualnie wybranego w systemie zestawu znaków. Oto przykáadowy fragment kodu procedury okna przechwytujący wprowadzenie przez uĪytkownika znaku A i znaku tabulacji. case WM_CHAR: { if(wParam == A ) { // dzialanie zwiazane z wprowadzeniem znaku A } if(wParam == ) { // dzialanie zwiazane z wprowadzeniem znaku tabulacji } } return 0; Parametr lParam zawiera identyczną informacjĊ o stanie naciĞniĊtego lub zwolnionego klawisza, jak w przypadku wiadomoĞci WM_KEYDOWN. JeĪeli procedura okna przetwarza wiadomoĞü WM_CHAR, powinna zwróciü do systemu wartoĞü zerową. 4.5. WiadomoĈci WM_SYSKEYDOWN i WM_SYSKEYUP WiadomoĞü WM_SYSKEYDOWN jest wstawiana do kolejki wiadomoĞci, kiedy naciĞniemy klawisz F10 lub przytrzymamy klawisz Alt i wciĞniemy dodatkowo jakiĞ inny klawisz. WiadomoĞci WM_SYSKEYDOWN towarzyszy zawsze pojawienie siĊ wiadomoĞci WM_SYSKEYUP, generowanej w momencie zwolnienia klawisza, który zostaá naciĞniĊty w czasie, gdy kla- wisz Alt byá przytrzymany. WiadomoĞci WM_SYSKEYDOWN i WM_SYSKEYUP na ogóá nie przetwarzamy. Oddajemy je do obsáugi przez domyĞlną procedurĊ okna — DefWin- dowProc. Blokowanie tych wiadomoĞci moĪe powodowaü, Īe system nie wykona zadaĔ, które wywoáujemy za pomocą skrótów klawiaturowych z uĪyciem klawisza Alt. Przykáa- dowo nie zadziaáa kombinacja Alt+F4 zamykająca okno. Z wiadomoĞci WM_SYSKEYDOWN i WM_SYSKEYUP najprawdopodobniej nigdy nie skorzystamy podczas pisania naszych przykáadowych programów. Wiedza o nich bĊdzie jednak potrzebna do lepszego zrozumienia treĞci kolejnych rozdziaáów. Parametry wParam i lParam wiadomoĞci WM_SYSKEYDOWN i WM_SYSKEYUP zawierają takie same informacje jak dla wiadomoĞci WM_KEYDOWN i WM_KEYUP. PowinieneĞ równieĪ pamiĊtaü o tym, Īe gdy je przetwarzasz, procedura okna powinna zwróciü do systemu wartoĞü zerową. 276 Visual Studio 2005. Programowanie z Windows API w jözyku C++ 4.6. NiezaleĔne pobieranie informacji o stanie klawiszy Czy nie wydaje Ci siĊ, Īe odbieranie informacji o stanie klawiszy wyáącznie przy uĪyciu wiadomoĞci WM_KEYDOWN, WM_KEYUP i WM_CHAR w procedurze okna jest nieco niewygodne. Czasami moĪe siĊ zdarzyü, Īe bĊdziemy chcieli niezaleĪnie sprawdziü stan jakiegoĞ klawisza, np. podczas przetwarzania wiadomoĞci WM_PAINT. Co wtedy? Windows API dostarcza wiele funkcji do obsáugi klawiatury, dwie z nich moĪemy wykorzystaü do rozwiązania naszego problemu. Pierwsza to GetKeyState. Jej nagáówek jest zdefiniowany w pliku winuser.h i ma nastĊ- pującą postaü: SHORT GetKeyState(int nVirtKey); Jako parametr nVirtKey podajemy kod wirtualnego klawisza, którego stan zamierzamy sprawdziü. JeĪeli klawisz jest wciĞniĊty, funkcja zwraca wartoĞü ujemną (najstarszy bit zwróconej wartoĞci jest ustawiony). JeĪeli zwrócona wartoĞü jest nieujemna, klawisz jest zwolniony (najstarszy bit zwróconej wartoĞci nie jest ustawiony). JeĪeli najmáodszy bit jest ustawiony, klawisz jest wáączony, w przeciwnym razie klawisz jest wyáączony. Stan wáączenia i wyáączenia odnosi siĊ do klawiszy sterujących pracą klawiatury, takich jak Caps Lock, Scroll Lock czy Num Lock. Mimo Īe moĪemy wyróĪ- niü trzy klawisze tego typu, powinieneĞ za pomocą funkcji GetKeyState sprawdzaü wyáącznie stan klawisza Caps Lock. Znam jeszcze jedną bardzo waĪną wskazówkĊ, dotyczącą pracy z funkcją GetKeyState. Funkcja nie odnosi siĊ bezpoĞrednio do klawiatury w celu zbadania stanu danego kla- wisza. Wykorzystuje fakt, Īe podczas tworzenia kaĪdej wiadomoĞci okna system za- pamiĊtuje aktualny stan klawiatury i na podstawie tego zbioru informacji ocenia stan klawiszy. Do bezpoĞredniego badania stanu klawiszy klawiatury sáuĪy funkcja GetAsyncKeyState. Podczas wywoáania komunikuje siĊ z klawiaturą i zwraca rzeczywisty stan klawisza. Oto jej nagáówek: SHORT GetAsyncKeyState(int nVirtKey); Poprzez parametr nVirtKey okreĞlamy kod wirtualnego klawisza, którego stanem jeste- Ğmy zainteresowani. JeĪeli wywoáanie funkcji siĊ powiedzie, zwracana wartoĞü okreĞla stan klawisza. Gdy jej najbardziej znaczący bit jest ustawiony (wartoĞü jest ujemna), klawisz jest wciĞniĊty. Kiedy natomiast jest wyzerowany (wartoĞü jest nieujemna), klawisz jest zwolniony. JeĪeli najmniej znaczący bit jest ustawiony, oznacza to, Īe klawisz byá naciĞniĊty po poprzednim wywoáaniu funkcji GetAsyncKeyState. JeĪeli zwróconą wartoĞcią jest zero, znaczy to, Īe Īadne z okien aplikacji (procesu) nie jest aktywne, co automatycznie wiąĪe siĊ z tym, iĪ do aplikacji nie docierają Īadne wiadomoĞci związane z klawiaturą. Rozdzia 4. i Klawiatura 277 Dodatkowo funkcje GetKeyState i GetAsyncKeyState obsáugują trzy kody wirtualnych klawiszy powiązanych z przyciskami myszy (tabela 4.2). Tabela 4.2. Kod wirtualnych przycisków myszy Kod dziesiötnie Kod szesnastkowo Identyfikator Uwagi o wirtualnym przycisku 1 2 4 0x01 0x02 0x04 VK_LBUTTON VK_RBUTTON VK_MBUTTON Lewy przycisk myszy Prawy przycisk myszy ĝrodkowy przycisk myszy Przykáadowe wywoáanie funkcji GetAsyncKeyState sprawdzające, czy jest naciĞniĊty klawisz spacji, mogáoby wyglądaü nastĊpująco: if(0x8000 GetAsyncKeyState(VK_SPACE)) { // kod wykonywany w odpowiedzi na wykrycie // wcisnietego klawisza spacji } 4.7. Projekt: „Klawiatura” Mówiąc krótko, przykáadowy program bĊdzie przechwytywaá wiadomoĞci WM_KEYDOWN, WM_KEYUP oraz WM_CHAR, po czym wypisze informacje o naciĞniĊtym klawiszu. BĊdzie to m.in. jego kod skaningowy, kod wirtualny i licznik powtórzeĔ. Budowa programu, w porównaniu do poprzednich przykáadowych programów, nie ulegáa zmianie (listing 4.1). Program wyĞwietla jedno okno, w którym demonstruje swoje dziaáa- nie. Poza funkcją WinMain i procedurą okna — ProceduraOkna — zdefiniowaáem jeszcze tylko jedną funkcjĊ WypiszInformacjeKlawisza. Zanim omówiĊ jej dziaáanie, do- káadnie przeanalizuj kod programu. Przypuszczam, Īe jeĞli bĊdziesz miaá z nim jakiekol- wiek problemy, to bĊdą dotyczyü tylko nowej funkcji. Na rysunku 4.2 przedstawiam okno programu Klawiatura po naciĞniĊciu kilku klawiszy. Listing 4.1. Odbieranie informacji o naciĞniĊtych klawiszach (projekt: Klawiatura, plik: WinMain.cpp) 001: // P L I K I N A G L O W K O W E 002: /////////////////////////////////////////// 003: #include windows.h 004: #include stdio.h 005: 006: // D E K L A R A C J E 007: /////////////////////////////////////////// 008: LRESULT CALLBACK ProceduraOkna( 009: HWND hWnd, UINT message, 010: WPARAM wParam, LPARAM lParam); 011: 012: void WypiszInformacjeKlawisza( 013: HWND hwnd, UINT message, 014: WPARAM wParam, LPARAM lParam); 015: 278 Visual Studio 2005. Programowanie z Windows API w jözyku C++ Rysunek 4.2. Okno programu Klawiatura 016: // D E F I N I C J E 017: /////////////////////////////////////////// 018: #define WYSOKOSC_OKNA 500 019: #define SZEROKOSC_OKNA 400 020: 021: char* const g_nazwaKlasyOkna = StandardoweOkno ; 022: BOOL g_czyAktywna = true; 023: 024: // W I N M A I N 025: /////////////////////////////////////////// 026: int WINAPI WinMain( 027: HINSTANCE hInstance, 028: HINSTANCE hPrevInstance, 029: LPSTR lpCmdLine, 030: int nShowCmd) 031: { 032: // definiujemy klase okna 033: WNDCLASSEX wndclassex = {0}; 034: 035: wndclassex.cbSize = sizeof(WNDCLASSEX); 036: wndclassex.style = CS_VREDRAW | CS_HREDRAW; 037: wndclassex.lpfnWndProc = ProceduraOkna; 038: wndclassex.cbClsExtra = 0; 039: wndclassex.cbWndExtra = 0; 040: wndclassex.hInstance = hInstance; 041: wndclassex.hIcon = LoadIcon(0, (LPCTSTR)IDI_APPLICATION); 042: wndclassex.hCursor = LoadCursor(0, (LPCTSTR)IDC_ARROW); 043: wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 044: wndclassex.lpszMenuName = 0; 045: wndclassex.lpszClassName = g_nazwaKlasyOkna; 046: wndclassex.hIconSm = LoadIcon(0, (LPCTSTR)IDI_APPLICATION); 047: 048: // rejestrujemy klase okna Rozdzia 4. i Klawiatura 279 049: RegisterClassEx( wndclassex); 050: 051: // zmienna na uchwyt okna 052: HWND uchwytOkna = 0; 053: 054: // tworzymy okno 055: uchwytOkna = CreateWindowEx( 056: 0, // styl rozszerzony 057: g_nazwaKlasyOkna, // klasa okna 058: Klawiatura , // tekst na belce 059: WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME, // styl okna 060: 100, // pozycja X okna 061: 60, // pozycja Y okna 062: SZEROKOSC_OKNA, // szerokosc okna 063: WYSOKOSC_OKNA, // wysokosc okna 064: 0, // okno nadrzedne 065: 0, // uchwyt menu 066: hInstance, // uchwyt aplikacji 067: 0); // wskaznik na dane 068: 069: // wyswietlamy okno 070: ShowWindow(uchwytOkna, SW_NORMAL); 071: 072: // wymuszamy odswiezenie okna 073: UpdateWindow(uchwytOkna); 074: 075: // wiadomosc 076: MessageBox( 077: uchwytOkna, 078: Zamknij okno komunikatu i 079: nacisnij dowolny klawisz klawiatury. , 080: informacja , MB_OK | MB_ICONINFORMATION); 081: 082: // petla wiadomosci 083: MSG msg; 084: for(;;) 085: { 086: if(PeekMessage( msg, NULL, 0, 0, PM_REMOVE) != 0) 087: { 088: if(msg.message == WM_QUIT) break; 089: TranslateMessage( msg); 090: DispatchMessage( msg); 091: } 092: 093: if(g_czyAktywna == false) 094: WaitMessage(); 095: else ; // po prostu nic nie robimy 096: } 097: 098: return (int)msg.wParam; 099: } 100: 101: // D E F I N I C J E F U N K C J I 102: /////////////////////////////////////////// 103: LRESULT CALLBACK ProceduraOkna( 104: HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 105: { 280 Visual Studio 2005. Programowanie z Windows API w jözyku C++ 106: switch(message) 107: { 108: case WM_PAINT: 109: ValidateRect(hWnd, 0); 110: return 0; 111: 112: // w przypadku przechwycenia jednej z wiadomosci 113: // klawiatury wywolujemy funkcje WypiszInformacjeKlawisza 114: case WM_CHAR: 115: case WM_KEYDOWN: 116: case WM_KEYUP: 117: WypiszInformacjeKlawisza( 118: hWnd, message, wParam, lParam); 119: return 0; 120: 121: case WM_CLOSE: 122: if(IDYES == 123: MessageBox(hWnd, Czy na pewno zamknac okno? , 124: Pytanie , MB_YESNO | MB_ICONQUESTION)) 125: return DefWindowProc(hWnd, message, wParam, lParam); 126: else 127: return 0; 128: 129: case WM_ACTIVATE: 130: if(LOWORD(wParam) == WA_INACTIVE) 131: { 132: g_czyAktywna = false; 133: } else 134: { 135: g_czyAktywna = true; 136: } 137: return 0; 138: 139: case WM_DESTROY: 140: PostQuitMessage(0); 141: return 0; 142: } // koniec switch 143: 144: return DefWindowProc(hWnd, message, wParam, lParam); 145: } 146: 147: void WypiszInformacjeKlawisza( 148: HWND hwnd, UINT message, 149: WPARAM wParam, LPARAM lParam) 150: { 151: // definicja niezbednych zmiennych 152: // automatycznych i statycznych 153: int wysokoscWierszaTekstu = 0; 154: static unsigned short ileWierszy = 2; 155: char buforWierszaTekstu[80] = { }; 156: 157: // naglowek tabeli 158: static char naglowekTabeli[60] = 159: { WIADOMOSC ZNAK SKAN KOD WIR KOD LICZNIK }; 160: static char podkreslenie[60] = 161: { ----------------------------------------------- }; 162: Rozdzia 4. i Klawiatura 281 163: // pobieramy uchwyt kontekstu urzadzenia okna 164: HDC hdc = 0; 165: hdc = GetDC(hwnd); 166: 167: // wybieramy czcionke o stađej szerokosci znaku 168: HGDIOBJ gdiObj = 0; 169: gdiObj = SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); 170: 171: // pobieramy wysokosc pojedynczego wiersza tekstu 172: // zapisanego za pomoca czcionki aktualnie wybranej w kontekscie 173: // urzadzenia 174: TEXTMETRIC tm = {0}; 175: 176: GetTextMetrics(hdc, tm); 177: wysokoscWierszaTekstu = 178: tm.tmHeight + tm.tmExternalLeading; 179: 180: // sprawdzamy, czy wyswietlany wiersz jest 181: // pierwszym wierszem tekstu w oknie oraz czy 182: // okno nie zostalo calkowicie zapisane, gdy jeden z 183: // warunkow zostanie spelniony, czyscimy obszar roboczy okna, 184: // malujac go na biađo, po czym wyswietlamy naglowek tabeli 185: if((ileWierszy == 2) || 186: ((ileWierszy * wysokoscWierszaTekstu) 187: WYSOKOSC_OKNA - wysokoscWierszaTekstu * 3)) 188: { 189: // pobieramy rozmiar obszaru roboczego okna 190: RECT rect = {0}; 191: GetClientRect(hwnd, rect); 192: 193: // malujemy go na bialo 194: FillRect(hdc, rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); 195: 196: // ustalmy pozycje pierwszego wiersza tekstu 197: ileWierszy = 2; 198: 199: // wyswietlamy naglowek tabeli 200: TextOut( 201: hdc, 10, 0, 202: naglowekTabeli, (int)strlen(naglowekTabeli)); 203: 204: TextOut( 205: hdc, 10, wysokoscWierszaTekstu, 206: podkreslenie, (int)strlen(podkreslenie)); 207: 208: // informacja dzwiekowa 209: MessageBeep(MB_OK); 210: } 211: 212: // przygotowujemy tekst zawierajacy informacje o odebranej 213: // wiadomosci i stanie klawisza 214: sprintf_s( 215: buforWierszaTekstu, 216: sizeof(buforWierszaTekstu), 217: -14s -6c #-6x -5i -9i -7i , 218: 219: // identyfikator wiadomosci 282 Visual Studio 2005. Programowanie z Windows API w jözyku C++ 220: (message == WM_CHAR) ? WM_CHAR : 221: (message == WM_KEYDOWN) ? WM_KEYDOWON : WM_KEYUP , 222: 223: // znak 224: (message == WM_CHAR) ? (char)wParam : , 225: 226: // kod skaningowy klawisza, szesnastkowo i dziesietnie 227: (lParam 0x00FF0000) 16, 228: (lParam 0x00FF0000) 16, 229: 230: // kod wirtualnego klawisza 231: (message != WM_CHAR) ? wParam : 0, 232: 233: // licznik powtorzen klawisza 234: (lParam 0x0000FFFF) 235: 236: ); // - koniec wywođania funkcji sprintf_s 237: 238: // wyswietlamy tekst 239: TextOut( 240: hdc, 10, ileWierszy * wysokoscWierszaTekstu, 241: buforWierszaTekstu, (int)strlen(buforWierszaTekstu)); 242: 243: // ustalamy pozycje nastepnego wiersza 244: ileWierszy++; 245: 246: // przywracamy pierwotne ustawienia kontekstu urzadzenia, 247: // zatwierdzamy caly obszar roboczy okna i zwalniamy uchwyt 248: // kontekstu urzadzenia 249: SelectObject(hdc, gdiObj); 250:
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Visual Studio 2005. Programowanie z Windows API w języku C++
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: