Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
Grafika i komunikacja człowieka z komputerem
API Windows – interfejs windows
2
Wstęp – programowanie a Windows
Istnieje wiele języków programowania (i środowisk) wraz z bibliotekami klas ułatwiających i przyspieszających tworzenie aplikacji dla Windows. W terminologii inżynierii oprogramowania pojęcie „biblioteki klas” lub „systemu szkieletowego” (ang. resource framework) oznacza system obejmujący strukturę, interfejs, a często również „prefabrykowane” elementy, które projektant może wykorzystać do budowy aplikacji.
3
Wstęp – programowanie a Windows
Spośród bibliotek (np.. W środowisku Borland) znajduje się biblioteka komponentów VCL (Visual Component Library. Biblioteka VCL jest kluczowym elementem opracowanych przez firmę Borland narzędzi do szybkiego tworzenia aplikacji (RAD) – Delphi i C++Buildera. Poprzedniczką VCL była biblioteka OWL (Object Windows Library), przeznaczona dla wcześniejszych wersji systemu Windows.
4
Wstęp – programowanie a Windows
Projektując aplikację przeznaczoną dla Windows, warto w większości przypadków przynajmniej rozważyć możliwość użycia oprogramowania pośredniego, „otaczającego” interfejs Win32. Dodatkowo interfejs udostępniany przez biblioteki klas i oprogramowanie pośrednie pozwala na obiektowe traktowanie wywołań Win32 API, którego natura jest bardziej strukturalna. Mimo tych niewątpliwych zalet, w niektórych przypadkach dokładna znajomość „podstaw”, czyli funkcji Win32, okazuje się niezbędna – nie mówiąc już o konieczności ich bezpośredniego (choćby sporadycznego) użycia. Jednym z powodów takiego stanu rzeczy jest fakt, iż bezpośrednie odwołania do funkcji Win32 są szybsze i mniej „pamięciożerne” niż analogiczne operacje realizowane z użyciem oprogramowania pośredniego. Warto też zauważyć, iż programiści, wykorzystujący bezpośrednio funkcje API, na ogół lepiej rozumieją mechanizmy współdziałania aplikacji z systemem operacyjnym, innymi aplikacjami i sprzętem.
5
Wstęp API (ang. Application Programming Interface), interfejs programowania aplikacji, interfejs programu użytkownika – specyfikacja procedur, funkcji lub interfejsów umożliwiających komunikację z biblioteką, systemem operacyjnym lub innym systemem zewnętrznym w stosunku do aplikacji korzystającej z API. Dobry interfejs API tworzony jest nie tylko z myślą o ułatwieniu procesu tworzenia oprogramowania programistom poprzez dobrą dokumentację oraz ukrycie szczegółów implementacyjnych, ale także z myślą o użytkowniku, dzięki zagwarantowaniu podobnego interfejsu wszystkim aplikacjom opartym o dany API. Do najpopularniejszych API dla komputerów osobistych należy opracowany i wprowadzony w lipcu 1993 przez firmę Microsoft interfejs Win32 API, obejmujący zbiór funkcji używanych w systemie Windows
6
Windows API Windows API (zwane też WinAPI) – interfejs programistyczny systemu Windows; zbiór funkcji, stałych i zmiennych potrzebnych i umożliwiających działanie programu w systemie operacyjnym Windows. Zbiór ten jest bardzo obszerny i zawiera funkcje do tworzenia okien programów, elementów interfejsu użytkownika, obsługi zdarzeń oraz umożliwiające dostęp do innych aplikacji, funkcji sieciowych czy sprzętu w komputerze. Mianem WinAPI określamy standardowe funkcje przychodzące wraz z bibliotekami DLL (w 16-bitowych wersjach z rozszerzeniem .exe) dostarczanymi z systemem - np. kernel32.dll, user32.dll, gdi32.dll czy wsock32.dll, znajdujące się w podkatalogu System w głównym katalogu Windows. Liczba bibliotek rośnie wraz z każdą nową wersją Windows. Powoduje to także problemy z uruchomieniem aplikacji napisanej w starej wersji systemu pod kontrolą nowej. Obecnie znakomita większość kompilatorów posiada odpowiednie pliki nagłówkowe umożliwiające korzystanie z WinAPI.
7
API firmy Microsoft Windows APIs: Windows API : Win16 • Win32 • Win32s • Win32 dla 64-bit Windows Grafika: DirectX • Direct3D • DirectDraw • Graphics Device Interface (GDI) • GDI+ • Desktop Window Manager • ClearType • Windows Presentation Foundation • Windows Image Acquisition Dźwięk: DirectSound • DirectMusic • XACT Multimedia: DirectShow • Media Foundation • Windows Media Dostęp danych: Microsoft Data Access Components • ActiveX Data Objects • OLE DB • ADO.NET • Entity Framework Komunikacja: Winsock • Remote Application Programming Interface • Telephony Application Programming Interface Zarządzanie: Windows Management Instrumentation Model komponentu: ActiveX • Component Object Model (COM) • COM+ • Distributed Component Object Model • Dynamic Data Exchange • Object Linking and Embedding • .NET Bezpieczeństwo i dyskrecja: Cryptographic Application Programming Interface • Windows CardSpace .NET: .NET Framework • ASP.NET • ADO.NET • .NET Remoting • Silverlight • Windows Communication Foundation • Windows Presentation Foundation • Windows Workflow Foundation • Windows CardSpace • Managed DirectX
8
Funkcje interfejsu Win32
zarządzanie aplikacjami i oknami (windows management); usługi systemowe (system services); obsługa interfejsu urządzeń graficznych (GDI, Graphics Device Interface); usługi multimedialne (multimedia services); standardowe elementy interfejsu użytkownika (common controls and dialogs); funkcje powłoki systemu (shell features); obsługa ustawień regionalnych (international features); usługi sieciowe (network services).
9
Zarządzanie oknami Do tworzenia i zarządzania aplikacjami uruchamianymi w systemie Windows służą funkcje zawarte w bibliotece obsługującej interfejs użytkownika (user32.dll). Realizowane przez nią usługi obejmują: zarządzanie oknami, menu, oknami dialogowymi, okienkami komunikatów, komunikację z klawiaturą i myszą oraz innymi elementami interfejsu użytkownika. Okno jest swoistym punktem styku, przez który użytkownik porozumiewa się z aplikacją.
10
Najczęściej używane funkcje zarządzania oknami
CascadeWindows() Układa dane okna (lub okna potomne danego okna) kaskadowo. CloseWindow() Ukrywa (nie likwiduje) dane okno. CreateWindow() Tworzy okno wyposażone w pasek tytułu (overlapped), wyskakujące (pop-up) lub potomne (child). DestroyWindow() Likwiduje okno; jej wywołanie powoduje przesłanie do okna systemowego komunikatu WM_DESTROY. EnableWindow() Blokuje lub odblokowuje odbieranie przez okno komunikatów wysyłanych przez klawiaturę i mysz. EnumWindows() Identyfikuje wszystkie okna najwyższego poziomu (ang. top level window; są to okna, których rodzicem jest pulpit Windows), przekazując kolejno ich uchwyty do zdefiniowanej przez użytkownika funkcji zwrotnej. EnumWindowsProc() Odbiera uchwyty okien przekazywane przez EnumWindows() w celu dalszego przetwarzania (funkcja zwrotna definiowana przez programistę). FindWindow() Zwraca uchwyt okna najwyższego poziomu identyfikowanego nazwą klasy i zawartością paska tytułu okna. FindWindowEx() Zwraca uchwyt okna identyfikowanego nazwą klasy oraz zawartością paska tytułu; działa podobnie do FindWindow(), jednak umożliwia również zlokalizowanie okna potomnego (typu child). GetWindowRect() Zwraca współrzędne ekranowe prostokąta, zawierającego dane okno. GetWindowText() Zwraca tekst zawarty w oknie (zwykle w pasku tytułu). MoveWindow() Przesuwa okno lub zmienia jego rozmiary. SetWindowText() Zmienia tekst zawarty w oknie (zwykle w pasku tytułu). ShowWindow() Modyfikuje stan widoczności danego okna. Możliwości funkcji ShowWindow() obejmują: maksymalizację, minimalizację, ukrywanie, przywracanie rozmiarów oraz uaktywnianie okien. TileWindows() Układa dane okna (lub okna potomne danego okna) obok siebie. WinMain() Definiuje punkt wejścia do aplikacji Win32; wywoływana przez system operacyjny.
11
Usługi systemowe Funkcje określane ogólnie mianem usług systemowych umożliwiają aplikacji zarządzanie i nadzorowanie stanu zasobów, dostęp do plików, folderów oraz urządzeń wejścia-wyjścia, a także rejestrację i obsługę błędów oraz wyjątków. Usługi systemowe obejmują także funkcje wykorzystywane przy tworzeniu programów innych niż „okienkowe”, np. tekstowych aplikacji Win32, usług i sterowników. Większość funkcji systemowych niskiego poziomu (w tym funkcje przeznaczone do obsługi plików, zarządzania pamięcią i innymi zasobami oraz obsługi pracy wielozadaniowej i wielowątkowej) zawarta jest w bibliotece implementującej jądro systemu (kernel.dll). Funkcje jądra wykorzystywane są przez wszystkie programy przeznaczone dla Windows. Przykładowo, jeśli dana aplikacja wymaga dodatkowej pamięci (czy to podczas uruchamiania, czy w trakcie pracy), kieruje odpowiednie żądanie właśnie do jądra systemu. Podstawowe grupy i elementy usług systemowych. Omawianie tych funkcji przekracza zakres tematyczny wykładu.
12
Przykładowe funkcje systemowe
Atomy- Obsługa wymiany między aplikacjami łańcuchów tekstowych identyfikowanych liczbami całkowitymi Usługi komunikacyjne - Komunikacja z urządzeniami peryferyjnymi (porty szeregowe, równoległe i modemy) Obsługa konsoli - Obsługa wejścia-wyjścia w trybie tekstowym (dla aplikacji nie korzystających z graficznego interfejsu użytkownika) Usługi uruchomieniowe - Sterowany zdarzeniami system uruchomieniowy (debugger) Wejście-wyjście - Komunikacja pomiędzy aplikacją a sterownikami urządzeń Dynamiczna wymiana danych (DDE, Dynamic Data Exchange) - Wymiana danych pomiędzy aplikacjami. Funkcje DDE są obsługiwane przez bibliotekę interfejsu użytkownika (user32.dll) oraz bibliotekę DDEML (Dynamic Data Exchange Management Library)
13
Interfejs GDI Interfejs urządzeń graficznych GDI (Graphics Device Interface) zapewnia możliwość rysowania i drukowania zawartości okien. Obsługujące go funkcje, zawarte w bibliotece gdi32.dll, umożliwiają m.in. kreślenie linii, wyprowadzanie tekstu, manipulowanie czcionkami oraz zarządzanie kolorami. Jednym z podstawowych elementów GDI jest tzw. kontekst urządzenia (ang. device context, DC). Reprezentuje on strukturę danych, obejmującą zestaw obiektów graficznych, ich atrybutów oraz trybów wyprowadzania. Tworzenie kontekstów realizują funkcje GetDC() i CreateDC(); oprócz nich biblioteka GDI definiuje wiele innych funkcji stosowanych intensywnie do obsługi kontekstów urządzeń.
14
Obiekty GDI Mapa bitowa (bitmap) - Kopiowanie i przemieszczanie fragmentów zawartości ekranu Pędzel (brush) - Malowanie i wypełnianie obszarów wielokątów, elips i ścieżek Czcionka (font) - Określanie kształtu, rozmiaru i atrybutów znaków wyprowadzanego tekstu Paleta (palette) - Ustalanie zestawu używanych kolorów Pióro (pen) - Kreślenie linii Obszar (region) - Obcinanie, wyznaczanie kształtu i inne operacje związane z obszarem rysowania
15
Obsługa multimediów Elementy prezentacji multimedialnych, jak np. dźwięk i sekwencje wideo, można znaleźć w coraz większej liczbie nowoczesnych aplikacji, co bez wątpienia poszerza możliwości komunikowania się z użytkownikiem. Rozszerzenia multimedialne opracowane przez Microsoft dla systemu Windows obejmują m.in.: bibliotekę Multimedia System Library (mmsystem.dll), bibliotekę obsługi zapisów wideo Microsoft Video for Windows (msvfw32.dll) oraz bibliotekę obsługi kompresji dźwięku Microsoft Audio Compression Manager Library (msacm32.dll). Można powiedzieć, że współczesne odmiany Windows są z praktycznego punktu widzenia „urządzeniami multimedialnymi” tak samo, jak np. telewizor czy wieża stereo (właściwie należałoby powiedzieć „kombajnami”, gdyż Windows łączy w sobie funkcje wszystkich typowych urządzeń do odtwarzania dźwięku i obrazu – przyp. tłum.). System Windows obsługuje większość urządzeń i formatów zapisu danych multimedialnych, w tym urządzenia MIDI, spróbkowane zapisy dźwięku oraz pliki wideo. Większość podstawowych funkcji multimedialnych skupiono w trzech bibliotekach: mmsystem.dll, msvfw32.dll oraz msacm32.dll, zaś sprawną i stosunkowo prostą obsługę gier oraz odtwarzania dźwięku i obrazu zapewnia multimedialny interfejs programowy DirectX. W tym rozdziale skupimy się na funkcjach udostępnianych przez wspomniane wyżej „systemowe” biblioteki dynamiczne; odpowiadające im pliki nagłówkowe noszą nazwy digitalv.h, mciavi.h, msystem.h, msacm.h, vcr.h i vfw.h.
16
Usługi multimedialne Menedżer kompresji dźwięku (Audio Compression Manager, ACM) - Udostępnia funkcje systemowe umożliwiające kompresję, dekompresję, filtrowanie i konwersję danych dźwiękowych (msacm32.dll). Miksery dźwiękowe - Umożliwiają sterowanie przepływem danych dźwiękowych z urządzeń rejestrujących i do urządzeń odtwarzających, a także regulację głośności i innych efektów dźwiękowych (mmsystem.dll). Funkcje AVICap - Umożliwiają rejestrację sekwencji wideo; obsługują interfejsy urządzeń rejestrujących obrazy oraz dźwięk w postaci spróbkowanej; zarządzają zapisywaniem strumieni danych wideo na dysku (msvfw32.dll). Funkcje i makrodefinicje AVIFile - Obsługują dostęp do plików w formacie AVI (Audio-Video Interleaved) (msvfw32.dll). Funkcje DrawDib - Umożliwiają szybkie wyświetlanie map bitowych typu DIB, (Device Independent Bitmap) z pominięciem funkcji GDI (msvfw32.dll). Obsługa joysticków - Zapewnia obsługę joysticków i innych dodatkowych urządzeń wejściowych, wykorzystujących bezwzględne układy współrzędnych, jak np. pióra świetlne, ekrany i tabliczki dotykowe (mmsystem.dll). Klasa MCIWnd - Definiuje klasę okna przeznaczoną do sterowania urządzeniami multimedialnymi; umożliwia łatwe dołączanie do aplikacji funkcji zapisu i odtwarzania danych multimedialnych (msvfw32.dll). I wiele innych
17
Standardowe elementy interfejsu użytkownika
System Windows udostępnia programistom kolekcję standardowych elementów sterujących, zawartą w bibliotece comctl32.dll oraz comdlg32.dll. Druga biblioteka zawiera z kolei zestaw standardowych okien dialogowych. Wykorzystanie obu bibliotek ułatwia projektantom aplikacji szybkie tworzenie interfejsu użytkownika, zwalniając ich z konieczności żmudnego tworzenia odpowiednich elementów we własnym zakresie. Co prawda C++Builder udostępnia większość standardowych elementów interfejsu użytkownika w postaci odpowiednich komponentów VCL, jednak znajomość zestawu elementów sterujących i okien dialogowych udostępnianych poprzez interfejs Win32 jest dla programisty sprawą dość istotną. Oficjalna liczba elementów zawartych w wersji 4.71 biblioteki comctl32.dll (udostępnionej wraz z przeglądarką Internet Explorer 4.0) wynosi 22. Szczegółowe informacje na ich temat można uzyskać, np. analizując dostarczany w pakiecie C++Builder plik nagłówkowy commctrl.h.
18
Standardowe elementy interfejsu
Okienko animacji (Animation Control) - Implementuje prosty odtwarzacz plików AVI (bez możliwości odtwarzania dźwięku). Rozszerzona lista rozwijana ComboBoxEx - Implementuje listę rozwijaną, obsługującą elementy graficzne (ikony). Selektor daty i czasu (Date/Time Picker) - Wyświetla okno służące do wyświetlania i wprowadzania daty i czasu. Lista obsługująca przeciąganie (Drag List Box) - Implementuje listę, umożliwiającą zmianę kolejności elementów przez przeciąganie. Płaski pasek przewijania (Flat Scroll Bar) - Implementuje dwuwymiarowy („płaski”) pasek przewijania (tworzony poprzez wywołanie funkcji InitializeFlatSB()). Nagłówek kolumny (Header Control) - Umożliwia tworzenie nagłówków kolumn tekstowych lub liczbowych, pozwalających na zmianę szerokości. Klawisz szybkiego dostępu (Hotkey Control) -Obsługuje definiowanie klawiszy i kombinacji klawiszy szybkiego dostępu (skrótu).
19
Standardowe elementy interfejsu
Widok listy (List View) - Umożliwia prezentowanie zawartości listy w postaci dużych lub małych ikon, listy lub widoku szczegółowego (ang. report view). Kalendarz miesięczny (Monthly Calendar) - Implementuje graficzną reprezentację kalendarza, umożliwiającą przeglądanie i wybieranie dat. Strona przewijana (Page Scroller) - Umożliwia utworzenie przewijalnego okna, zawierającego okno potomne (np. inny element interfejsu), którego rozmiary nie pozwalają wyświetlić go w całości. Wskaźnik postępu (Progress Bar) - Implementuje pasek, informujący o stanie zaawansowania operacji. Pasek statusu (Status Bar) Umożliwia wyświetlanie tekstowych i graficznych informacji o stanie aplikacji (przeważnie ma postać paska „przyklejonego” do krawędzi okna). Pasek narzędzi (Toolbar) Pozwala na grupowanie przycisków w obrębie pojedynczego panelu. Etykietka (Tooltip Control) Umożliwia wyświetlanie „dymków” z podpowiedziami po wskazaniu danego komponentu myszą. Suwak (Trackbar) Implementuje wyskalowany suwak, pozwalający na zmianę wartości całkowitoliczbowej w zadanym zakresie.
20
Standardowe elementy interfejsu użytkownika
Oprócz standardowych elementów sterujących (kontrolek) Microsoft udostępnia programistom także kilka powszechnie używanych okien dialogowych. Obecnie jest ich osiem.
21
Standardowe okna dialogowe w API Win32
Wybór koloru - ChooseColor() Wybór czcionki - ChooseFont() Wyszukiwanie tekstu - FindText Otwarcie pliku - GetOpenFileName() Zapisanie pliku - GetSaveFileName() Ustawienia wydruku - PageSetupDlg() Drukowanie - PrintDlg() Wyszukiwanie i zamiana tekstu - ReplaceText()
22
Elementy i funkcje powłoki systemu
Termin „powłoka” (ang. shell) oznacza w systemie Windows program umożliwiający użytkownikowi grupowanie, uruchamianie i zarządzanie innymi programami. Funkcje udostępniane przez powłokę obejmują m.in.: obsługę mechanizmu „przesuń i upuść”, zarządzanie skojarzeniami (ang. file associations), pozwalającymi automatycznie wyszukiwać i uruchamiać aplikacje, pobieranie ikon z plików itd. Charakterystyka funkcji przekracza zakres wykładu
23
Obsługa ustawień regionalnych
Interfejs Win32 zawiera elementy usprawniające projektowanie aplikacji przeznaczonych dla środowisk innych niż anglojęzyczne. Do reprezentowania znaków diakrytycznych oraz symboli (np. technicznych) służy w Windows alfabet Unicode, w którym znaki reprezentowane są w postaci 16-bitowej. Lokalizację programu (tj. tworzenie wersji przeznaczonej na rynek danego kraju) ułatwiają także funkcje obsługi języków (National Language Support, NLS). Charakterystyka funkcji przekracza zakres wykładu
24
Usługi sieciowe Funkcje należące do tej grupy umożliwiają wymianę danych pomiędzy programami oraz komunikację pomiędzy komputerami połączonymi za pomocą sieci. Służą one do tworzenia i zarządzania odwołaniami do współużytkowanych zasobów sieciowych, takich jak katalogi i drukarki. W skład podsystemu usług sieciowych wchodzą: Sieć Windows (Windows Networking), interfejs NetBIOS, protokoły Windows Sockets, RAS (Remote Access Service), SNMP (Simple Network Management Protocol) oraz funkcje sieciowej dynamicznej wymiany danych (Network DDE). Charakterystyka funkcji przekracza zakres wykładu
25
API Windows - wstęp Przedstawiony przed chwilą podział funkcji Win32 stanowi podstawę do zrozumienia budowy API i oferowanych przezeń możliwości. W C++ głównym elementem programu jest funkcja main. W programach pisanych pod Windows'a jest WinMain. Musimy dołączyć bibliotekę windows.h – dyrektywa include,}
26
Przykład #include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nMode) { return 0; } Funkcja główna ma 4 argumenty. Pierwszy argument hInstance to uchwyt (wskaźnik) instancji. Drugim argumentem tej funkcji, czyli hPrevInstance jest także uchwyt. Odnosi się on do poprzedniej instancji. Jest on jednak nieistotny, gdyż w systemie 32-bitowym nie jest używany. Kolejny argument o nazwie lpszCmdLine to wskaźnik do łańcucha znakowego. Ten łańcuch to nic innego, jak wskaźnik do ścieżki poleceń. Gdy program zostanie uruchomiony z argumentami, to można się do nich dostać za pomocą tego wskaźnika. Ostatni argument - nMode. Określa on sposób wyświetlania okna. Konkretnie chodzi o to, czy okno po utworzeniu ma być zminimalizowane czy zmaksymalizowane etc. - zazwyczaj stawiamy tam 0.
27
Przykład - cd Funkcja główna jest pusta. Zdefiniujemy trzy obiekty. Pierwszy to obiekt typu HWND będący uchwytem okna, drugi to struktura komunikatów typu MSG, a trzeci to struktura reprezentująca klasę okna, czyli typ WNDCLASS. HWND hOkno; MSG message; WNDCLASS okno; okno.hInstance = hInstance; okno.lpszClassName = "klasa główna"; okno.lpfnWndProc = DefWindowProc; okno.lpszMenuName = NULL; okno.style = 0; okno.hIcon = LoadIcon (NULL,IDI_WINLOGO); okno.hCursor = LoadCursor (NULL,IDC_ARROW); okno.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); okno.cbClsExtra = 0; okno.cbWndExtra = 0;
28
Objaśnienia Pierwsza instrukcja to: okno.hInstance = hInstance. W tej instrukcji określamy, do jakiej instancji będzie należało nasze okno. My podaliśmy nazwę hInstance, czyli to, co jest pierwszym argumentem funkcji głównej WinMain. Następna linijka to: okno.lpszClassName = "klasa główna";, czyli po prostu nazwa naszej klasy. Nazwa klasy posłuży nam później do utworzenia okienka. Kolejny wers okno.lpfnWndProc = DefWindowProc; to wskaźnik do procedury obsługi okna. Standardowa procedura o nazwie DefWindowProc obsługuje wszystkie zdarzenia i komunikaty. Robi to w sposób tradycyjny, co nie zawsze akceptujemy. Jeżeli chcemy, aby okienko w danej sytuacji reagowało inaczej to należy napisać własną procedurę i podczepić ją pod konkretne okno. Kolejnym elementem struktury WNDCLASS jest pole lpszMenuName. Tutaj określamy czy okno będzie posiadać menu. NULL oznacza, że menu nie będzie. Natomiast okno.style oznacza styl okna – 0 standardowy. Dwie następne instrukcje to okno.hIcon = LoadIcon(NULL, IDI_WINLOGO); i okno.hCursor = LoadCursor(NULL, IDC_ARROW);. Pierwsza określa, jaka ikona będzie widoczna na pasku tytułowym okna. W drugiej określamy jaki wygląd będzie miał kursor. Funkcja LoadIcon służy do odczytania ikony. Pierwszym argumentem tej funkcji jest NULL, co oznacza, że wybieramy ikonę z zasobów Windows'a. Jej nazwa jest podana w drugim argumencie. Analogicznie wygląda sprawa z kursorem. Ostatnią rzeczą, którą należy zrobić przy inicjalizacji struktury reprezentującej klasę okna jest ustawienie koloru okienka. Musimy zatem ustawić wskaźnik hbrBackground na odpowiedni pędzel. Pędzel to obiekt klasy HBRUSH. Ostatnie parametry to cbClsExtra i cbWndExtra. Określają one ile dodatkowej pamięci należy przydzielić dla klasy okna oraz samego okna. Zazwyczaj nie ma potrzeby rezerwowania dodatkowej pamięci i wpisujemy 0.
29
Tworzenie okna Praktycznie już możemy utworzyć nowe okno – po ustawieniach w przykładzie. Jednak zanim to zrobimy musimy jeszcze zarejestrować naszą klasę. Rejestracją zajmuje się funkcja RegisterClass. Jako argument przyjmuje adres struktury reprezentującej klasę okna. Rejestrujemy okno następująco: if (!RegisterClass (& okno)) return 0; Gdy wszystko pójdzie dobrze funkcja RegisterClass zwraca wartość niezerową. W przeciwnym wypadku [np. gdy braknie pamięci] klasa nie zostanie zarejestrowana i funkcja zwróci wartość 0. Wtedy trzeba jakoś zareagować – w tym przypadku zwracamy wartość 0 do funkcji WinMain co jest równoznaczne z zakończeniem programu.
30
Tworzenie okna Jednak gdy wszystko będzie dobrze i klasa zostanie zarejestrowana możemy wreszcie utworzyć pierwsze okno :) Robi się to funkcją CreateWindow. Jej deklaracja wygląda tak: HWND WINAPI CreateWindow (LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID); Pierwszym argumentem jest nazwa klasy okna. Drugi argument to tytuł okna, czyli text wyświetlany na pasku tytułowym. Dalej podajemy styl okna oraz koordynaty lewego-górnego narożnika okna. Dwa kolejne argumenty to wysokość i szerokość. Następnie jest uchwyt rodzica, czyli okna nadrzędnego, uchwyt menu i uchwyt instancji. Ostatni argument to dodatkowe informacje- często wstawiamy tu wartość NULL. Jeżeli tworzenie okna powiedzie się funkcja CreateWindow zwróci uchwyt do nowo utworzonego okna.
31
Przykład hOkno = CreateWindow ( "klasa główna", //nazwa klasy okna
"pierwsze okno", //tytuł okna WS_OVERLAPPEDWINDOW, //styl - //WS_OVERLAPPEDWINDOW to standardowe okienko 300, 400, //współrzędne lewego górnego rogu 200, 100, //..wymiary okna – szerokość i wysokość NULL, //brak okna nadrzędnego, właścicielem jest pulpit NULL, //brak menu hInstance, //uchwyt instancji NULL //brak dodatkowych danych );
32
Wyświetlenie okna na ekranie
Okienko już istnieje, ale trzeba jeszcze poinformować nasz program, że chcemy je wyświetlić na ekranie. Wystarczy wywołać funkcję ShowWindow. Funkcja ta przyjmuje tylko dwa argumenty. Pierwszy to uchwyt okienka [u nas jest to hOkno], a drugi to tryb wyświetlania okna [my podamy SW_SHOW, czyli po prostu wyświetlenie okna w normalnej postaci]. ShowWindow (hOkno, SW_SHOW);
33
Obsługa okna while (GetMessage (&message, NULL, 0, 0)) {
DispatchMessage (&message); } Funkcja GetMessage pobiera komunikaty od systemu. Gdy takowe się pojawią zostaje wywołana kolejna funkcja - DispatchMessage, która posyła komunikat do procedury okna, gdzie następuje odpowiednia reakcja. Pętla będzie tak długo wykonywana, aż zamkniemy okno.
34
Cały program #include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpsCmdLine, int nMode) { //uchwyt okna HWND hOkno; //struktura komunikatów MSG message; //klasa okna WNDCLASS okno; //uchwyt instancji okno.hInstance = hInstance; //nazwa klasy okna okno.lpszClassName = "klasa główna"; //standardowa procedura okna okno.lpfnWndProc = DefWindowProc; //brak menu okno.lpszMenuName = NULL; //standardowe okno okno.style = 0; //standardowa ikona okno.hIcon = LoadIcon (NULL, IDI_WINLOGO); //standardowy kursor okno.hCursor = LoadCursor (NULL, IDC_ARROW); //czarny kolor okno.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); //brak przydziału dodatkowej pamieci dla klasy okna okno.cbClsExtra = 0; //brak przydziału dodatkowej pamieci okna okno.cbWndExtra = 0; //rejestracja klasy okna if(!RegisterClass (&okno)) return 0; //utworzenie okna hOkno = CreateWindow ("klasa główna", "łokno :p", WS_OVERLAPPEDWINDOW, 100,100,200,100, NULL, NULL, hInstance, NULL); //wyświetlenie okna na ekranie ShowWindow (hOkno, SW_SHOW); while (GetMessage (&message, NULL, 0, 0)) DispatchMessage (&message); } Cały program
35
Okna informacyjne Okienko informacyjne zawierają informację. Takie okienka zazwyczaj zawierają dwa przycisk ok oraz anuluj. Okienko tworzymy za pomocą funkcji MessageBox (HWND hRodzic, LPCSTR lpTekst, LPCSTR lpNaglowek, UINT nStyl);. Pierwszy argument to uchwyt okna-rodzica. Wartość NULL oznacza brak rodzica. Dwa następne argumenty to kolejno text, jaki ukaże się w okienku oraz text nagłówka. Ostatni to flaga lub suma flag określająca wygląd okna. Zacznijmy od rodzaju przycisków w okienku. Do wyboru mamy kilka flag, które przedstawia następny slajd.
36
Znaczenie flag flaga dostępne przyciski
MB_ABORTRETRYIGNORE przerwij, ponów, ignoruj MB_OK ok MB_OKCANCEL ok, anuluj MB_RETRYCANCEL ponów, anuluj MB_YESNO tak, nie MB_YESNOCANCEL tak, nie, anuluj
37
Flaga a ikony Flaga dostępne ikony
MB_ICONEXCLAMATION lub MB_ICONWARNING czarny wykrzyknik w żółtym trójkącie MB_ICONINFORMATION lub MB_ICONASTERISK niebieski wykrzyknik w białym dymku MB_ICONQUESTION niebieski pytajnik w białym dymku MB_ICONSTOP lub MB_ICONERROR lub MB_ICONHAND czarny krzyżyk w czerwonym kole
38
Badanie naciśniętego przycisku
Jeżeli chcemy sprawdzić, jaki przycisk został wciśnięty to analizujemy odpowiedź Funkcji MessageBox: IDOK ok. IDCANCEL anuluj IDYES tak IDNO nie IDABORT przerwij IDRETRY ponów IDIGNORE ignoruj
39
Domyślny wybór Po wyświetleniu okienka domyślnie podświetlony jest pierwszy przycisk. Aby to zmienić należy dorzucić jedną flagę MB_DEFBUTTON*, gdzie * określa numer przycisku. Przykład: MessageBox (NULL, "Kliknij OK, aby rozpocząć formatowanie dysku :D", "informacja", MB_ABORTRETRYIGNORE | MB_DEFBUTTON2 | MB_ICONERROR);
40
Przykład #include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { int i; while(i!=IDYES) i=MessageBox(NULL, "Czy chcesz wyjść z programu?","Pytanie", MB_YESNO|MB_ICONQUESTION); } return 0;
41
Procedury obsługi okna
Budowa procedury: LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { //tutaj znajduje się obsługa komunikatów } Parametry: pierwszy to uchwyt kontrolki, która wysłała komunikat. Drugi to dowolna liczba większa od zera określająca treść owego komunikatu. Spis komunikatów można znaleźć w dokumentacji. Dwa pozostałe są ściśle związane z samym komunikatem. Ich zawartość jest uzależniona od tego, jaki komunikat przywędrował do procedury. Może to być np. kod wciśniętego klawisza, koordynaty kursora bądź inne podobne informacje.
42
Przykład Chcemy, by procedura w momencie kliknięcia jednego z przycisków z paska systemowego (prawy, górny róg okna) wyświetli stosowną informację. Chcemy tylko jak sprawdzić, co zostało kliknięte i czy w ogóle kliknięcie nastąpiło? Tutaj z pomocą przychodzą nam komunikaty. W momencie kliknięcia, na którymś z trzech wspomnianych przycisków do procedury zostaje wysłany komunikat WM_SYSCOMMAND. Oczywiście należy jeszcze zorientować się, który przycisk wciśnięto. Ta informacja zawarta jest w zmiennej typu WPARAM, która u nas będzie nazywała się wpar.
43
Przykład - cd //procedura obsługi okna
LRESULT CALLBACK NaszaProcedura (HWND hwnd, UINT message, WPARAM wpar, LPARAM lpar) { switch (message) case WM_SYSCOMMAND: switch (wpar) case SC_CLOSE: //wyświetlenie okienka z informacją i zakończenie programu MessageBox (hwnd, "koniec", "", MB_OK); PostQuitMessage (0); break; case SC_MINIMIZE: MessageBox (hwnd, "minimalizacja", "", MB_OK); case SC_MAXIMIZE: MessageBox (hwnd, "maksymalizacja", "", MB_OK); } default: return DefWindowProc (hwnd, message, wpar, lpar);
44
Rysowanie tekstu LRESULT CALLBACK ProcOkna(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; switch(message) case WM_PAINT: hdc = BeginPaint(hwnd,&ps); sprintf(str,"Witaj mistrzu!"); TextOut(hdc,0,0,napis,strlen(napis)); EndPaint(hwnd,&ps); break; case WM_DESTROY: PostQuitMessage(0); default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0;
45
Objaśnienia BeginPaint daje uchwyt do kontekstu urządzenia (hdc = handle of a device context), co umożliwia pisanie w naszym okienku. Funkcja sprintf umieszcza nasz tekst w tablicy napis po to, aby później móc podać jego długość dla funkcji TextOut. Funkcja TextOut ma pięć argumentów: pierwszy to wspominany uchwyt, drugi i trzeci to współrzędne x i y początku napisu, czwarty to wskaźnik do łańcucha (napis), zaś piątym jest długość łańcucha.
46
Własności tekstu: kolor liter i tła
Są to funkcje: SetTextColor(hdc,RGB(r,g,b)); SetBkColor(hdc,RGB(r,g,b)); Pierwsza funkcja ustawia kolor tekstu, zaś druga kolor tła. Trzy liczby w makrze RGB to składowe: czerwona, zielona i niebieska. Są nimi liczby z przedziału Jeśli napis nie jest widoczny to znaczy, że prawdopodobnie został przekroczony zakres przy podawaniu współrzędnych.
47
Własności tekstu: rozmieszczanie tekstu
Funkcja SetTextAlign wyrównuje tekst do lewej (TA_LEFT), do prawej (TA_RIGHT) bądź centruje (TA_CENTER). Druga stała powoduje zmianę wysokości w położeniu tekstu.
48
Rysowanie linii Linie rysujemy za pomocą dwu poleceń:
MoveToEx(hdc, x1, y1, zapamietaj_pop_punkt); LineTo(hdc, x2, y2);
49
Obsługa myszy LRESULT CALLBACK ProcOkna(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int cxClient, cyClient, cxMyszy, cyMyszy; HDC hdc; PAINTSTRUCT ps; switch(message) case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); break; case WM_LBUTTONDOWN: cxMyszy = LOWORD(lParam); cyMyszy = HIWORD(lParam); ilosc++; InvalidateRect(hwnd,NULL,TRUE); case WM_PAINT: hdc = BeginPaint(hwnd,&ps); sprintf(napis,"%d",ilosc); TextOut(hdc, cxMyszy, cyMyszy, napis, strlen(napis)); EndPaint(hwnd,&ps); case WM_DESTROY: PostQuitMessage(0); default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0;
50
Obsługa myszy Po kliknięciu lewym przyciskiem na obszarze roboczym, pojawia się liczba, która za każdym razem się zwiększa. Przedstawia ona ilość kliknięć myszką i przechowuje ją zmienna całkowita ilosc. Pojawił się również nowy komunikat WM_LBUTTONDOWN, który system wysyła, gdy tylko naciśniemy lewy przycisk myszki. Podobnie jak w przypadku komunikatu WM_SIZE, w słowach zmiennej lParam znajdują się interesujące nas rzeczy. Są to współrzędne położenia kursora w momencie kliknięcia i przechowują je zmienne statyczne cxMyszy i cyMyszy. Ponieważ funkcje rysujące działają dopiero po wysłaniu WM_PAINT, musimy to wymusić funkcją InvalidateRect, która każdorazowo odświeży nam cały obszar roboczy. W identyczny sposób można dodać obsługę WM_RBUTTONDOWN, czyli prawego przycisku myszy, który np. może zmniejszać wartość zmiennej ilosc o jeden.
51
Kontrolki Kontrolka to wszystko to, co znajduje się w oknie. Począwszy od standardowych przycisków, poprzez paski przewijania, rozwijane listy, paski postępu na kontrolce wyświetlającej strukturę plików na dysku kończąc. Utworzenie kontrolki, czy też okna pochodnego jest bardzo proste. Wystarczy skorzystać z funkcji CreateWindow. Problem pojawia się dopiero w przypadku bardziej zaawansowanych kontrolek, które potrzebują więcej informacji. Trzeba wtedy stworzyć odpowiednią strukturę, należycie ją zainicjalizować i posłać do kontrolki w postaci komunikatu.
52
Tworzenie kontrolki Do stworzenia oraz skorzystania z dowolnej kontrolki potrzeba: nazwy klasy reprezentującej kontrolkę znajomość funkcji CreateWindow dostępne style kontrolki komunikaty do obsługi kontrolki znajomość struktur potrzebnych podczas inicjalizacji kontrolki wiedza odnośnie funkcji SendMessage Pomoc: Można ją pobrać m.in. z serwera winapi.org. Archiwum zajmuje około 6 MB. Dotyczy ona WINAPI.
53
Przykład HWND hPrzycisk; hPrzycisk = CreateWindow ("button", "zwykły przycisk", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 10, 10, 100, 20, hOknoGlowne, NULL, hInstancja, NULL); Pierwszy argument to klasa okna. Drugi to nazwa okna, czyli w naszym przypadku tekst widniejący na przycisku. Trzeci argument to styl. Styl BS_PUSHBUTTON oznacza zwyczajny prostokątny [ew. kwadratowy] przycisk. Pozostałe argumenty to kolejno współrzędne przycisku, jego rozmiary, uchwyt okna-rodzica, uchwyt menu lub identyfikator kontrolki [wymagany przez komunikat WM_COMMAND], uchwyt instancji oraz dodatkowe informacje, których nie ma.
54
Praca z bitmapami Aby dodać bitmapy definiujemy dwie zmienne hBit1 i hBit2, które są uchwytami do bitmap. Uzyskuje je się za pomocą funkcji LoadBitmap. Nazwy bitmap są umieszczone w pliku zasobów o rozszerzeniu .rc w postaci: nazwa_bitmapy BITMAP plik.bmp Kolejna rzecz, którą musimy zrobić, to dostać uchwyt do tzw. kontekstu urządzenia pamięciowego (chodzi po prostu o pamięć). Czyni to funkcja CreateCompatibleDC. Następnie za pomocą SelectObject umieszczamy w pamięci wybraną bitmapę. Możemy już wreszcie wyświetlić nasz obrazek dzięki BitBlt. Tu kopiuje ona piksele bit po bicie z kontekstu pamięci (memDC) do kontekstu urządzenia (hdc). Dwie pierwsze liczby w wywołaniu funkcji określają początkowe współrzędne, zaś dwie następne rozmiar kopiowanego obszaru (nasze bitmapy są 128x128). Ważne, aby zwolnić pamięć, gdy już jest po wszystkim. Usuwamy kontekst pamięci funkcją DeleteDC oraz uchwyty do bitmap funkcją DeleteObject.
55
Przykład …. hBit1 = LoadBitmap(hInstance,"KRZYZYK");
hBit2 = LoadBitmap(hInstance,"KOLKO"); … LRESULT CALLBACK ProcOkna(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; HDC memDC; PAINTSTRUCT ps; switch(message) case WM_PAINT: hdc = BeginPaint(hwnd,&ps); memDC = CreateCompatibleDC(hdc); SelectObject(memDC, hBit1); BitBlt(hdc, 0, 0, 128, 128, memDC, 0,0,SRCCOPY); SelectObject(memDC, hBit2); BitBlt(hdc, 128, 0, 128, 128, memDC, 0,0,SRCCOPY); EndPaint(hwnd,&ps); DeleteDC(memDC); break; case WM_DESTROY: DeleteObject(hBit1); DeleteObject(hBit2); PostQuitMessage(0); default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0;
56
Tworzenie menu Utwórz plik „menu1.h” Utwórz plik zasoby2.rc
#define IDM_NOWA #define IDM_WYJSCIE 101 #define IDM_O_GRZE 102 Utwórz plik zasoby2.rc #include "menu1.h" MOJEMENU MENU { POPUP "&Gra" MENUITEM "&Nowa", IDM_NOWA MENUITEM "&Wyjście", IDM_WYJSCIE } POPUP "&Pomoc" MENUITEM "&O grze...", IDM_O_GRZE
57
Przykłady do samodzielnej pracy:
ii3.ap.siedlce.pl/~mirek/grafika
58
Literatura Informacje na podstawie:
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.