Komunikaty Windows

20
Komunikaty Windows Jacek Matulewski 22 września 2012 Programowanie Windows http://www.fizyka.umk.pl/~jacek/dydaktyka/winprog/

description

Programowanie Windows. Komunikaty Windows. Jacek Matulewski 22 września 2012. http://www.fizyka.umk.pl/~jacek/dydaktyka/winprog/. Zaliczenie. Lab.: projekt (obowiązkowy) Wybór z listy do końca października Własny po mojej akceptacji - PowerPoint PPT Presentation

Transcript of Komunikaty Windows

Page 1: Komunikaty Windows

Komunikaty Windows

Jacek Matulewski22 września 2012

Programowanie Windows

http://www.fizyka.umk.pl/~jacek/dydaktyka/winprog/

Page 2: Komunikaty Windows

Komunikaty Windows

• Komunikaty Windows (ang. Windows messages) to mechanizm przekazywania informacji od systemu do aplikacji (ew. między aplikacjami) – układ nerwowy Windows

• Przykładowe komunikaty:WM_LBUTTONDOWN, WM_LBUTTONUPWM_MOUSEMOVE, WM_NCMOUSEMOVE,WM_KEYDOWN, WM_KEYUP, WM_KEYCHAR,WM_DROPFILES, WM_CLOSE, WM_PAINT

WM_DISPLAYCHANGE, WM_DEVICECHANGEWM_QUERYENDSESSION, WM_ENDSESSION, WM_SYSCOMMAND, WM_USER

• http://www.autohotkey.com/docs/misc/SendMessageList.htm

Page 3: Komunikaty Windows

Pętla główna

• Każda aplikacja Windows musi mieć funkcję zwrotną (ang. callback) o nazwie WinMain. W niej umieszcza się pętlę główną aplikacji, której zasadniczym zadaniem jest odbieranie komunikatów z kolejki komunikatów aplikacji.

WPARAM Run(){

MSG msg;while(GetMessage(&msg, NULL, 0, 0)){

TranslateMessage(&msg);DispatchMessage(&msg);

}return msg.wParam;

}

Page 4: Komunikaty Windows

Pętla główna

• Każda aplikacja Windows musi mieć funkcję zwrotną (ang. callback) o nazwie WinMain. W niej umieszcza się pętlę główną aplikacji, której zasadniczym zadaniem jest odbieranie komunikatów z kolejki komunikatów aplikacji.

WPARAM Run(){

MSG msg;while(GetMessage(&msg, NULL, 0, 0)){

TranslateMessage(&msg);DispatchMessage(&msg);

}return msg.wParam;

}

Zwraca 0 tylko dla WM_QUIT; alt. PeekMessage

typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG, *PMSG, *LPMSG;

Przekształcanie komunikatów (klawiatury)

Rozsyłanie komunikatów do okien-adresatów(w tym kontrolek)

Page 5: Komunikaty Windows

Obsługa komunikatu

• Etap 1: Działanie użytkownika lub sytuacja w systemieSystem tworzy strukturę komunikatu MSG z numerem WM_Wysyła komunikat do adresata (okno aplikacji lub jego dziecko)

• Etap 2:Struktura zostaje umieszczona w kolejce komunikatów aplikacjiIstnieje jednak możliwość pominięcia kolejki i przesłania bezpośrednio do okna-adresata (kontrolki).Komunikat może być też rozsyłany do wszystkich okien (ang. broadcast)

• Etap 3:Aplikacja odbiera komunikat z kolejki i przesyła do właściwego pod-okna – a właściwie do tzw. procedury okna WndProc.

Page 6: Komunikaty Windows

• Procedura okna to funkcja zwrotna wskazywana w momencie rejestracji klasy okna, która jest wywoływana w momencieotrzymania przez okno komunikatu.LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SIZE: { int width = LOWORD(lParam); int height = HIWORD(lParam); OnSize(hwnd, (UINT)wParam, width, height); } break;

default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0;}

Procedura okna

Page 7: Komunikaty Windows

• Procedura okna to funkcja zwrotna wskazywana w momencie rejestracji klasy okna, która jest wywoływana w momencie otrzymania przez okno komunikatu. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SIZE: { int width = LOWORD(lParam); int height = HIWORD(lParam); OnSize(hwnd, (UINT)wParam, width, height); } break;

default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0;}

Procedura oknaW kodzie C++ okno zazwyczaj reprezentowane jest przez klasę ze zdefiniowaną metodą WndProc:

LRESULT CALLBACK WndProc(HWND hWnd,UINT message, WPARAM wParam,LPARAM lParam){

return okno.WndProc(hWnd,message,wParam,lParam);}

Filtrowanie komunikatów

LOWORD i HIWORD – makra:#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16))#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xFFFF))

OnSize to zdefiniowana przez nas funkcja dedykowana do obsługi komunikatu WM_SIZE

Funkcja DefWindowProc wywołuje domyślną procedurę okna obsługującą wszystkie te komunikaty, które nas nie interesują (bez tego zamiast okna pojawia się tylko biała plama!). „Def” od default, a nie od definition.

hwnd – uchwyt okna, czyli jednoznaczny identyfikator w danej sesji systemu

Page 8: Komunikaty Windows

Funkcja PreTranslateMessage (MFC)

• Funkcja WindowProc uruchamiana jest dla ostatecznego okna-adresata (po rozdzieleniu w pętli obsługi komunikatów).

• Jeżeli kontrolka (np. ListBox) przesłania część okna, to funkcja ta nie będzie „widzieć” komunikatów o ruchu myszy, gdy mysz jest nad kontrolką!

• Do odczytu wszystkich komunikatów, jeszcze przed rozesłaniem ich do poszczególnych kontrolek/okien służy metoda CWnd::PreTranslateMessage wywoływana przed TranslateMessage w pętli głównej okna MFC.

BOOL CKomunikatyDlg::PreTranslateMessage(MSG* pMsg) { if(pMsg->message == WM_KEYDOWN) Beep(100,10);

return CDialogEx::PreTranslateMessage(pMsg);}

Page 9: Komunikaty Windows

Tworzenie okna (przy okazji)

• Struktury WNDCLASS(EX) – styl okna np. CS_HREDRAW | CS_VREDRAW | CS_OWNDC– procedura okna,

– uchwyt bieżącej instancji aplikacji

– ikony, kursor, pędzel tła np. (HBRUSH)(COLOR_WINDOW+1)– tytuł okna i nazwa klasy okna;

oba łańcuchy umożliwiają wyszukiwanie okna funkcją FindWindow

• Rejestracja klasy okna: RegisterClass(Ex)

• Tworzenie okna: CreateWindow• Pokazywanie, ukrywanie, maksymalizacja, minimalizacja

okna: ShowWindow (SW_SHOW, SW_HIDE, ...)

• Aktualizacja okna: UpdateWindow

Page 10: Komunikaty Windows

Demo: WinMain

• Klasa C++ „opakowująca” tworzenie i utrzymywanie okna

• Procedura ok na WndProc jako metoda (problem dostępu do składowych klasy C++ okna)

Page 11: Komunikaty Windows

Demo: Komunikaty (MFC)

• Aplikacja MFC wyświetlająca komunikaty odbierane z kolejki komunikatów w liście ListBox.

• Co się stanie, gdy „odetniemy” komunikaty (zablokujemy ich obsługę przez aplikację usuwając wywołanie funkcji DefWindowProc)?

Page 12: Komunikaty Windows

Mapowanie komunikatów (MFC)

• W MFC metody można związać z komunikatami za pomocą mechanizmu mapowania komunikatów (domyślny sposób obsługi komunikatów przeznaczonych dla kontrolek w VS):

BEGIN_MESSAGE_MAP(CKomDlg, CDialogEx) ON_WM_PAINT() ON_WM_QUERYDRAGICON()

ON_BN_CLICKED(IDC_BUTTON1, &CKomDlg::OnBnClickedButton1) ON_BN_CLICKED(IDC_BUTTON2, &CKomDlg::OnBnClickedButton2) ON_BN_CLICKED(IDC_RADIO1, &CKomDlg::OnBnClickedRadio1) ON_BN_CLICKED(IDC_RADIO2, &CKomDlg::OnBnClickedRadio1) ON_BN_CLICKED(IDC_RADIO3, &CKomDlg::OnBnClickedRadio1)

END_MESSAGE_MAP()

• W pliku nagłówkowym: DECLARE_MESSAGE_MAP()

Page 13: Komunikaty Windows

Odczytywanie danych z kom.

• Komunikaty zwykle przekazują dodatkowe informacje o zdarzeniu (parametry lParam i wParam).

• Przykład zdarzeń związanych z myszką:

wchar_t txt_x[256]; wchar_t txt_y[256];

_itow_s(LOWORD(lParam),txt_x,256,10);_itow_s(HIWORD(lParam),txt_y,256,10);

edit1.SetWindowText(txt_x); edit2.SetWindowText(txt_y);

Page 14: Komunikaty Windows

Odczytywanie danych z kom.

• Komunikaty zwykle przekazują dodatkowe informacje o zdarzeniu (parametry lParam i wParam).

• Odczytanie klawiatury:

BOOL CKomunikatyDlg::PreTranslateMessage(MSG* pMsg) { //tu nie bedzie WM_CHAR if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) { Beep(300,200); } ...

Page 15: Komunikaty Windows

Wysyłanie komunikatów

• Uwaga! Standardowe funkcje WinAPI mają opakowania w klasie CWnd (MFC), które często „przesłaniają” zasadnicze funkcje.

• Wysyłanie komunikatów: PostMessage vs SendMessage.Pierwsza wysyła komunikat tradycyjnie tj. do kolejki komunikatów okna/kontrolki, druga – pomija kolejkę i wysyła bezpośrednio do okna/kontrolki.

this->PostMessage(WM_CLOSE); //metoda klasy CWnd

::PostMessage( //funkcja czystego WinAPI this->m_hWnd, //uchwyt okna-adresata WM_CLOSE, //identyfikator komunikatu 0,0); //lParam i wParam

Page 16: Komunikaty Windows

Wysyłanie komunikatów

• Uwaga! Standardowe funkcje WinAPI mają opakowania w klasie CWnd (MFC), które często „przesłaniają” zasadnicze funkcje.

• Wysyłanie komunikatów: PostMessage vs SendMessage.Pierwsza wysyła komunikat tradycyjnie tj. do kolejki komunikatów okna/kontrolki, druga – pomija kolejkę i wysyła bezpośrednio do okna/kontrolki.

this->SendMessage(WM_SYSCOMMAND,SC_SCREENSAVE,0);

::SendMessage( this->m_hWnd, WM_SYSCOMMAND, SC_SCREENSAVE,0); Niektóre aplikacje pozwalają na ich kontrolowanie

za pomocą komunikatów (np. WinAmp i Adobe).

Page 17: Komunikaty Windows

Znajdywanie uchwytu okna

• Uchwyty okien (w tym kontrolek) można szukać korzystając z funkcji FindWindow podając tytuł okna lub nazwę jego klasy (zob. też FindWindowEx):

::PostMessage( ::FindWindow(NULL,L"Komunikaty"), WM_CLOSE, 0,0);

• Przeszukiwanie okien w poszukiwaniu tych o konkretnych własnościach: EnumWindow i EnumChildWindows

• WindowFromPoint, ChildWindowFromPoint• GetDesktopWindow, GetForegroundWindow, GetNextWindow, IsWindow, IsWindowVisible

Page 18: Komunikaty Windows

Haki

• Można napisać bibliotekę DLL, która będzie ładowana do przestrzeni adresowej aplikacji w momencie np. wystąpienia zdarzenia związanego z klawiaturą lub myszą (po zarejestrowaniu tzw. haka – ang. hook).W takiej sytuacji nastąpi wywołanie funkcji zdefiniowanej w bibliotece DLL (potencjalnie niebezpieczne! - podsłuch).

• Uwaga! Przykład haka omówiony będzie na ćwiczeniach po tym, jak nauczymy się tworzyć biblioteki DLL z eksportowanymi funkcjami.

Page 19: Komunikaty Windows

Przykładowe pytania

• Jakich funkcji WinAPI można użyć do wysłania komunikatu?

• Jaki komunikat służy do ukrycia/zamknięcia okna?

• Jaka funkcja służy do pobrania komunikatu z kolejki komunikatów? A jaka do jego pobrania bez usunięcia z kolejki?

• Jaka funkcja służy do znalezienia uchwytu okna o znanej nazwie klasy?

• Jak wykonać pętlę po wszystkich oknach i ich oknach-dzieciach?

• Opisz w jaki sposób haki mogą być zagrożeniem dla bezpieczeństwa użytkownika.

• „Naszkicuj” kod funkcji zwracającej uchwyt okna znajdującego pod kursorem myszy. Opcjonalnie zrób go oknem aktywnym.

Page 20: Komunikaty Windows

Dodatek: Opis błędów

• Pobieranie opisu błędów dla wskazanegokodu błędu: FormatMessage

• Wyświetlanie: MessageBox(najpopularniejsza funkcja WinAPI)

• Demo: FormatMessage (MFC)