Jarosław Kuchta Komunikaty w Windows
Okna i procedury okien W Windows każde okno ma swoją procedurę sterującą. LRESULT CALLBACK WndProc ( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { … } gdzie: hWnd jest uchwytem – identyfikatorem okna message jest komunikatem kierowanym do okna wParam jest parametrem krótkim komunikatu lParam jest parametrem długim komunikatu
Komunikaty Komunikat jest poleceniem do wykonania dla procedury okna Rodzaje komunikatów: komunikaty systemowe (generowane przez system w reakcji na zdarzenia pochodzące od urządzeń) komunikaty aplikacji (zdefiniowane w aplikacji i wysyłane od okna do okna).
Komunikaty systemowe – rozpoznawane przez przedrostek WM_ - duża grupa komunikatów ogólnych CCM_ - komunikaty uogólnione różnych kontrolek EM_, EN_ - komunikaty pola edycji CDM_ - komunikaty dialogów (np. otwarcia pliku) …
Komunikaty ogólne komunikaty okien powiadomienia o zdarzeniach okien powiadomienia o zdarzeniach klawiatury komunikaty klawiatury powiadomienia o skrótach klawiaturowych komunikaty skrótów klawiaturowych powiadomienia o zdarzeniach myszy …
Komunikaty okien WM_PAINT – odrysowanie okna WM_GETFONT – pobranie czcionki okna WM_SETFONT – ustawienie czcionki okna WM_SETICON – ustawienie ikony okna WM_SETTEXT – wpisanie tekstu do okna (kontrolka też jest oknem) WM_GETTEXTLENGTH – pobranie długości tekstu wprowadzonego do okna WM_GETTEXT – pobranie tekstu wprowadzonego do okna …
Powiadomienia o zdarzeniach okien WM_CREATE – okno zostało utworzone WM_ACTIVATE – okno zostało aktywowane WM_ENABLE – okno dostało zezwolenie na przyjmowanie komunikatów od klawiatury i myszy WM_SETFOCUS – okno będzie otrzymywać powiadomienia o zdarzeniach od klawiatury WM_KILLFOCUS – okno przestaje otrzymywać powiadomienia o zdarzeniach od klawiatury (tylko jedno okno dostaje WM_CLOSE – okno zostało zamknięte WM_DESTROY – okno zostało zniszczone …
Powiadomienia o zdarzeniach klawiatury WM_KEYDOWN – klawisz został naciśnięty WM_KEYUP – klawisz został zwolniony WM_CHAR – przyszedł znak od klawiatury …
Powiadomienia o zdarzeniach myszy WM_LBUTTONDOWN – lewy przycisk naciśnięty WM_LBUTTONUP – lewy przycisk zwolniony WM_LBUTTONDBLCLK – lewy przycisk naciśnięty dwukrotnie WM_MBUTTONDOWN – środkowy przycisk naciśnięty WM_MBUTTONUP – środkowy przycisk zwolniony WM_MBUTTONDBLCLK – środkowy przycisk naciśnięty dwukrotnie WM_RBUTTONDOWN – prawy przycisk naciśnięty WM_RBUTTONUP – prawy przycisk zwolniony WM_RBUTTONDBLCLK – prawy przycisk naciśnięty dwukrotnie WM_MOUSEMOVE – mysz przesunięta WM_MOUSEWHEEL – kółko myszy przekręcone
Przekazywanie komunikatów komunikaty niekolejkowane komunikaty kolejkowane
Komunikaty niekolejkowane Wymagają natychmiastowej reakcji okna, np.: WM_ACTIVATE WM_SETFOCUS WM_SETCURSOR Wysyłane przez funkcje: SendMessage SendMessageTimeout SendNotifyMessage BroadcastSystemMessage
Funkcja SendMessage LRESULT WINAPI SendMessage( __in HWND hWnd, __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam ); Wysyła komunikat do procedury okna i czeka na jego obsłużenie. Nie powraca, dopóki okno docelowe nie zareaguje na komunikat.
Funkcja SendMessageTimeout LRESULT WINAPI SendMessageTimeout( __in HWND hWnd, __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam, __in UINT fuFlags, __in UINT uTimeout, __out_opt PDWORD_PTR lpdwResult ); Wysyła komunikat do okna i czeka na jego obsłużenie, ale tylko określony czas. Umożliwia przesłanie komunikatu do wszystkich okien najwyższego poziomu (głównych okien programów).
Funkcja SendNotifyMessage LRESULT WINAPI SendNotifyMessage( __in HWND hWnd, __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam ); Wysyła komunikat do okna i: jeśli okno należy do tego samego wątku, to czeka na jego obsłużenie, jeśli nie, to przekazuje komunikat do procedury okna i wraca od razu.
Funkcja BroadcastSystemMessage long WINAPI BroadcastSystemMessage( __in DWORD dwFlags, __inout_opt LPDWORD lpdwRecipients, __in UINT uiMessage, __in WPARAM wParam, __in LPARAM lParam ); Wysyła komunikat do określonych odbiorców: aplikacji instalowanych sterowników urządzeń systemowych sterowników urządzeń sterowników sieciowych
Funkcja SendMessage LRESULT WINAPI SendMessage( __in HWND hWnd, __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam ); Wysyła komunikat do okna i czeka na jego obsłużenie. Nie powraca, dopóki okno docelowe nie zareaguje na komunikat.
Komunikaty kolejkowane komunikaty od klawiatury komunikaty od myszy inne, które nie muszą być obsłużone natychmiast umieszczane w kolejce komunikatów
Kolejki komunikatów Pojedyncza kolejka systemowa Kolejki własne wątków GUI Inicjalnie każdy wątek jest tworzony bez kolejki komunikatów Dla wątku, który wywołuje funkcje GUI, przy pierwszym wywołaniu tworzona jest kolejka komunikatów. Funkcje nie należące do GUI nie tworzą kolejki komunikatów.
Wysyłanie komunikatów do kolejki Funkcje: PostMessage PostThreadMessage Komunikaty są umieszczane na końcu kolejki. Komunikaty opuszczają kolejkę i są przekazywane do procedury okna w kolejności ich umieszczania w kolejce z wyjątkiem: WM_PAINT WM_TIMER WM_QUIT które są zatrzymywane w kolejce do czasu, aż nie ma w niej innych komunikatów i wtedy są przekazywane do procedury okna
Funkcja PostMessage LRESULT WINAPI PostMessage( __in HWND hWnd, __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam ); Wysyła komunikat do kolejki wątku skojarzonego z oknem i powraca natychmiast
Funkcja PostThreadMessage LRESULT WINAPI PostThreadMessage( __in DWORD idThread , __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam ); Wysyła komunikat do kolejki określonego wątku i powraca natychmiast
Pętla obsługi komunikatów Aplikacja pobiera w pętli komunikaty z kolejki, tłumaczy je i kieruje do właściwej procedury okna. MSG msg; BOOL bRet; while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) { if (bRet == -1) // handle the error and possibly exit } else TranslateMessage(&msg); DispatchMessage(&msg);
Funkcja GetMessage BOOL WINAPI GetMessage( __out LPMSG lpMsg, __in_opt HWND hWnd, __in UINT wMsgFilterMin, __in UINT wMsgFilterMax ); Pobiera z kolejki komunikat kierowany do określonego okna. Umożliwia filtrowanie komunikatów. Wynik podaje w strukturze LPMSG
Funkcja TranslateMessage BOOL WINAPI TranslateMessage( __in const MSG *lpMsg ); Tłumaczy komunikaty klawiatury, np.: WM_KEYDOWN i WM_KEYUP są tłumaczone na WM_CHAR (gdy to możliwe)
Funkcja DispatchMessage LRESULT WINAPI DispatchMessage( __in const MSG *lpmsg ); Kieruje komunikat do właściwego okna określonego w strukturze MSG
Obsługa komunikatów HWND hwndCombo; int cTxtLen; PSTR pszMem; switch (uMsg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDD_ADDCBITEM: // handle of the combo box message return TRUE; … } break;
Funkcja PeekMessage BOOL WINAPI PeekMessage( __out LPMSG lpMsg, __in_opt HWND hWnd, __in UINT wMsgFilterMin, __in UINT wMsgFilterMax, __in UINT wRemoveMsg ); Przekazuje komunikaty wysłane metodą Send, sprawdza, czy w kolejce są komunikaty i zwraca komunikat (gdy kolejka jest niepusta)
Sprawdzanie komunikatów w czasie długotrwałych operacji HWND hwnd; BOOL fDone; MSG msg; // Begin the operation and continue until it is complete // or until the user clicks the mouse or presses a key. fDone = FALSE; while (!fDone) { fDone = DoLengthyOperation(); // application-defined function // Remove any messages that may be in the queue. If the // queue contains any mouse or keyboard messages, end the operation. while (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) switch(msg.message) { case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_KEYDOWN: // Perform any required cleanup. fDone = TRUE; }