Programowanie Windows Komunikaty Windows Jacek Matulewski 22 wrzenia

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

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

Komunikaty Windows • Komunikaty Windows (ang. Windows messages) to mechanizm przekazywania informacji od systemu

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_LBUTTONUP WM_MOUSEMOVE, WM_NCMOUSEMOVE, WM_KEYDOWN, WM_KEYUP, WM_KEYCHAR, WM_DROPFILES, WM_CLOSE, WM_PAINT WM_DISPLAYCHANGE, WM_DEVICECHANGE WM_QUERYENDSESSION, WM_SYSCOMMAND, WM_USER • http: //www. autohotkey. com/docs/misc/Send. Message. List. htm

Pętla główna • Każda aplikacja Windows musi mieć funkcję zwrotną (ang. callback) o nazwie

Pętla główna • Każda aplikacja Windows musi mieć funkcję zwrotną (ang. callback) o nazwie Win. Main. 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(Get. Message(&msg, NULL, 0, 0)) { Translate. Message(&msg); Dispatch. Message(&msg); } return msg. w. Param; }

Pętla główna typedef struct tag. MSG { HWND hwnd; UINT message; • Każda WPARAMaplikacja

Pętla główna typedef struct tag. MSG { HWND hwnd; UINT message; • Każda WPARAMaplikacja w. Param; Windows musi mieć funkcję zwrotną (ang. callback) o nazwie Win. Main. W niej umieszcza się pętlę LPARAM l. Param; DWORD time; główną aplikacji, której zasadniczym zadaniem jest odbieranie POINT pt; komunikatów z kolejki komunikatów aplikacji. } MSG, *PMSG, *LPMSG; WPARAM Run() Zwraca 0 tylko dla WM_QUIT; alt. Peek. Message { MSG msg; Przekształcanie komunikatów (klawiatury) while(Get. Message(&msg, NULL, 0, 0)) { Translate. Message(&msg); Dispatch. Message(&msg); } return msg. w. Param; Rozsyłanie komunikatów do okien-adresatów } (w tym kontrolek)

Obsługa komunikatu • Etap 1: Działanie użytkownika lub sytuacja w systemie System tworzy strukturę

Obsługa komunikatu • Etap 1: Działanie użytkownika lub sytuacja w systemie System 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 aplikacji Istnieje 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 Wnd. Proc.

Procedura okna • Procedura okna to funkcja zwrotna wskazywana w momencie rejestracji klasy okna,

Procedura okna • Procedura okna to funkcja zwrotna wskazywana w momencie rejestracji klasy okna, która jest wywoływana w momencie otrzymania przez okno komunikatu. LRESULT CALLBACK Window. Proc(HWND hwnd, UINT u. Msg, WPARAM w. Param, LPARAM l. Param) { switch (u. Msg) { case WM_SIZE: { int width = LOWORD(l. Param); int height = HIWORD(l. Param); On. Size(hwnd, (UINT)w. Param, width, height); } break; default: return Def. Window. Proc(hwnd, u. Msg, w. Param, l. Param); } } return 0;

W kodzie C++ okno zazwyczaj reprezentowane jest przez klasę ze zdefiniowaną metodą Wnd. Proc:

W kodzie C++ okno zazwyczaj reprezentowane jest przez klasę ze zdefiniowaną metodą Wnd. Proc: Procedura okna LRESULT CALLBACK Wnd. Proc(HWND h. Wnd, UINT message, WPARAM w. Param, LPARAM l. Param) { • Procedura okna to funkcja zwrotna wskazywana w momencie return okno. Wnd. Proc(h. Wnd, message, w. Param, l. Param); – uchwyt okna, jednoznaczny rejestracji klasy okna, która jesthwnd wywoływana wczyli momencie } identyfikator w danej sesji systemu otrzymania przez okno komunikatu. LRESULT CALLBACK Window. Proc(HWND Filtrowanie komunikatów { On. Size hwnd, UINT u. Msg, WPARAM w. Param, LPARAM l. Param) switch (u. Msg) { LOWORD i HIWORD – makra: case WM_SIZE: #define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) { #define ((WORD)((DWORD_PTR)(l) & 0 x. FFFF)) int LOWORD(l) width = LOWORD(l. Param); int height = HIWORD(l. Param); On. Size(hwnd, (UINT)w. Param, width, height); to zdefiniowana przez nas funkcja dedykowana do obsługi komunikatu WM_SIZE } break; Funkcja Def. Window. Proc wywołuje domyślną procedurę okna default: return Def. Window. Proc(hwnd, u. Msg, w. Param, l. Param); obsługującą wszystkie te komunikaty, które nas nie interesują } } (bez tego zamiast okna pojawia się tylko biała plama!). return„Def” 0; od default, a nie od definition.

Funkcja Pre. Translate. Message (MFC) • Funkcja Window. Proc uruchamiana jest dla ostatecznego oknaadresata

Funkcja Pre. Translate. Message (MFC) • Funkcja Window. Proc uruchamiana jest dla ostatecznego oknaadresata (po rozdzieleniu w pętli obsługi komunikatów). • Jeżeli kontrolka (np. List. Box) 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: : Pre. Translate. Message wywoływana przed Translate. Message w pętli głównej okna MFC. BOOL CKomunikaty. Dlg: : Pre. Translate. Message(MSG* p. Msg) { if(p. Msg->message == WM_KEYDOWN) Beep(100, 10); } return CDialog. Ex: : Pre. Translate. Message(p. Msg);

Tworzenie okna (przy okazji) • Struktury WNDCLASS(EX) – – – styl okna np. CS_HREDRAW

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ą Find. Window • Rejestracja klasy okna: Register. Class(Ex) • Tworzenie okna: Create. Window • Pokazywanie, ukrywanie, maksymalizacja, minimalizacja okna: Show. Window (SW_SHOW, SW_HIDE, . . . ) • Aktualizacja okna: Update. Window

Demo: Win. Main • Klasa C++ „opakowująca” tworzenie i utrzymywanie okna • Procedura ok

Demo: Win. Main • Klasa C++ „opakowująca” tworzenie i utrzymywanie okna • Procedura ok na Wnd. Proc jako metoda (problem dostępu do składowych klasy C++ okna)

Demo: Komunikaty (MFC) • Aplikacja MFC wyświetlająca komunikaty odbierane z kolejki komunikatów w liście

Demo: Komunikaty (MFC) • Aplikacja MFC wyświetlająca komunikaty odbierane z kolejki komunikatów w liście List. Box. • Co się stanie, gdy „odetniemy” komunikaty (zablokujemy ich obsługę przez aplikację usuwając wywołanie funkcji Def. Window. Proc)?

Mapowanie komunikatów (MFC) • W MFC metody można związać z komunikatami za pomocą mechanizmu

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(CKom. Dlg, CDialog. Ex) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON 1, &CKom. Dlg: : On. Bn. Clicked. Button 1) ON_BN_CLICKED(IDC_BUTTON 2, &CKom. Dlg: : On. Bn. Clicked. Button 2) ON_BN_CLICKED(IDC_RADIO 1, &CKom. Dlg: : On. Bn. Clicked. Radio 1) ON_BN_CLICKED(IDC_RADIO 2, &CKom. Dlg: : On. Bn. Clicked. Radio 1) ON_BN_CLICKED(IDC_RADIO 3, &CKom. Dlg: : On. Bn. Clicked. Radio 1) END_MESSAGE_MAP() • W pliku nagłówkowym: DECLARE_MESSAGE_MAP()

Odczytywanie danych z kom. • Komunikaty zwykle przekazują dodatkowe informacje o zdarzeniu (parametry l.

Odczytywanie danych z kom. • Komunikaty zwykle przekazują dodatkowe informacje o zdarzeniu (parametry l. Param i w. Param). • Przykład zdarzeń związanych z myszką: wchar_t txt_x[256]; wchar_t txt_y[256]; _itow_s(LOWORD(l. Param), txt_x, 256, 10); _itow_s(HIWORD(l. Param), txt_y, 256, 10); edit 1. Set. Window. Text(txt_x); edit 2. Set. Window. Text(txt_y);

Odczytywanie danych z kom. • Komunikaty zwykle przekazują dodatkowe informacje o zdarzeniu (parametry l.

Odczytywanie danych z kom. • Komunikaty zwykle przekazują dodatkowe informacje o zdarzeniu (parametry l. Param i w. Param). • Odczytanie klawiatury: BOOL CKomunikaty. Dlg: : Pre. Translate. Message(MSG* p. Msg) { //tu nie bedzie WM_CHAR if (p. Msg->message == WM_KEYDOWN && p. Msg->w. Param == VK_ESCAPE) { Beep(300, 200); }. . .

Wysyłanie komunikatów • Uwaga! Standardowe funkcje Win. API mają opakowania w klasie CWnd (MFC),

Wysyłanie komunikatów • Uwaga! Standardowe funkcje Win. API mają opakowania w klasie CWnd (MFC), które często „przesłaniają” zasadnicze funkcje. • Wysyłanie komunikatów: Post. Message vs Send. Message. Pierwsza wysyła komunikat tradycyjnie tj. do kolejki komunikatów okna/kontrolki, druga – pomija kolejkę i wysyła bezpośrednio do okna/kontrolki. this->Post. Message(WM_CLOSE); //metoda klasy CWnd : : Post. Message( //funkcja czystego Win. API this->m_h. Wnd, //uchwyt okna-adresata WM_CLOSE, //identyfikator komunikatu 0, 0); //l. Param i w. Param

Wysyłanie komunikatów • Uwaga! Standardowe funkcje Win. API mają opakowania w klasie CWnd (MFC),

Wysyłanie komunikatów • Uwaga! Standardowe funkcje Win. API mają opakowania w klasie CWnd (MFC), które często „przesłaniają” zasadnicze funkcje. • Wysyłanie komunikatów: Post. Message vs Send. Message. Pierwsza wysyła komunikat tradycyjnie tj. do kolejki komunikatów okna/kontrolki, druga – pomija kolejkę i wysyła bezpośrednio do okna/kontrolki. this->Send. Message(WM_SYSCOMMAND, SC_SCREENSAVE, 0); : : Send. Message( this->m_h. Wnd, WM_SYSCOMMAND, SC_SCREENSAVE, 0); Niektóre aplikacje pozwalają na ich kontrolowanie za pomocą komunikatów (np. Win. Amp i Adobe).

Znajdywanie uchwytu okna • Uchwyty okien (w tym kontrolek) można szukać korzystając z funkcji

Znajdywanie uchwytu okna • Uchwyty okien (w tym kontrolek) można szukać korzystając z funkcji Find. Window podając tytuł okna lub nazwę jego klasy (zob. też Find. Window. Ex): : : Post. Message( : : Find. Window(NULL, L"Komunikaty"), WM_CLOSE, 0, 0); • Przeszukiwanie okien w poszukiwaniu tych o konkretnych własnościach: Enum. Window i Enum. Child. Windows • Window. From. Point, Child. Window. From. Point • Get. Desktop. Window, Get. Foreground. Window, Get. Next. Window, Is. Window. Visible

Haki • Można napisać bibliotekę DLL, która będzie ładowana do przestrzeni adresowej aplikacji w

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.

Przykładowe pytania • Jakich funkcji Win. API można użyć do wysłania komunikatu? • Jakie

Przykładowe pytania • Jakich funkcji Win. API można użyć do wysłania komunikatu? • Jakie wartości zwraca funkcja Get. Message? • 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 oknachdzieciach? • 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.

Dodatek: Opis błędów • Pobieranie opisu błędów dla wskazanego kodu błędu: Format. Message •

Dodatek: Opis błędów • Pobieranie opisu błędów dla wskazanego kodu błędu: Format. Message • Wyświetlanie: Message. Box (najpopularniejsza funkcja Win. API) • Demo: Format. Message (MFC)