Tworzenie aplikacji Windows Podstawy obsługi komunikatów Windows (C++ Builder)

Podobne dokumenty
Tworzenie aplikacji Windows Podstawy obsługi komunikatów Windows (Delphi)

Komunikaty w Windows. Jarosław Kuchta

Programowanie na poziomie sprzętu. Programowanie w Windows API

Tworzenie aplikacji Windows Mechanizm drag n drop

Budowa aplikacji z graficznym interfejsem użytkownika - GUI (Graphic User Interface)

Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład.

Szkolenie dla nauczycieli SP10 w DG Operacje na plikach i folderach, obsługa edytora tekstu ABC. komputera dla nauczyciela. Materiały pomocnicze

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

CZĘŚĆ A PIERWSZE KROKI Z KOMPUTEREM

Delphi podstawy programowania. Środowisko Delphi

Microsoft Visual C++

Instrukcja. importu dokumentów. z programu Fakt do programu Płatnik. oraz. przesyłania danych do ZUS. przy pomocy programu Płatnik

Programowanie w języku Python. Grażyna Koba

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Rozdział 5. Administracja kontami użytkowników

Podstawy programowania w języku C dla środowiska Windows

Przykładowa dostępna aplikacja w Visual Studio - krok po kroku

Utworzenie pliku. Dowiesz się:

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

Informatyka II. Laboratorium Aplikacja okienkowa

Makra Access 2003 wg WSiP Wyszukiwanie, selekcjonowanie i gromadzenie informacji Ewa Mirecka

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Wprowadzenie do systemu Delphi

Obsługa grafiki w Delphi, rysowanie na płótnie, obsługa myszki, zapisywanie obrazków do plików, bitmapy pozaekranowe.

1. Przypisy, indeks i spisy.

Programowanie w środowisku graficznym GUI

Dell UltraSharp UP3017 Dell Display Manager Instrukcja użytkownika

Przygotowanie własnej procedury... 3 Instrukcja msgbox wyświetlanie informacji w oknie... 6 Sposoby uruchamiania makra... 8

Obliczenie azymutu ze współrzędnych wersja C++ Builder

Baltie 3. Podręcznik do nauki programowania dla klas I III gimnazjum. Tadeusz Sołtys, Bohumír Soukup

Programowanie zaawansowane

Rozdział 1. Zagadnienia podstawowe

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Dostęp do poczty przez www czyli Kerio Webmail Poradnik

Projektowanie i programowanie aplikacji biznesowych. Wykład 2

Lekcja 5. Funkcje handlemessage() i initialize(), konstruktor i destruktor

Programowanie w języku C++ z użyciem Windows API

Celem ćwiczenia jest zapoznanie się z podstawowymi funkcjami i pojęciami związanymi ze środowiskiem AutoCAD 2012 w polskiej wersji językowej.

I Tworzenie prezentacji za pomocą szablonu w programie Power-Point. 1. Wybieramy z górnego menu polecenie Nowy a następnie Utwórz z szablonu

Instrukcja importu dokumentów z programu Fakt do programu Płatnik

Delphi 7 + Indy 10 Przykłady prostych aplikacji sieciowych

Podręcznik Użytkownika aplikacji NOVO Szkoła. Profil Ucznia

EDYCJA TEKSTU MS WORDPAD

Programowanie obiektowe

5. Administracja kontami uŝytkowników

Ćwiczenie 6 Proste aplikacje - podstawowe komponenty.

Podręcznik Użytkownika aplikacji NOVO Szkoła. Profil Opiekuna

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

PWI Instrukcja użytkownika

Słowa kluczowe Sterowanie klawiaturą, klawiatura, klawisze funkcyjne, przesuwanie obiektów ekranowych, wydawanie poleceń za pomocą klawiatury

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Zdarzenia Zdarzenia onload i onunload

Wprowadzenie do projektu QualitySpy

Baltie - programowanie

14. TWORZENIE MAKROPOLECEŃ

Kurs programowania 2 - listy

5.4. Tworzymy formularze

Edytor tekstu OpenOffice Writer Podstawy

Temat: Organizacja skoroszytów i arkuszy

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Nawigacja po długim dokumencie może być męcząca, dlatego warto poznać następujące skróty klawiszowe

BACKUP BAZ DANYCH FIREBIRD

Podręczna pomoc Microsoft Power Point 2007

Zastanawiałeś się może, dlaczego Twój współpracownik,

Nr: 15. Tytuł: Kancelaris w systemie Windows 8 i Windows 8.1. Data modyfikacji:

WASTE MANAGEMENT SYSTEM PODRĘCZNIK UŻYTKOWNIKA SERWISU WWW

Tworzenie prezentacji w MS PowerPoint

Politechnika Poznańska Wydział Budowy Maszyn i Zarządzania

Visual Basic w programie Excel dla Windows

MS Word Długi dokument. Praca z długim dokumentem. Kinga Sorkowska

Laboratorium - Monitorowanie i zarządzanie zasobami systemu Windows 7

Podstawy programowania. Ćwiczenie. Pojęcia bazowe. Języki programowania. Środowisko programowania Visual Studio

Dodawanie grafiki i obiektów

5.2. Pierwsze kroki z bazami danych

Advance CAD 2016 SP2. W tym dokumencie opisano ulepszenia w Advance CAD Service Pack 2. Co nowego w Advance CAD 2016 SP2

Nagrywanie Makr. Na karcie Dostosowywanie Wstążki zaznaczamy kartę Deweloper.

OBIEKTY TECHNICZNE OBIEKTY TECHNICZNE

Temat: Programowanie zdarzeniowe. Zdarzenia: delegacje, wykorzystywanie zdarze. Elementy Windows Application (WPF Windows Presentation Foundation).

MS Access formularze

Zadanie 3. Praca z tabelami

INSTRUKCJA INSTALACJI I URUCHOMIENIA PROGRAMÓW FINKA DOS W SYSTEMACH 64 bit

Programowanie Obiektowe GUI

Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 1 Tworzenie plików pomocy Programowanie Wizualno Obiektowe Zajęcia 5, część 1

Komputery I (2) Panel sterowania:

Dodanie nowej formy do projektu polega na:

Program V-SIM tworzenie plików video z przebiegu symulacji

BAZY DANYCH Panel sterujący

Systemy operacyjne I Laboratorium Część 3: Windows XP

1.Formatowanie tekstu z użyciem stylów

Jest to program stworzony z myślą o nauczycielach, wykładowcach, trenerach i prezenterach.

Kontrola topto. 1. Informacje ogólne. 2. Wymagania sprzętowe i programowe aplikacji. 3. Przykładowa instalacja topto. 4. Komunikacja.

UMOWY INSTRUKCJA STANOWISKOWA

Użycie przestrzeni papieru i odnośników - ćwiczenie

Zaawansowany kurs języka Python

Laboratorium z Grafiki InŜynierskiej CAD. Rozpoczęcie pracy z AutoCAD-em. Uruchomienie programu

Nazwa implementacji: Kółko i krzyżyk w Lazarusie. Autor: Piotr Fiorek Andrzej Stefaniuk

Rejestracja faktury VAT. Instrukcja stanowiskowa

Ćwiczenia nr 2. Edycja tekstu (Microsoft Word)

Site Installer v2.4.xx

Podstawy technologii WWW

Transkrypt:

Jacek Matulewski http://www.phys.uni.torun.pl/~jacek/ Tworzenie aplikacji Windows Podstawy obsługi komunikatów Windows (C++ Builder) Ćwiczenia Toruń, 2 grudnia 2002 Najnowsza wersja tego dokumentu znajduje się pod adresem http://www.phys.uni.torun.pl/~jacek/dydaktyka/rad/rad4_wm_cbuilder.pdf Źródła opisanych w tym dokumencie programów znajdują się pod adresem http://www.phys.uni.torun.pl/~jacek/dydaktyka/rad/rad4_wm.zip 1

I. Spis treści I. Spis treści... 2 II. Odbieranie i wysyłanie komunikatów...3 1. Lista komunikatów odbieranych przez aplikację... 3 2. Śledzenie komunikatów dotyczących ruchu myszy w obrębie aplikacji... 4 3. Metody obsługujące komunikaty: zmiana położenia formy... 5 4. Wysyłanie komunikatów: wykrycie zmiany trybu pracy karty graficznej... 6 5. Blokowanie zamknięcia sesji Windows... 7 6. Jeszcze raz wysyłanie komunikatów... 7 2

II. Odbieranie i wysyłanie komunikatów Komunikat Windows jest informacją przekazywaną przez system do aplikacji dotyczącą szczególnej sytuacji w systemie związanej bądź z działaniem użytkownika (np. przesunięcie myszy, naciśnięcie klawisza, zamknięcie okna itp.) lub wynikającej z funkcjonowania systemu (np. odmalowanie formy, zamknięcie sesji Windows itp.). Przekazywana przez komunikat informacja dotyczy przede wszystkim rodzaju zdarzenia, której jest skutkiem oraz związanych z tą sytuacją parametrów (zawsze czas wystąpienia, położenie myszy oraz np. naciśnięty klawisz). Mechanizm komunikatów Windows (ang. Windows messages) stracił na znaczeniu w środowisku Delphi/C++ Builderze po wprowadzeniu mechanizmu zdarzeń w obiektach VCL. Większość komunikatów, a wszystkie istotne w codziennej praktyce programowania aplikacji Windows, jest reprezentowana przez odpowiednie zdarzenia. Co więcej operowanie zdarzeniami jest bezpieczniejsze. Jest jednak kilka szczególnych zdarzeń nie mających swojej reprezentacji wśród zdarzeń obiektów VCL wymagających ręcznej obsługi. Przykładem może być komunikat związany z przesunięciem okna (TForm nie ma zdarzenia OnMove). Etapy systemowej obsługi komunikatów są następujące: 1. W reakcji na sytuację w systemie lub działanie użytkownika system tworzy strukturę typu tagmsg (opis w Win32 SDK) zawierającą uchwyt okna którego dotyczy komunikat, numer zdarzenia systemowego (w Win32 SDK opisane są stałe identyfikujące komunikaty, nazwy stałych zaczynają się zawsze od WM_ (ang. Windows Message), definicje stałych można też znaleźć w C++ Builderze w pliku winuser.h), dwa elementy przekazujące informację o zdarzeniu wparam i lparam, czas wystąpienia zdarzenia i położenie myszki. Znaczenie parametrów wparam i lparam opisane jest oddzielnie dla każdego komunikatu w Win32 SDK. 2. Struktura zostaje umieszczona w kolejce komunikatów aplikacji, której okno jest adresatem przesyłanego komunikatu. 3. Aplikacja odbiera komunikat i przekazuje go do właściwego okna (zgodnie z uchwytem w komunikacie) 4. Wywoływana jest metoda obsługująca komunikat (np. WM_PAINT spowoduje odmalowanie formy). Od tej reguły są wyjątki niektóre komunikaty przekazywane są bezpośrednio do właściwego okna z pominięciem kolejki aplikacji. 1. Lista komunikatów odbieranych przez aplikację Obiekt Application (tworzony automatycznie w momencie uruchomienia aplikacji) posiada zdarzenie OnMessage. W nowszych wersjach C++ Buildera dostęp do tego i innych zdarzeń Application został ułatwiony dzięki komponentowi TApplicationEvents. Umieśćmy ten komponent na formie i stwórzmy szkielet metody zdarzeniowej ApplicationEvents1Message(). Uruchamiana będzie zawsze, gdy aplikacja odbierze komunikat. Pierwszym argumentem tej metody jest referencja do struktury komunikatu. Najprostszym zastosowaniem tego zdarzenia jest wyświetlanie listy odebranych komunikatów (nie dotyczy to komunikatów wysyłanych bezpośrednio do okna z pominięciem obiektu aplikacji): ListBox1->Items->Add(Msg.message); Wcześniej należy umieścić na formie ListBox1 i ustalić liczbę kolumn na np. 15 (ListBox musi być duży, żeby pomieścić efekty ruchu myszki). Można też reagować na wybrane przez nas zdarzenia: void fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg, bool &Handled) 3

switch (Msg.message) //Odmalowywanie okna case WM_PAINT: ListBox1->Items->Add("WM_PAINT"); break; //Myszka case WM_LBUTTONDOWN: ListBox1->Items->Add("WM_LBUTTONDOWN"); break; case WM_LBUTTONUP: ListBox1->Items->Add("WM_LBUTTONUP"); break; case WM_LBUTTONDBLCLK: ListBox1->Items->Add("WM_LBUTTONDBLCLK"); break; case WM_RBUTTONDOWN: ListBox1->Items->Add("WM_RBUTTONDOWN"); break; case WM_RBUTTONUP: ListBox1->Items->Add("WM_RBUTTONUP"); break; case WM_RBUTTONDBLCLK: ListBox1->Items->Add("WM_RBUTTONDBLCLK"); break; //Klawiatura case WM_KEYDOWN: ListBox1->Items->Add("WM_KEYDOWN"); break; case WM_KEYUP: ListBox1->Items->Add("WM_KEYUP"); break; case WM_CHAR: ListBox1->Items->Add("WM_CHAR"); break; Pominięto dwa komunikaty związane z ruchem myszy: WM_MOUSEMOVE (w obrębie client area) i WM_NCMOUSEMOVE (poza nim, ale w obrębie okna). Poza rozpoznaniem nazwy można by oczywiście wyświetlić dodatkowe informacje są one dostępne w strukturze Msg. Śledzenie komunikatów w ten sposób nie zmienia ich obsługi przez odpowiednie metody formy (TForm). 2. Śledzenie komunikatów dotyczących ruchu myszy w obrębie aplikacji Stosując zdarzenie OnMessage udostępnione w TApplicationEvents będziemy śledzić położenie myszy tj. zareagujemy na komunikaty WM_MOUSEMOVE i WM_NCMOUSEMOVE. Tworzymy nowy projekt. Na formie umieszczamy cztery komponenty TLabel (w tym przykładzie pokazanym na rysunku dodatkowy obiekt Label3 wykorzystany jest przez znak x pomiędzy Label2 i Label4). Dodajemy również drugą formę i ustalamy jej własność Visible=True. Dalej postępujemy jak w poprzednim paragrafie, z tym, że w metodzie zdarzeniowej umieszczamy następujący kod: void fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg, bool &Handled) switch (Msg.message) case WM_MOUSEMOVE: Label1->Caption="W obrębie client area formy (wsp. okna)"; Label2->Caption=LOWORD(Msg.lParam); Label4->Caption=HIWORD(Msg.lParam); if (Msg.hwnd==Form1->Handle) Label5->Caption="Form1"; else Label5->Caption="Form2"; break; case WM_NCMOUSEMOVE: Label1->Caption="Poza client area formy (wsp. ekranu)"; Label2->Caption=LOWORD(Msg.lParam); Label4->Caption=HIWORD(Msg.lParam); if (Msg.hwnd==Form1->Handle) 4

Label5->Caption="Form1"; else Label5->Caption="Form2"; break; Widać, że aplikacja odbiera komunikaty skierowane do obu form. Jeżeli myszka znajduje się wewnątrz obszaru dostępnego dla użytkownika (ang. client area) przekazywane przez komunikat współrzędne położenia myszy to współrzędne względem formy, a dokładniej względem lewego górnego rogu obszaru użytkownika. Poza nim (a więc na brzegu okna, na pasku tytułu) są to współrzędne ekranu. Zadanie Uzgodnić współrzędne wyświetlane w przypadku obu komunikatów na współrzędne ekranu lub okna korzystając z funkcji WinAPI ClientToScreen lub ScreenToClient (ewentualnie z metod TForm o tych samych nazwach). Punkt zapisać korzystając ze struktury WinAPI tagpoint (w C++ Builderze występuje też jako TPoint) 3. Metody obsługujące komunikaty: zmiana położenia formy Niestety kilka ciekawych komunikatów nie przechodzi przez aplikację. Wśród nich komunikaty związane ze zmianą rozmiaru i położenia okna. O ile zmiana rozmiaru jest obsługiwana przez zdarzenie OnResize formy, to poruszenie okna nie ma odzwierciedlenia w VCL. Możemy jednak przechwycić komunikat i napisać do niego metodę obsługi. Musi być to dosłownie metoda, a nie funkcja, gdyż komunikat dotyczyć będzie obiektu i tylko metoda tego obiektu może go obsłużyć. W ten sposób na poziomie obiektu możemy przechwycić wszystkie komunikaty, nawet te, które omijają kolejkę aplikacji. Zadeklarujmy metodę, najlepiej w sekcji private lub protected, o nazwie związanej z nazwą obsługiwanego komunikatu w ten sposób, że pomijamy znak podkreślenia i część znaczącą nazwy piszemy tzw. stylem wielbłądzim (oddzielne słowa piszemy razem, ale zaznaczamy wielkimi literami). Z WM_MOVE powstaje WMMove, z WM_MOUSEMOVE WMMouseMove. protected: void fastcall WMMove(TMessage& Msg); W następnych liniach deklaracji klasy musimy za pomocą odpowiednich makr przechwycić komunikat i skierować go do tej metody: MESSAGE_HANDLER(nazwa_komunikatu, typ_struktury_komunikatu, nazwa_metody) /* tu dodajemy kolejne przechwycenia */ END_MESSAGE_MAP(klasa_bazowa) Makra te dbają o wywołanie odpowiedniej metody obsługi klasy bazowej. W naszym przypadku: MESSAGE_HANDLER(WM_MOVE, TMessage, WMMove) END_MESSAGE_MAP(TForm) 5

1 Pozostaje tylko napisać odpowiednią metodę może to być na przykład: void fastcall TForm1::WMMove(TMessage& Msg) if (CheckBox1->Checked) MessageBeep(0); FlashWindow(Application->Handle,true); Zadanie Stworzyć komponent dziedziczący z TForm zawierający zdarzenie OnMove. 4. Wysyłanie komunikatów: wykrycie zmiany trybu pracy karty graficznej 2 Jest pewna grupa komunikatów, które rozsyłane są do wszystkich aplikacji. Związane są one najczęściej ze zmianą parametrów systemu np. wylogowanie użytkownika lub zmiana rozdzielczości karty graficznej. Użytkownik może zareagować na wysłanie także tych komunikatów. Zrobimy to pisząc odpowiednie metody obsługi. Zmiana trybu pracy karty graficznej (a co za tym idzie także monitora) powoduje wysłanie komunikatu WM_DISPLAYCHANGE. Przechwyćmy komunikat deklarując metodę i jej przechwycenie podobnie jak w poprzednim paragrafie: protected: void fastcall WMDisplayChange(TMessage& Msg); MESSAGE_HANDLER(WM_DISPLAYCHANGE, TMessage, WMDisplayChange) END_MESSAGE_MAP(TForm) oraz definiując metodę, która zapisuje nowe parametry ekranu do Memo1: #define pisz(a) Memo1->Lines->Add(A) void fastcall TForm1::WMDisplayChange(TMessage& Msg) pisz("zmiana rozdzielczości:"); pisz("komunikat Windows: "+(AnsiString)(double)Msg.Msg); pisz("kolory: "+(AnsiString)(double)Msg.WParam+" bitów"); pisz("rozdzielczość: "+(AnsiString)LOWORD(Msg.LParam)+" x "+(AnsiString)HIWORD(Msg.LParam)); pisz(""); #undef pisz Przed metodą zostało zdefiniowane makro, które zastępuje długi łańcuch dodawania łańcucha do Memo1. Jeżeli po uruchomieniu aplikacji chcemy uzyskać aktualne parametry możemy to zrobić bardzo prosto wysyłając komunikat do okna za pomocą funkcji SendMessage() lub PostMessage(). Pierwsza wysyła komunikat bezpośrednio do okna, druga do kolejki komunikatów jego aplikacji. Tylko ta druga spowoduje wywołanie 1 Częstym błędem jest umieszczanie w END_MESSAGE_MAP() klasy bieżącej zamiast bazowej. 2 Paragraf ten można potraktować jako kontynuację rozdziału VI w części dotyczącej WinAPI. 6

zdarzenia Application->OnMessage. Parametry obu funkcji są identyczne: uchwyt do okna, numer komunikatu, lparam, wparam. Dopiszmy przed usunięciem makra: void fastcall TForm1::FormCreate(TObject *Sender) pisz("rozpoznawamie parametrów wyświetlania (wysyłanie komunikatu):"); SendMessage(Form1->Handle,WM_DISPLAYCHANGE, GetDeviceCaps(Form1->Canvas->Handle,PLANES)* GetDeviceCaps(Form1->Canvas->Handle,BITSPIXEL), (DWORD)(Screen->Height<<16)+Screen->Width); W trzecim argumencie badamy ilość kolorów (dokładniej ilość bitów, ilość kolorów możemy uzyskać podnosząc 2 do tej liczby) 3. W ostatnim argumencie, 32-bitowym DWORD, musimy umieścić informacje o rozdzielczości ekranu, tak, aby wysokość zajmowała pierwsze 16-bitów, a szerokość drugie. 5. Blokowanie zamknięcia sesji Windows Kolejnym przykładem przechwycenia obsługi komunikatów systemowych jest zablokowanie zamknięcia systemu przez aplikację. Można oczywiście zrobić podobnie działającą aplikację korzystając ze zdarzenia TForm->OnCloseQuery, ale wynik nie jest do końca satysfakcjonujący ponieważ nie w każdej sytuacji system pyta aplikację o pozwolenie zamknięcia. Natomiast obsługa komunikatu WM_QUERYENDSESSION daje bardzo dobre rezultaty. Postępujemy podobnie jak poprzednio. Do deklaracji klasy dodajemy protected: void fastcall WMQueryEndSession (TWMQueryEndSession& Message); MESSAGE_HANDLER(WM_QUERYENDSESSION, TWMQueryEndSession, WMQueryEndSession); END_MESSAGE_MAP(TForm) natomiast w pliku głównym definiujemy metodę obsługi komunikatu jak poniżej: void fastcall TForm1::WMQueryEndSession(TWMQueryEndSession& Message) ShowMessage("Zamknięcie sesji Windows zablokowane"); FlashWindow(Application->Handle,true); Message.Result=0; Po uruchomieniu aplikacji próba zamknięcia systemu zakończy się jedynie wyświetleniem odpowiedniego komunikatu. 6. Jeszcze raz wysyłanie komunikatów Przykład wysyłania komunikatu mieliśmy w paragrafie II.4. Teraz jeszcze tylko jeden zabawny przykład. Wysyłając komunikat do systemu można spowodować włączenie wygaszacza ekranu. Wystarczy wykonać polecenie: SendMessage(Application->Handle,WM_SYSCOMMAND,SC_SCREENSAVE,0); 3 Możliwości funkcji WinAPI GetDeviceCaps() są znacznie szersze. Zob. opis w Win32 SDK. 7