1 / 18

Komunikaty Windows

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

onawa
Download Presentation

Komunikaty Windows

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Zaliczenie Lab.: projekt (obowiązkowy)Wybór z listy do końca październikaWłasny po mojej akceptacji Lab.: referat lub kolokwium (pisanie kodu)Wybór tematu referatu z listy do końca wrześniaReferat na lab. („ręce na klawiaturze”) lub na wykładziePrezentacja (ppt/pdf) + 2 pytania Wykład: egzaminTeoretyczny (bez programowania na żywo)

  3. 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_PAINTWM_DISPLAYCHANGE, WM_DEVICECHANGEWM_QUERYENDSESSION, WM_ENDSESSION, WM_SYSCOMMAND, WM_USER • http://www.autohotkey.com/docs/misc/SendMessageList.htm

  4. 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;}

  5. Pętla główna typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG, *PMSG, *LPMSG; • 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 Przekształcanie komunikatów (klawiatury) Rozsyłanie komunikatów do okien-adresatów (w tym kontrolek)

  6. 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.

  7. Procedura okna to funkcja zwrotna (wskazywana w momencie rejestracji klasy okna), która jest wywoływana po otrzymaniu 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

  8. W 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); } hwnd – uchwyt okna, czyli jednoznaczny identyfikator w danej sesji systemu Filtrowanie komunikatów 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 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;} 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.

  9. 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);}

  10. Demo (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)?

  11. 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()

  12. 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);

  13. 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); } ...

  14. 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

  15. 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).

  16. 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

  17. 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.

  18. 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.

More Related