Cechy systemu Windows Wielozadaniowość Współdzielenie zasobów sprzętowych: ekran klawiatura mysz pamięć dysk Wymiana danych pomiędzy aplikacjami Niezależna sprzętowo grafika Zdefiniowany w systemie interfejs użytkownika Biblioteki dynamiczne
Prefiks b c cx,cy dw h l n p pt rc str sz w wnd Notacja węgierska Typ BOOL char odległość wzdłuż osi X, Y DWORD uchwyt LONG int wskaźnik CPoint lub POINT CRect lub RECT CString string zakończony zerem WORD CWnd
Budowanie aplikacji Pliki z kodem źródłowym *.cpp *.h Plik zasobów *.rc elementy interfejsu użytkownika ikony czcionki bitmapy menu paski narzędzi okna dialogowe biblioteki statyczne *.lib dynamiczne *.dll
Obsługa wiadomości
Obsługa wiadomości
Obsługa wiadomości WM_DESTROY
Przykładowa aplikacja Wersja tekstowa #include <stdio.h> void main( void ) { printf( Hello world! ); } Wersja graficzna
Przykładowa aplikacja #include <windows.h> LONG WINAPI WndProc( HWND, UINT, WPARAM, LPARAM ); int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdline, int ncmdshow ) { static char szappname[] = MyApp ; WNDCLASS wc; HWND hwnd; MSG msg; wc.style = 0; //styl klasy wc.lpfnwndproc = (WNDPROC)WndProc; //adres procedury obsługi zdarzeń wc.cbclsextra = 0; //liczba bajtów obszaru danych klasy wc.cbwndextra = 0; //liczba bajtów obszaru danych okna wc.hinstance = hinstance; //uchwyt do instancji aplikacji wc.hicon = LoadIcon( NULL, IDI_APPLICATION ); //uchwyt do ikony wc.hcursor = LoadCursor( NULL, IDC_ARROW ); //uchwyt do kursora wc.hbrbackground = COLOR_WINDOW + 1; //kolor tła wc.lpszmenuname = NULL; //nazwa menu wc.lpszclassname = szappname; //nazwa klasy RegisterClass( & wc );
Przykładowa aplikacja hwnd = CreateWindow( szappname, //nazwa WNDCLASS szappname, //tytuł okna WS_OVERLAPPEDWINDOW, //styl okna CW_USEDEFAULT, CW_USERDEFAULT, //pozycja CW_USEDEFAULT, CW_USEDEFAULT, //rozmiar HWND_DESKTOP, //uchwyt do okna rodzica NULL, //uchwyt do menu hinstance, //uchwyt do instancji aplikacji NULL ); //dane (tworzenie okna) ShowWindow( hwnd, ncmdshow ); UpdateWindow( hwnd ); //pętla obsługi wiadomości while( GetMessage( & msg, NULL, 0, 0 ) ) //pobranie wiadomości z kolejki { TranslateMessage( & msg ); //przekształcenie wiadomości (klawiatura) DispatchMessage( & msg ); //przekazanie wiad. do proc. obsługi zdarzeń } return msg.wparam; }
Przykładowa aplikacja LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT ps; HDC hdc; RECT rect; switch( message ) { case WM_PAINT: hdc = BeginPaint( hwnd, & ps ); GetClientRect( hwnd, & rect ); DrawText( hdc, Hello Windows!, -1, & rect, DT_SINGLELINE DT_CENTER DT_VCENTER ); EndPaint( hwnd, & ps ); return 0; case WM_DESTROY: PostQuitMessage( 0 ); //wysłanie wiadomości WM_QUIT return 0; } return DefWindowProc( hwnd, message, wparam, lparam ); }
Przetwarzanie wiadomości WM_PAINT WM_SIZE WM_COMMAND WM_TIMER WM_KEYDOWN Kolejka wiadomości Aplikacja WinMain Procedura obsługi zdarzeń okna Pętla obsługi wiadomości DefWindowProc
Funkcje Windows API typedef struct _WNDCLASS { UINT style; //styl klasy WNDPROC lpfnwndproc; // adres procedury obsługi zdarzeń int cbclsextra; // liczba bajtów obszaru danych klasy int cbwndextra; // liczba bajtów obszaru danych okna HANDLE hinstance; //uchwyt do instancji aplikacji HICON hicon; //uchwyt do ikony HCURSOR hcursor; //uchwyt do kursora HBRUSH hbrbackground; //kolor tła LPCTSTR lpszmenuname;//nazwa menu LPCTSTR lpszclassname;//nazwa klasy } WNDCLASS; ATOM RegisterClass{ CONST WNDCLASS *lpwc ); int WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpszcmdline, int ncmdshow ); // uchwyt do instancji aplikacji // uchwyt do poprzedniej instancji aplikacji // adres linii poleceń // sposób wyświetlenia okna
Funkcje Windows API HWND CreateWindow( LPCTSTR lpszclassname, LPCTSTR lpszwindowname, DWORD dwstyle, int x, int y, int nwidth, int nheight, HWND hwndparent, HMENU hmenu, HANDLE hinst, LPVOID lpvparam ); BOOL ShowWindow( HWND hwnd, // uchwyt do okna int ncmdshow ); // sposób wyświetlenia okna BOOL UpdateWindow( HWND hwnd ); // uchwyt do okna // nazwa klasy (WNDCLASS) // tytuł okna // styl okna // położenie okna (x) // położenie okna (y) // szerokość okna // wysokość okna // uchwyt do okna rodzica // uchwyt do menu // uchwyt do instancji aplikacji // dane (tworzenie okna)
typedef struct tagmsg { HWND hwnd; UINT message; WPARAM wparam; LPARAM lparam; DWORD time; POINT pt; } MSG; BOOL GetMessage( LPMSG lpmsg, HWND hwnd, UINT umsgfiltermin, UINT umsgfiltermax ); Funkcje Windows API BOOL TranslateMessage( MSG *lpmsg ); LONG DispatchMessage( CONST MSG *lpmsg ); // uchwyt do okna (odbiorca wiadomości) // numer wiadomości // parametr wiadomości // parametr wiadomości // czas wysłania wiadomości // pozycja kursora w chwili wysłania wiadomości // adres struktury z wiadomością // uchwyt do okna (adresat wiadomości) // najmniejszy numer która będzie pobierana // największy numer która będzie pobierana
Funkcje Windows API HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lpps ); BOOL EndPaint( HWND hwnd, CONST PAINTSTRUCT *lppaint ); typedef struct _PAINTSTRUCT { HDC hdc; BOOL ferase; RECT rcpaint; BOOL frestore; BOOL fincupdate; BYTE rgbreserved[32]; } PAINTSTRUCT; HDC GetDC( HWND hwnd ); int ReleaseDC( HWND hwnd,hdc hdc ); BOOL TextOut( HDC hdc, int nxstart, int nystart, LPCTSTR lpstring, int cbstring ); // uchwyt do kontekstu urządzenia // flaga określająca, czy będzie czyszczone tło // prostokąt gdzie będzie można rysować // zarezerwowane przez Windows // zarezerwowane przez Windows // zareserwowane przez Windows // uchwyt do kontekstu urządzenia // współrzędna x // współrzędna y // adres ciągu do wyświetlenia // liczba znaków do wyświetlenia
Hierarchia okien Windows zarządza oknami używając zależności: widoczność własność relacja ojciec\dziecko Każde okno przechowuje: uchwyt do okna dziecka uchwyt do następnego okna w liście dzieci (brata) uchwyt do okna rodzica uchwyt do okna właściciela
Hierarchia okien
Hierarchia okien Desktop window jest korzeniem list dla menadżera okien Top level windows - kolejny poziom w hierarchii (wszystkie okna, które nie są dziećmi WS_OVERLAPPED, WS_POPUP) Child window okna dzieci (WS_CHILD) Właścicielem okna top-level może być inne okno tego typu lub pulpit Właścicielem okna dziecka może być okno typu top-level
Hierarchia okien Usunięcie okna (DestroyWindow) powoduje: Usunięcie wszystkich dzieci tego okna Usunięcie okien, których to okno jest właścicielem Wyświetlenie modalnego okna dialogowego powoduje: Wyłączenie (disable) okna które jest właścicielem tego okna dialogowego (i wszystkich jego dzieci)
Kategorie funkcji GDI Pobierające i zwalniają kontekst urządzenia Pozyskujące informacje o kontekście urządzenia Rysujące Ustawiające i pobierające parametry kontekstu urządzenia Pracujące z obiektami GDI
Pobieranie HDC W obsłudze wiadomości WM_PAINT (rysujemy w obszarze roboczym okna) case WM_PAINT : hdc = BeginPaint( hwnd, & ps );... EndPaint( hwnd, & ps ); break; W obsłudze dowolnej wiadomości (rysujemy w obszarze roboczym okna) hdc = GetDC( hwnd );... ReleaseDC( hwnd, hdc );
Pobieranie HDC W obsłudze dowolnej wiadomości (rysujemy w całym oknie) hdc = GetWindowDC( hwnd );... ReleaseDC( hwnd, hdc ); Tworzenie kontekstu urządzenia CreateDC( pszdriver, pszdevice, pszoutput, pdata ); hdc = CreateDC( DISPLAY, NULL, NULL, NULL );... DeleteDC( hdc ); Pobieranie uchwytu do kontekstu (tylko informacje) CreateIC( pszdriver, pszdevice, pszoutput, pdata ); hdc = CreateIC( DISPLAY, NULL, NULL, NULL );... DeleteDC( hdc );
Wiadomość WM_PAINT Jest generowana przez system gdy okno wymaga odświeżenia BOOL InvalidateRect( HWND hwnd, CONST RECT *lprc, BOOL ferase ); Jest sklejana w kolejce wiadomości (maksymalnie jedna wiadomość WM_PAINT dla okna) Jest usuwana z kolejki przez funkcję EndPaint case WM_PAINT : hdc = BeginPaint( hwnd, & ps );... EndPaint( hwnd, & ps ); break;
Wiadomość WM_PAINT Zawiera informacje (PAINTSTRUCT) o obszarze wymagającym odświeżenia Umożliwia rysowanie tylko w obszarze wymagającym odświeżenia typedef struct _PAINTSTRUCT { HDC hdc; // uchwyt do kontekstu urządzenia BOOL ferase; // flaga określająca, czy będzie czyszczone tło RECT rcpaint; // prostokąt gdzie będzie można rysować BOOL frestore; // zarezerwowane przez Windows BOOL fincupdate; // zarezerwowane przez Windows BYTE rgbreserved[32]; // zareserwowane przez Windows } PAINTSTRUCT;
Parametry kontekstu urządzenia Atrybut Wart. domyślna Ustawianie Odczyt Kolor tekstu Czarny SetTextColor GetTextColor Kolor tła Biały SetBkColor GetBkColor Sposób wypełniania tła OPAQUE SetBkMode GetBkMode Tryb odwzorowania MM_TEXT SetMapMode GetMapMode Początek okna ( 0, 0 ) SetWindowOrgEx GetWindowOrgEx Początek widoku ( 0, 0 ) SetViewportOrgEx GetViewportOrgEx Rozciągłość okna ( 1, 1 ) SetWindowExtEx GetWindowExtEx Rozciągłość widoku ( 1, 1 ) SetViewportExtEx GetViewportExtEx Tryb rysowania R2_COPYPEN SetROP2 GetROP2 Pozycja pióra ( 0, 0 ) MoveTo GetCurrentPosition Pióro BLACK_PEN SelectObject SelectObject Pędzel WHITE_BRUSH SelectObject SelectObject Czcionka SYSTEM_FONT SelectObject SelectObject
Parametry kontekstu urządzenia Tryb odwzorowania Jednostka logiczna MM_TEXT 1 piksel MM_LOMETRIC 0,1 mm MM_HIMETRIC 0,01 mm MM_LOENGLISH 0.01 in MM_HIENGLISH 0,001 in MM_TWIPS 1/1440 in MM_ISOTROPIC definiowane przez użytkownika (takie same w x i y) MM_ANISOTROPIC definiowane przez użytkownika (różne w x i y) xviewporte xt xviewport = + xwinext ( xwindow xwinorg ) xviewportorg yviewportext yviewport = + ywinext ( ywindow ywinorg ) yviewportorg
Zapamiętywanie parametrów DC CS_OWNDC w stylu klasy okna parametry zapamiętywane dla każdego okna niezależnie wndclass.style =... CS_OWNDC CS_CLASSDC w stylu klasy okna parametry zapamiętywane dla klasy okna wndclass.style =... CS_CLASSDC Zapamiętywanie i odtwarzanie parametrów kontekstu urządzenia idsaved = SaveDC( hdc ); RestoreDC( hdc, idsaved );
Kolory Full color - 24 bits High color - 16 bits 256 colors - 8 bits (index in palette) 16 colors - 4 bits ( 16 fixed colors) Liczba bitów koloru na piksel: ibitspixel=getdevicecaps(hdc, BITSPIXEL); #define RGB(r,g,b)((COLORREF)(((BYTE)(r) \ ((WORD)((BYTE)(g)) << 8)) \ (((DWORD)(BYTE)(b)) << 16))) RGB(255, 0, 0) - Red
Pióra Używanie piór predefiniowanych (ze składnicy Windows) HPEN hpen = GetStockObject( WHITE_PEN ); Tworzenie pióra hpen = CreatePen( ipenstyle, iwidth, crcolor ); LOGPEN logpen; hpen = CreatePenIndirect ( & logpen ); Usuwanie pióra DeleteObject( hpen ); Piór ze składnicy Windows nie należy usuwać. Należy usuwać obiekty, które zostały utworzone. Nie należy usuwać obiektów GDI dopóki są one wybrane w ważnym kontekście.
Pióra Ustawianie aktywnego pióra SelectObject( hdc, hpen ); Jeżeli grubość pióra jest większa od 1 piksel (po narysowaniu), to linie niezależnie od stylu będą liniami ciągłymi. Przerwy pomiędzy liniami są wypełniane kolorem tła (OPAQUE) lub pozostają bez zmian (TRANSPARENT)
Pędzle Używanie pędzli predefiniowanych (ze składnicy Windows) HBRUSH hbrush = GetStockObject( WHITE_BRUSH ); Tworzenie pędzli hbrush=createsolidbrush( crcolor ); hbrush=createhatchbrush( ihatchstyle, crcolor ); LOGBRUSH logbrush; hbrush = CreateBrushIndirect ( & logbrush ); Usuwanie pędzli DeleteObject( hbrush ); Pędzli ze składnicy Windows nie należy usuwać. Należy usuwać obiekty, które zostały utworzone. Nie należy usuwać obiektów GDI dopóki są one wybrane w ważnym kontekście.
Pędzle Ustawianie aktywnego pędzla SelectObject( hdc, hbrush ); Przerwy pomiędzy liniami są wypełniane kolorem tła (OPAQUE) lub pozostają bez zmian (TRANSPARENT)
Rysowanie punktów i linii Punkty SetPixel (hdc, x, y, crcolor) ; crcolor = GetPixel (hdc, x, y) ; Linie proste BOOL LineTo( HDC hdc, int nxend, int nyend ); BOOL Polyline( HDC hdc, CONST POINT * lppt, int cpoints ); Łuki (Arc, ArcTo, AngleArc, PolyDraw, PolyBezier) BOOL PolyBezier( HDC hdc, CONST POINT * lppt, DWORD cpoint );
Funkcje obramowania BOOL Rectangle(hdc, xleft, ytop, xright, ybottom); Rectangle (hdc, 1, 1, 5, 4) ;
Funkcje obramowania BOOL Ellipse(hdc, xleft, ytop, xright, ybottom);
Funkcje obramowania BOOL RoundRect (hdc, xleft, ytop, xright, ybottom, xcornerellipse, ycornerellipse) ;
Funkcje obramowania BOOL Arc(hdc, xleft, ytop, xright, ybottom, xstart, ystart, xend, yend);
Funkcje obramowania BOOL Chord(hdc, xleft, ytop, xright, ybottom, xstart, ystart, xend, yend);
Funkcje obramowania BOOL Pie(hdc, xleft, ytop, xright, ybottom, xstart, ystart, xend, yend);
Tryb wypełniania wielokątów Polygon (hdc, apt, icount); PolyPolygon (hdc, apt, aicounts, ipolycount); SetPolyFillMode (hdc, imode) ; ALTERNATE WINDING
Tryb wypełniania wielokątów 2,0 1,1 ALTERNATE WINDING
Tryby rysowania SetROP2 (hdc, idrawmode); idrawmode = GetROP2 (hdc); Mix mode Description R2_BLACK - always 0 R2_COPYPEN - pen R2_MASKNOTPEN R2_MASKPEN R2_MASKPENNOT R2_MERGENOTPEN R2_MERGEPEN R2_MERGEPENNOT R2_NOP - nothing R2_NOT - not background R2_NOTCOPYPEN R2_NOTMASKPEN R2_NOTMERGEPEN R2_NOTXORPEN R2_WHITE - always 1 R2_XORPEN - xor
Regiony Tworzenie regionu hrgn = CreateRectRgn( xleft, ytop, xright, ybottom ); hrgn = CreateRectRgnIndirect( & rect ); hrgn = CreateEllipticRgn( xleft, ytop, xright, ybottom ); hrgn = CreatePolygonRgn( & point, icount, ipolyfillmode ); Tworzenie regionu złożonego irgntype = CombineRgn( hdstrgn, hsrcrgn1, hsrcrgn2, icomb ); icomb: RGN_AND, RGN_OR, RGN_XOR, RGN_DIFF, RGN_COPY irgntype: NULLREGION, SIMPLEREGION, COMPLEXREGION, ERROR Usuwanie regionu DeleteObject( hrgn );
Odświerzanie regionu InvalidateRgn (hwnd, hrgn, berase) ; Region obcinania SelectObject(hdc, hrgn); SelectClipRgn(hdc, hrgn); Regiony
Fokus Komunikaty związana z klawiaturą odbiera okno posiadające fokus (jest to okno aktywne lub dziecko okna aktywnego) WM_SETFOCUS - wiadomość wysyłana do okna otrzymującego fokus wparam - uchwyt do okna, które utraciło fokus WM_KILLFOCUS - wiadomość wysyłana do okna tracącego fokus wparam - uchwyt do okna, które uzyska fokus
Klawiatura - przyciski Komunikaty informującego wciśnięciu i zwolnieniu przycisku Przyciski systemowe i niesystemowe Niesystemowe Systemowe Wciśnięcie WM_KEYDOWN WM_SYSKEYDOWN Zwolnienie WM_KEYUP WM_SYSKEYUP
Klawiatura - przyciski Parametry wiadomości: wparam - kod wirtualny przycisku (np. VK_LBUTTON, VK_F2, VK_TAB) lparam - dodatkowe informacje
Klawiatura - wprowadzenie znaku Wiadomości informujące o wprowadzeniu znaku (generowane przez funkcję TranslateMesage) while( GetMessage( &msg, NULL, 0, 0 ) { TranstateMessage( &msg ); DispatchMessage( & msg ); } Niesystemowe Systemowe Znaki WM_CHAR WM_SYSCHAR Martwe znaki WM_DEADCHAR WM_SYSDEADCHAR
Klawiatura - wprowadzenie znaku Parametry wiadomości: wparam - kod ANSI znaku lparam - dodatkowe informacje
Stan przycisków Uzyskiwanie informacji o stanie przycisków SHORT GetAsyncKeyState( int vkey ); Uzyskiwanie informacji o stanie przycisków w chwili wystąpienia zdarzenia SHORT GetKeyState( int nvirtkey );
Kolejność komunikatów Wprowadzenie litery a Wiadomość Klawisz lub kod WM_KEYDOWN kod wirtualny klawisza A WM_CHAR kod znaku a WM_KEYUP kod wirtualny klawisza A Wprowadzenie litery A Wiadomość Klawisz lub kod WM_KEYDOWN kod wirtualny klawisza VK_SHIFT WM_KEYDOWN kod wirtualny klawisza `A' WM_CHAR kod znaku `A' WM_KEYUP kod wirtualny klawisza `A' WM_KEYUP kod wirtualny klawisza VK_SHIFT
Kolejność komunikatów Wprowadzenie litery a (autorepetycja) Wiadomość Klawisz lub kod WM_KEYDOWN kod wirtualny klawisza A WM_CHAR kod znaku a... WM_KEYDOWN kod wirtualny klawisza A WM_CHAR kod znaku a WM_KEYUP kod wirtualny klawisza A
Kolejność komunikatów Wprowadzenie litery ą Wiadomość Klawisz lub kod WM_KEYDOWN kod wirtualny klawisza ~ WM_DEADCHAR kod znaku ~ WM_KEYUP kod wirtualny klawisza ~ WM_KEYDOWN kod wirtualny klawisza A WM_CHAR kod znaku ą WM_KEYUP kod wirtualny klawisza A
Funkcje CreateCaret SetCaretPos ShowCaret Karetka HideCaret ukrywa karetkę DestroyCaret niszczy karetkę utworzenie karetki ustawia pozycję karetki w oknie wyświetla karetkę Może istnieć tylko jedna karetka
Karetka ukrywanie przy rysowaniu case WM_SETFOCUS: CreateCaret (hwnd, NULL, cxchar, cychar); SetCaretPos ( x, y ); ShowCaret (hwnd); return 0; case WM_KILLFOCUS: HideCaret ( hwnd ); DestroyCaret(); return 0 ; case WM_LBUTTONDOWN : HideCaret( hwnd ); hdc = GetDC( hwnd );... releasedc( hwnd, hdc ); ShowCaret( hwnd ); return 0;
Mysz (obszar roboczy) Wciśnięcie Zwolnienie Podwójne wciśnięcie Lewy WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK Środkowy WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK Prawy WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK Zmiana położenia kursora myszy WM_MOUSEMOVE Dodanie CS_DBLCLK do stylu klasy okna umożliwia otrzymywanie wiadomości o podwójnym naciśnięciu przycisku myszy
Mysz (obszar roboczy) Parametry wiadomości: wparam - informacja o stanie przycisków LOWORD( lparam ) - współrzędna x kursora HIWORD( lparam ) - współrzędna y kursora Położenie podawane we współrzędnych fizycznych względem obszaru roboczego okna Maski do sprawdzania stanu przycisków MK_LBUTTON, MK_MBUTTON, MK_RBUTTON MK_SHIFT, MK_CONTROL
Mysz (poza obszarem roboczym) Wciśnięcie Zwolnienie Podwójne wciśnięcie Lewy WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK Środkowy WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK Prawy WM_RBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK Zmiana położenia kursora myszy WM_NCMOUSEMOVE Dodanie CS_DBLCLK do stylu klasy okna umożliwia otrzymywanie wiadomości o podwójnym naciśnięciu przycisku myszy
Mysz (poza obszarem roboczym) Parametry wiadomości: wparam - identyfikator obszaru okna LOWORD( lparam ) - współrzędna x kursora HIWORD( lparam ) - współrzędna y kursora Położenie podawane we współrzędnych fizycznych względem całego ekranu Identyfikatory obszarów HTCAPTION - pasek tytułu HTSYSMENU - menu systemowe HTCLOSE - przycisk zamykający okno
Komunikat testu na trafienie okna Wiadomość WM_NCHITTEST poprzedza wszystkie inne wiadomości związane z myszą Parametry: wparam - nie wykorzystywany LOWORD( lparam ) - współrzędna x kursora HIWORD( lparam ) - współrzędna y kursora Położenie podawane we współrzędnych fizycznych względem całego ekranu
Komunikat testu na trafienie okna DefWindowProc przetwarza wiadomość WM_NCHITTEST i zwraca identyfikator obszaru okna Na podstawie informacji zwróconej przez procedurę obsługi zdarzeń okna system wstawia do kolejki odpowiednią wiadomość Identyfikatory obszarów HTCAPTION HTCLIENT HTNOWHERE HTTRANSPARENT pasek tytułu obszar roboczy żadne okno okno przykryte przez inne
Funkcje związane z myszą Sprawdzanie obecności i liczby przycisków myszy fmouse = GetSystemMetrics( SM_MOUSEPRESENT ); cbutton = GetSystemMetrics( SM_CMOUSEBUTTONS ); Ukrywanie i pokazywanie kursora ShowCursor( TRUE ); ShowCursor( FALSE ); Pobieranie i ustawianie pozycji kursora GetCursorPos( & pt ); SetCursorPos( x, y ); Przechwytywanie myszy SetCapture( hwnd ); ReleaseCapture();
Zegar Zegar to urządzenie wejściowe generujące wiadomość WM_TIMER z zadaną częstotliwością Parametry wparam - identyfikator zegara lparam - wskazanie na funkcję obsługi Czas podaje się w ms ale maksymalna rozdzielczość to: dla Win 98 55 ms, dla Win NT 10 ms Wiadomość WM_TIMER jest kolejkowana i sklejana (w kolejce może być tylko jedna taka wiadomość dla jednego zegara)
Zegar Obsługa przez procedurę obsługi zdarzeń okna SetTimer( hwnd, itimerid, imsecinterval, NULL ); case WM_TIMER :... break; Obsługa przez funkcję call-back VOID CALLBACK TimerProc( HWND hwnd, UINT message, {... } UINT itimerid, DWORD dwtime ) SetTimer( hwnd, itimerid, imsecinterval, TimerProc ); Obsługa przez funkcję call-back (hwnd = NULL) VOID CALLBACK TimerProc( HWND hwnd, UINT message, UINT itimerid, DWORD dwtime ) {... } itimerid = SetTimer( NULL, 0, imsecinterval, TimerProc ); Usuwanie zegara KillTimer( hwnd, itimerid );
Kategorie wiadomości Wiadomości kolejkowane Przykłady wiadomości WM_LBUTTONDOWN, WM_PAINT, WM_TIMER Wysyłanie wiadomości LRESULT PostMessage(HWND hwnd,uint msg,wparam wpar,lparam lpar); Wiadomości niekolejkowane Przykład wiadomości WM_SETFOCUS, WM_KILLFOCUS, WM_ACTIVATE Wysyłanie wiadomości LRESULT SendMessage(HWND hwnd,uint Msg,WPARAM wpar, LPARAM lpar);
Wiadomości kolejkowane Wiadomości są wstawiane na koniec kolejki i pobierane z początku FIFO (wyjątkiem są WM_PAINT i WM_TIMER) Wysłanie powoduje wstawienie do kolejki związanej z wątkiem, w którym zostało utworzone okno do którego adresowana jest wiadomość
Wiadomości kolejkowane Thread A Thread B 1 Thread message queue PostMessage( ); 2 while( GetMessage( ) ) { DispatchMessage( ); } WndProc
Wiadomości niekolejkowane Wysłanie powoduje bezpośrednie wywołanie procedury obsługi zdarzeń okna (w kontekście wątku, w którym to okno zostało utworzone) Wysyłający czeka na zakończenie obsługi wiadomości Odbierający może potwierdzić obsłużenie wiadomości przed zakończeniem procedury obsługi zdarzeń okna BOOL ReplyMessage( LRESULT lresult ); Wątek odbierający musi wywoływać funkcję pobierania wiadomości
Wiadomości niekolejkowane Thread A Thread A Thread B 1 1 1 SendMessage( ); 3 SendMessage( ); 3 GetMessage( ); 3 WndProc 2 WndProc 2 2
Wiadomości niekolejkowane Thread A 1 SendMessage( ); 3 Thread B 1 GetMessage( ); 4 WndProc 2 2 ReplayMessage( ); 3
Adresat wiadomości Parametr hwnd może mieć wartość HWND_BROADCAST wysłanie wiadomości do wszystkich okien typu top level NULL (tylko PostMessage) wysłanie wiadomości do wątku Wysyłanie wiadomości do wątku BOOL PostThreadMessage( DWORD idthread,uint Msg,WPARAM wpar, LPARAM lpar);
Rejestrowanie wiadomości Rejestrujemy wiadomość podając ciąg znaków i otrzymujemy identyfikator UINT RegisterWindowMessage( LPCTSTR lpstring ); Rejestracja nazw wiadomości globalna dla całego systemu Unikamy konfliktów identyfikatorów wiadomości
Zakresy identyfikatora wiadomości Zakres 0 - (WM_USER 1) WM_USER - 0x7FFF WM_APP - 0xBFFF 0xC000-0xFFFF > 0xFFFF Opis zarezerwowane do użytku prywatnego zarezerwowane wiadomości zarejestrowane zarezerwowane
Informacje o oknie Pobieranie informacji o oknie LONG GetWindowLong( HWND hwnd, int nindex ); Ustawianie informacji o oknie LONG SetWindowLong( HWND hwnd, int nindex, LONG dwnewlong ); Parametr nindex zawiera indeks wartości z obszaru danych alokowanych dla okna struct WNDCLASS { UINT style; WNDPROC lpfnwndproc; int cbclsextra; int cbwndextra;... };
Informacje o oknie Inne wartości parametru nindeks GWL_EXSTYLE rozszerzony styl okna GWL_STYLE styl okna GWL_WNDPROC adres procedury obsługi zdarzeń GWL_HINSTANCE uchwyt do instancji aplikacji GWL_ID identyfikator okna GWL_USERDATA wartość do wykorzystania przez aplikację
Zakładanie podklasy okna Pobranie adresu procedury obsługi zdarzeń LONG GetWindowLong( HWND hwnd, int nindex ); nindex = GWL_WNDPROC Ustawienie adresu procedury zdarzeń LONG SetWindowLong( HWND hwnd, int nindex, LONG dwnewlong ); nindex = GWL_WNDPROC Zamieniając procedurę obsługi zdarzeń możemy zmienić zachowanie okna Nowa procedura obsługi może dla zdarzeń przez nią nie obsługiwanych wywołać starą procedurę obsługi zdarzeń
Kontrolki okna potomnego Każde dziecko posiada unikatowy identyfikator (w obrębie swojego rodzeństwa) Pobieranie uchwytu do okna rodzica HWND GetParent( HWND hwnd ); Uzyskiwanie uchwytu do okna na podstawie identyfikatora HWND GetDlgItem( HWND hdlg, int niddlgitem ); Uzyskiwanie identyfikatora na podstawie uchwytu do okna id = GetWindowLong( hwndchild, GWL_ID ); int GetDlgCtrlID( HWND hwndctl );
Kontrolki okna potomnego W systemie są zdefiniowane klasy okien: button, static, scrollbar, edit, listbox, combobox Przy zmianie swojego stanu kontrolki wysyłają do okna rodzica wiadomość WM_COMMAND HIWORD( wparam ) - kod powiadomienia LOWORD( wparam ) - identyfikator kontrolki lparam - uchwyt do kontrolki (okna)
Klasa przycisków BS_PUSHBUTTON BS_DEFPUSHBUTTON BS_CHECKBOX BS_AUTOCHECKBOX BS_RADIOBUTTON BS_3STATE BS_AUTO3STATE BS_GROUPBOX BS_AUTORADIOBUTTON BS_OWNERDRAW BS_LEFTTEXT przycisk naciskany przycisk naciskany pole wyboru pole wyboru przycisk opcji pole wyboru (3 stany) pole wyboru (3 stany) pole grupy przycisk opcji przycisk rysowane przez program wyrównanie tekstu do lewej strony
Komunikacja z oknem nadrzędnym Przy zmianie stanu przycisk wysyła do swojego rodzica wiadomość WM_COMMAND z kodem powiadomienia BN_CLICKED naciśnięcie przycisku BN_DBLCLK podwójne naciśnięcie przycisku myszy BN_SETFOCUS uzyskanie fokusu BN_KILLFOCUS utrata fokusu
Komunikacja z oknem nadrzędnym Jeśli do stylu przycisku dodano BS_NOTIFY to będzie on informował okno nadrzędne o: uzyskaniu lub utracie fokusu podwójnym naciśnięciu przycisku myszy Przyciski BS_RADIOBUTTON, BS_AUTORADIOBUTTON, BS_OWNERDRAW zawsze informują okno nadrzędne o podwójnym naciśnięciu przycisku myszy Przyciski rysowane przez program wysyłają wiadomość WM_DRAWITEM gdy muszą być odświeżone lub gdy zmieni się ich stan
Komunikacja z przyciskami Okno nadrzędne może się komunikować z kontrolką za pomocą szeregu komunikatów WM_XXX Komunikaty charakterystyczne dla przycisków BM_GETCHECK BM_SETCHECK BM_GETSTATE BM_SETSTATE BM_SETSTYLE BM_CLICK BM_GETIMAGE BM_SETIMAGE pobranie stanu (pole wyboru, przycisk opcji) ustawienie stanu (pole wyboru, przycisk opcji) pobranie stanu (zwykły przycisk) ustawienie stanu (zwykły przycisk) ustawienie stylu przycisku wciśnięcie przycisku pobranie uchwytu do bitmapy lub ikony ustawienie uchwytu do bitmapy lub ikony
Przyciski widoczne i dostępne Okno potomne może odbierać komunikaty generowane przez mysz i klawiaturę jeśli jest widoczne i dostępne Widoczność okna BOOL ShowWindow( HWND hwnd, int ncmdshow ); BOOL IsWindowVisible( HWND hwnd ); Dostępność okna SW_HIDE, SW_SHOWNORMAL BOOL EnableWindow( HWND hwnd, BOOL benable ); BOOL IsWindowEnabled( HWND hwnd );
Zasoby Zasoby są definiowane w tekstowym pliku - skrypcie zasobów (plik *.rc) W trakcie tworzenia programu zasoby takie jak ikony, kursory, zasoby użytkownika, bitmapy są przechowywane w oddzielnych plikach binarnych Po utworzeniu programu zasoby są dołączane do pliku wykonywalnego
Zasoby
Przykładowe zasoby: ikony kursory ciągi znakowe zasoby użytkownika skróty klawiatury okna dialogowe bitmapy Zasoby
Ikony Używane Dwa rozmiary ikon: duża 32 x 32 piksele mała 16 x 16 pikseli Definicja ikony w pliku zasobów #define IDI_ICON 101 IDI_ICON ICON DISCARDABLE "icondemo.ico" MYICON ICON DISCARDABLE "icondemo.ico" Pobieranie ikony hicon = LoadIcon( hinstance, MAKEINTRESOURCE (IDI_ICON) ); hicon = LoadIcon ( hinstance, MYICON ) ; Wyświetlanie ikony BOOL DrawIcon( HDC hdc, int X, int Y, HICON hicon );
Ciągi znaków Definicja w pliku zasobów STRINGTABLE DISCARDABLE BEGIN IDS_STRING1, "character string 1" IDS_STRING2, "character string 2" END Każdy tekst musi być jednoznacznie identyfikowany przez stałą W tekstach można używać znaków \t i \n Pobieranie tekstu int LoadString( HINSTANCE hinstance, UINT uid LPTSTR lpbuffer, int nbuffermax );
Zasoby użytkownika Nazwa typu zasobu jest definiowana przez użytkownika Definicja w pliku zasobów IDR_BINTYPE1 BINTYPE BINDATA.BIN Pobieranie uchwytu do zasobu użytkownika hresource = LoadResource (hinstance, FindResource( hinstance, "BINTYPE", MAKEINTRESOURCE (IDR_BINTYPE1) ) ); Dostęp do zasobu pdata = LockResource( hresource ); FreeResource( hresource );
Szablon okna dialogowego Utworzenie zasobu okno dialogowe Wstawienie kontrolek Określenie kolejności kontrolek
Szablon okna dialogowego Ustawienie właściwości kontrolek WS_TABSTOP - kontrolka może otrzymać fokus WS_GROUP - rozpoczyna nową grupę przycisków wyboru
Okna dialogowe Typy okien dialogowych modalne okno dialogowe musi zostać zamknięte zanim użytkownik będzie pracował z innymi oknami aplikacji przykład otwarcie pliku nie modalne gdy okno dialogowe jest otwarte użytkownik może pracować z innymi oknami aplikacji przykład znajdź i zamień
Modalne okna dialogowe BOOL CALLBACK AboutDlgProc (HWND hdlg, UINT message, WPARAM wparam, LPARAM lparam) { } switch (message) { case WM_INITDIALOG : return TRUE ; case WM_COMMAND : } switch (LOWORD (wparam)) { case IDOK : case IDCANCEL : EndDialog (hdlg, 0) ; return TRUE ; } break ; return FALSE ;
Modalne okna dialogowe Wyświetlanie okna dialogowego case WM_COMMAND : switch (LOWORD (wparam)) { case IDM_APP_ABOUT : DialogBox(hInstance,"AboutBox", hwnd,aboutdlgproc); break ; } return 0 ;
Nie modalne okna dialogowe Tworzenie niemodalnego okna dialogowego hdlgmodeless = CreateDialog (hinstance, sztemplate, hwndparent, DialogProc); hdlgmodeless = CreateDialog (... ) ; ShowWindow( hdlgmodeless, SW_SHOW ) ; Zamykanie niemodalnego okna dialogowego case WM_CLOSE : DestroyWindow (hdlg) ; hdlgmodeless = NULL ; break ;
Nie modalne okna dialogowe Obsługa zdarzeń while( GetMessage (&msg, NULL, 0, 0) ) { } if (hdlgmodeless == 0!IsDialogMessage (hdlgmodeless, &msg)) { } TranslateMessage (&msg) ; DispatchMessage (&msg) ;
The Common Dialog Boxes Rodzaje okien Common Dialog ChooseColor ChooseFont FindText GetOpenFileName GetSaveFileName PageSetupDlg PrintDlg ReplaceText
The Common Dialog Boxes #include <commdlg.h> int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hprevinstance, PSTR szcmdline, int icmdshow) { static CHOOSECOLOR cc; static COLORREF crcustcolors[16]; cc.lstructsize = sizeof (CHOOSECOLOR); cc.hwndowner = NULL; cc.hinstance = NULL; cc.rgbresult = RGB (0x80, 0x80, 0x80); cc.lpcustcolors = crcustcolors; cc.flags = CC_RGBINIT CC_FULLOPEN; cc.lcustdata = 0; cc.lpfnhook = NULL; cc.lptemplatename = NULL; return ChooseColor (&cc); }
Biblioteki dynamiczne Mogą być używane przez kilka aplikacji jednocześnie (wspólny kod) Używją stosu wątku wywołującego funkcję i przestrzeni adresowej wołającego procesu Aplikacja 1 LIB Aplikacja 1 DLL Aplikacja 2 LIB Aplikacja 2
Biblioteki dynamiczne Ładowanie biblioteki dynamicznej w momencie uruchomienia programu (z programem został skonsolidowany plik *.lib dla tej biblioteki dynamicznej, zawiera on nagłówki eksportowanych funkcji) w trakcie działania programu HINSTANCE LoadLibrary( LPCTSTR lplibfilename ); Zwalnianie biblioteki dynamicznej BOOL FreeLibrary( HMODULE hlibmodule );
Biblioteki dynamiczne Funkcje eksportowane (widoczne na zewnątrz biblioteki) wymienia się w dyrektywie EXPORT w pliku.def plik.c short FAR PASCAL suma( short a, short b ); plik.def EXPORT suma
Punkt wejścia i wyjścia biblioteki Funkcja wywoływana w momencie podłączenia/odłączenia biblioteki BOOL DllEntryPoint( HINSTANCE hinstdll, DWORD fdwreason, LPVOID lpvres ); hinstdll - uchwyt do instancji biblioteki fdwreason - powód wywołania funkcji DLL_PROCESS_ATTACH - dołączenie biblioteki do przestrzeni adresowej procesu DLL_THREAD_ATTACH - gdy proces tworzy nowy wątek (nie woła się dla wątku dla którego było wywołanie DLL_PROCES_ATTACH) DLL_THREAD_DETACH - gdy wątek się zakończy (nie woła się dla wątku dla którego DLL_PROCES_DETACH) DLL_PROCESS_DETACH odłączenie biblioteki do przestrzenia adresowej procesu lpvres - parametr zarezerwowany
Biblioteki dynamiczne zalety/wady Zalety Podział programu na moduły, które mogą być wymieniane niezależnie i wykorzystywane przez różne aplikacje Mniejsza zajętość pamięci operacyjnej i dyskowej Możliwy do realizacji mechanizm wtyczek Wady Biblioteka musi być w systemie Problemy z różnymi wersjami tej samej biblioteki