280 likes | 407 Views
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
E N D
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; } } }