08.Komunikaty w Windows

Download Report

Transcript 08.Komunikaty w Windows

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:




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:




PostMessage
PostThreadMessage
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;
}
}
}