05_Kontekst_urzadzenia 129KB 284 2013
Transkrypt
05_Kontekst_urzadzenia 129KB 284 2013
mgr inż. Tomasz Jaworski Klasy graficzne GDI W wielu aplikacjach głównym sposobem komunikowania się z użytkownikiem jest obszar roboczy ich okien. Ten rozdział przedstawia zbiór funkcji służących do wykreślania figur i znaków w obszarze roboczym okna. Funkcji tych dostarcza system operacyjny Windows. Pozwala on również aplikacji na wykreślanie map bitowych poprzez tworzenie bloków pamięci o nazwie kontekst urządzenia w pamięci, które przechowują prostokątne obrazy. Funkcje rysujące potrafią kreślić w tym kontekście urządzeń. Windows uogólnia ten proces w taki sposób, że jeśli obsługują go konkretne urządzenia, to te same obiekty można wykreślać na drukarkach lub innych urządzeniach wyjściowych przez wywoływanie tych samych funkcji. 1. Interfejs urządzeń graficznych (GDI) Zestaw funkcji przeznaczonych do kreślenia i rysowania nazywa się GDI (Graphics Device Interface - Interfejs Urządzeń Graficznych). Jest to plik DLL dostarczany razem z systemem operacyjnym. Kiedy program kreśli obiekty bezpośrednio na ekranie lub drukarce, zawsze musi korzystać z funkcji GDI. Można wyróżnić dwie części systemu Windows, które dokonują konwersji wywoływanych funkcji graficznych na rzeczywiste polecenia wysyłane do urządzeń. Jedną z nich jest właśnie GDI. Większa jego część przechowywana jest w pliku o nazwie GDI.EXE znajdującym się w katalogu systemowym Windows. Środowisko operacyjne Windows ładuje GDI.EXE do pamięci, kiedy zachodzi potrzeba wykreślenia grafiki. System operacyjny również ładuje sterowniki urządzeń, jeśli konwersja nie jest zadaniem GDI.EXE. Sterowniki są zwykłymi programami ułatwiającymi interfejsowi GDI.EXE dokonywanie konwersji z poleceń graficznych na polecenia dla konkretnych urządzeń. 2. Kontekst urządzenia System operacyjny Windows zapewnia niezależność od urządzeń poprzez przyjęcie koncepcji kontekstu urządzenia. Oznacza to, że Twój program powinien umieć współpracować z różnymi klawiaturami, ekranami i drukarkami bez jakichkolwiek modyfikacji. Windows troszczy się o interfejs z urządzeniami, pozwalając programiście koncentrować się na samym programie. Programy dla Windows nie wysyłają danych bezpośrednio na ekran ani na drukarkę. Zamiast tego, program otrzymuje tzw. uchwyt do kontekstu urządzenia dla ekranu lub drukarki. Dane wyjściowe są wysyłane do kontekstu urządzenia, a potem system operacyjny dba już o ich przesłanie do konkretnego urządzenia. Zalety stosowania kontekstu urządzenia są takie, że polecenia dotyczące grafiki i tekstu przesyłane do kontekstu są zawsze takie same, bez względu na to, czy dane zostaną przedstawione na ekranie SVGA, drukarce czy innym nowym urządzeniu wynalezionym już po ukończeniu programu. Kontekst urządzenia jest fundamentalnym pojęciem systemu operacyjnego Windows. Reprezentuje on jedno z następujących urządzeń: ekran, drukarkę lub ploter albo pamięć. Oprócz reprezentowania określonego urządzenia wyjściowego, kontekst przechowuje informacje określające pewne aspekty wyglądu rysowanych obiektów. Kontekst urządzenia jest zbiorem danych (dokładniej mówiąc strukturą) zarządzanych przez Windows i identyfikowanym poprzez swój uchwyt. Reprezentuje on nie tylko obiekt przeznaczenia dla wykonywanych operacji graficznych, ale przechowuje również informacje o obiektach rysujących i parametrach określających tryby używane przez funkcje GDI podczas rysowania w kontekście. I tak, na przykład specjalny parametr określa kolor wykreślania znaków. Do ustawiania parametrów kontekstu urządzenia służą odpowiednie funkcje. Zawarte są one w klasie CDC. Omówione zostały w dalszej części rozdziału. Kontekst urządzenia przechowuje informacje o obiektach rysujących i parametrach kreślenia, jakich będzie się używać podczas rysowania w kontekście. Nazywa się je zbiorczo atrybutami kontekstu urządzenia. Kontekst urządzenia pobierany dla ekranu pochodzi zwykle z obszaru globalnego przechowującego ograniczoną liczbą kontekstów przeznaczonych dla wszystkich wykonywanych programów. Aby uniknąć wyczerpania tego obszaru, aplikacje powinny otrzymywać kontekst urządzenia bezpośrednio przed rysowaniem i zwalniać go natychmiast potem. Jeśli globalny obszar kontekstów zostanie wyczerpany, MFC poinformuje o tym użytkownika. Otrzymywany kontekst urządzenia jest strukturą danych zainicjowaną parametrami domyślnymi. Jeśli aplikacja zmienia któryś z atrybutów, to zmiany te giną po zwolnieniu przez nią lub usunięciu kontekstu. Istnieją dwie stowarzyszone funkcje CDC o nazwach SaveDC() i RestoreDC(), których można używać do zapamiętywania aktualnego stanu kontekstu przez skopiowanie wartości atrybutów (takich jak wybrane obiekty, tryb odwzorowania itp.) do specjalnego stosu zarządzanego przez Windows. Zapamiętane stany można później odtworzyć za pomocą funkcji RestoreCD(). Stosowanie tych funkcji wymaga określonego czasu na zapamiętywanie i odtwarzanie kontekstu. Pozwalają one jednak na uzyskiwanie zadowalającej efektywności programu. Istnieje pewien sposób całkowitego uniknięcia straty czasu związanej z uzyskiwaniem kontekstu urządzenia i zmienianiem atrybutów, kiedy aplikacja musi wykreślać dane. Jest to możliwe dzięki używaniu prywatnego kontekstu urządzenia. Powoduje to oszczędności czasu w programach, które często uaktualniają niewielkie fragmenty obrazu. Stosowanie prywatnych kontekstów urządzeń pociąga ryzyko wyczerpania wewnętrznego stosu GDI, zwłaszcza gdy korzysta się z kilku kontekstów (stosowanie prywatnego kontekstu urządzenia zostało omówione w ostatniej części tego rozdziału). Kontekst urządzenia zawiera informację opisującą urządzenie wyjściowe (ekran, drukarka itp.). Tę informację można otrzymać przez wywołanie funkcji CDC o nazwie GetDeviceCaps(nindex), gdzie nindex oznacza rodzaj pożądanej informacji. Na przykład wywołanie GetDeviceCaps(PLANES) zwraca liczbę płaszczyzn barw na każdy piksel. Można się też dowiedzieć, czy drukarka potrafi drukować grafikę, czy ekran jest monochromatyczny lub czy ma 16, 256 czy 6 milionów kolorów itp. 3. Obiekty GDI Kontekst urządzenia zawiera uchwyty do obiektów rysujących (terminu obiekt używa się tu w odniesieniu do rysowania, ale nie jest on obiektem C++). Obiekty te to: pędzel, pióro, czcionka, mapa bitowa (używana tylko w kontekście urządzeń pamięci), paleta i rejon (używany do rysowania i obcinania). Klasa MFC o nazwie CGdiObject dostarcza klasy bazowej dla tych obiektów. Obiektu CGdiObject nigdy nie tworzy się w sposób bezpośredni. Tworzy się go raczej w oparciu o jego klasy pochodne, takie jak: CPen, CBrush, CFont, CBitmap, CPalette i CRgn. Nigdy nie buduj obiektu klasy CGdiObject. Zamiast tego, buduj obiekty w oparciu o klasy pochodne. Konstruktory dla pewnych pochodnych klas GDI, takich jak CPen i CBrush, pozwalają na określanie dostatecznie wielu informacji po to, aby obiekt utworzyć w jednym kroku. Inne, takie jak CFont, można budować tylko w dwóch etapach. Dla tych klas buduje się najpierw obiekt C++ z konstruktorem domyślnym, a potem wywołuje funkcję CreateFont(). Klasa CGdiObject ma wirtualnego destruktora. Destruktor pochodny usuwa obiekt GDI związany z obiektem C++. Zasady rządzące stosowaniem obiektów GDI są następujące: • Jeśli budujesz obiekt GDI, to musisz go usunąć przed zakończeniem programu. • Nie usuwaj obiektów GDI, jeśli zostały one wybrane do kontekstu urządzenia (musisz najpierw oddzielić obiekt GDI od kontekstu urządzenia, a dopiero potem usunąć go). Ustawianie kontekstu urządzenia Kontekst urządzenia przechowuje i zapamiętuje aktualne ustawienia dla czcionki, jej koloru, koloru tła itp. W przypadku obiektu rysującego kontekst zostaje zmieniony przez wybranie obiektu do kontekstu za pomocą funkcji CDC::SelectObject(). Oznacza to po prostu, że udostępniony zostaje uchwyt obiektu rysującego i może on zostać natychmiast wykorzystany w kontekście. Poniższa tabela 4.1 przedstawia niektóre funkcje CDC służące do zmiany ustawień kontekstu. Tabela 4.1. Zmiana ustawień kontekstu urządzenia Ustawienia Kolor tekstu Kolor tła Tryb tła Czcionka systemowa Pióro Pióro systemowe Tryb wykreślania rastrowego Tryb wypełniania wieloboków Rejon obcinania Opis funkcji SetTextColor() ustawia kolor tekstu. SetBkColor() ustawia kolor tła otaczającego każdy znak. SetBkMode() ustawia proces malowania tekstu i grafiki, kiedy pokrywają one wszystko, co jest pod spodem (OPAQUE) lub kiedy białe obszary prześwitują. (TRANSPARENT). SelectStockObject() ustawia czcionkę używaną przez funkcję do wyprowadzania tekstu. SelectObject() ustawia pióro używane do rysowania linii i krawędzi obiektów. SelectStockObject() ustawia standardowe pióra systemowe. SetROP2() określa sposób łączenia wyświetlanych na ekranie pikseli z nowymi pikselami podczas rysowania piórami i pędzlami. SetPolyFillMode() określa sposób wypełniania wieloboków (zmienia ona obraz tylko wtedy, kiedy linie wielobo-ku przecinają się). SelectClipRgn() ogranicza obszar, w granicach którego wyświetlany jest obraz. Jak wynika z tabeli 4.1, funkcja SelectObject() została przeciążona dla każdego typu obiektu GDI. Zwraca ona wskaźnik do obiektu typu GDI aktualnie wybranego do kontekstu urządzenia. Zwróci na przykład CPen* dla obiektu CPen, CBrush* dla obiektu CBrush itp. SelectObject() ma wszystkie z następujących prototypów: CPen* CDC::SelectObject(CPen* p) CBrush* CDC::SelectObject(CBrush* b) CFont* CDC::SelectObject(CFont* f) CBItmap* CDC::SelectObject(CB1tmap* bm) CRgn* CDC::SelectObject(CRgn* r) 4. Klasa CDC Wszystkie operacje rysowania są wykonywane za pomocą funkcji składowych obiektu CDC. CDC dostarcza funkcji rysujących: Rectangle(), Ellipse(), Polygon(), PolyPolygon(), Chord(), RoundRect(), Pie(), LineTo(), Polyline() i Arc(). Klasa CDC dostarcza funkcji składowych dla operacji z kontekstem urządzenia i pracujących z narzędziami rysującymi, obiektami GDI oraz kolorami i paletami. Dostarcza również funkcji składowych do pobierania i ustawiania atrybutów rysowania oraz odwzorowywania, a także do pracy z polem widoku, obszarem okna i rejonami oraz do przekształcania współrzędnych i obcinania. Oferowane są również funkcje składowe do rysowania tekstu, pracy z czcionkami, przewijania i odtwarzania metaplików Klasa CDC dostarcza także obiektów dla kontekstu urządzenia. Zapewnia funkcje składowe oraz dane do pracy z kontekstem ekranu związanym z oknem. CDC zawiera dane składowe dla dwóch uchwytów kontekstów używanych w MFC: dla m_hDC, który jest uchwytem do kontekstu urządzenia wyjściowego oraz m_hAttribDC, który jest uchwytem dla kontekstu atrybutów. Podczas tworzenia obiektu CDC uchwyty te odnoszą się do tego samego urządzenia. CDC kieruje wszystkie wywołania wyjściowe GDI do m_hDC oraz większość wywołań odnoszących się do atrybutów - do m_hAttribDC. Przykładem wywołania z atrybutem jest GetTextColor(). SetTextColor() jest przykładem wywołania wyjściowego. Klasy kontekstu urządzenia MFC dostarcza kilku klas kontekstu urządzenia pochodzących od CDC, którymi są: CClientDC, CPaintDC, CWindowDC i CMetaFileDC. Wszystkie funkcje wyjściowe, takie jak TextOut(), są dziedziczone po klasie bazowej CDC, wskutek czego klasy kontekstu urządzeń wykorzystują ten sam zestaw odziedziczonych funkcji. Klasa CClient służy do zanicjowania kontekstu urządzenia dla ekranu monitora. Jeśli tworzony jest obiekt CClientDC, to tworzony jest również kontekst urządzenia, który zostaje odwzorowany tylko na obszar roboczy okna - rysowanie nie może odbywać się na zewnątrz niego. Punkt (0, 0) odnosi się zwykle do górnego lewego rogu obszaru roboczego. Klasa CClientDC działa wszędzie z wyjątkiem funkcji OnPaint(). Podczas przetwarzania komunikatu WM_PAINT w funkcji OnPaint() należy korzystać ze specjalnej klasy CPaintDC. Mieści ona w sobie wywołania do funkcji BeginPaint() i EndPaint(). Kiedy buduje się obiekt klasy CWindowCD, wówczas punkt (0,0) znajduje się w lewym, górnym rogu obszaru okna nie należącego do obszaru roboczego. Za pomocą tego kontekstu urządzenia rysowanie może odbywać się na brzegu okna, w obszarze jego nagłówka itp. CMetaFile jest specjalną klasą stosowaną razem z metaplikami. Metapliki składają się z kodu służącego do rysowania na ekranie monitora. Często mniej pamięci wymaga zapamiętywanie kodu niż przechowywanie map bitowych. Kiedy taki kod się zapamiętuje, pliki nazywa się metaplikami, a odwzorowywanie ich na ekranie „odtwarzaniem metaplików". W MFC obiekt kontekstu urządzenia dba o pobieranie kontekstu. Dba on również o jego zwalnianie. Najczęściej obiekt taki buduje się wewnątrz funkcji obsługi komunikatów. Kiedy związany z nim obiekt C++ wykracza poza swój zakres ważności, usuwany jest kontekst urządzenia. Przykład programu wykreślającego tekst i figury Program demonstruje zastosowanie kontekstu urządzenia i funkcji rysujących. Rysunek 4.1 przedstawia wynik działania tego programu, który ma nazwę „pr1". Kiedy wybierze się pozycję menu „DrawText", na ekranie wykreślany jest prostokąt, a w nim kolorem czerwonym tekst „Hello, World". Wykreślana jest również elipsa, zmienia się czcionka i na czarnym tle wykreślany jest biały tekst wewnątrz elipsy. Program ten demonstruje stosowanie klasy CClientDC i niektórych odziedziczonych funkcji składowych. Program demonstruje także funkcje rysujące CDC::Rectangle() i CDC::Elipse(). Obie one pobierają w charakterze parametrów wejściowych: int xl, int yt, int xr, int yb, gdzie (xl, yt) są współrzędnymi lewego górnego piksela, a (xr, yb) przedstawiają współrzędne prawego dolnego piksela obszaru roboczego. W przypadku elipsy dane te przedstawiają sobą prostokąt ograniczający, wewnątrz którego wykreślana jest elipsa. Rysunek 4.1. Wygląd okna działania programu „pr1” Wydruk 4.1. Kod źródłowy programu „pr1” Klasa aplikacji – pozostaje oryginalnie bez zmian Klasa okna głównego //--------------------------------------------------------------------------// mainfrm.h // class CMainFrame : publlc CFrameWnd { protected: CMainFrame(); DECLARE_DYNCREATE(CMainFrame) protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnRysuj(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //--------------------------------------------------------------------------// mainfrm.cpp // #include "MyApp.h" #include "malnfrm.h" #include "resource.h" BEGIN_MESSAGE_MAP(C_MainFrame, CFrameWnd) ON_COMMAND(ID_RYSUJ, OnRysuj) END_MESSAGE_MAP() C_MainFrame::C_MainFrame() { Create(NULL, "Hello World Example", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU1)); } void C_MainFrame::OnRysuj() { CClientDC MyDc (this); MyDc.SetViewportOrg(25,25); MyDc.Rectangle(25, 25, 200, 100); //wykreśla prostokąt MyDc.SetTextColor(RGB(255, 0, 0)); //ustala czerwony kolor tekstu MyDc.TextOut( 50, 50, "Hello, World!"); //wykreśla tekst wewnątrz prostokąta MyDc.Ellipse(250, 25, 450, 100); //wykreśla elipsę MyDc.SetTextColor(RGB(255, 255, 255)); //ustala biały kolor tekstu MyDc.SetBkColor(RGB( 0, 0, 0)); //ustala czarny kolor tła MyDc.SelectStockObject(ANSI_FIXED_FONT); //wybiera nową czcionkę systemową MyDc.TextOut( 300, 50, "Hello, World!"); //wykreśla tekst wewnątrz elipsy } //---------------------------------------------------------------------------- Program „Hello" wykreśla tekst i figury na ekranie. Do rysowania w obszarze roboczym okna wykorzystuje się kontekst CClient. Jego konstruktorowi przekazywany jest wskaźnik do obiektu okna, w którym wykreślane będą elementy. Wiersz: CClientDC MyDc(this); przekazuje wskaźnik okna funkcji konstruktora klasy CClient. Wskaźnik this wskazuje na obiekt klasy C_MainFrame, gdyż jest on używany wewnątrz ciała tej funkcji. Obiektowi CClientDC nadana zostaje nazwa MyDc. Kontekst urządzenia jest pobierany przez obiekt MyDc podczas jego konstruowania. Kiedy jest on pobierany po raz pierwszy, ma on wartości domyślne. Po utworzeniu obiektu CClientDC na ekranie można wykreślać wszelkiego rodzaju elementy za pomocą funkcji odziedziczonych przez obiekt MyDc. Najpierw wykreślany jest prostokąt z użyciem wartości domyślnych dla pióra i pędzla. Następnie kolor tekstu w kontekście zmienia się na czerwony i wewnątrz prostokąta wykreślany jest tekst. Następnie przy niezmienionych wartościach domyślnych dla pióra i pędzla wykreślana jest elipsa. Zmienia się kolor tekstu na biały, a kolor tła na czarny. Potem wykreśla się tekst wewnątrz elipsy. Na końcu funkcji obsługi obiekt MyDc traci zakres działania, automatycznie wywoływany jest jego destruktor, który powoduje zwolnienie kontekstu urządzenia. Możliwa jest zmiana początku układu współrzędnych poprzez wywołanie funkcji SetViewportOrg(25,25) na rzecz obiektu MyDc. Ustawi ona początek układu współrzędnych w punkcie (25,25), względem którego będą rysowane wszystkie kolejne elementy. Jak wygląda odświeżanie ekranu W poprzednim przykładzie do kreślenia w obszarze roboczym wykorzystano obiekt CClient. Takie podejście ma wadę, polegającą na tym, że wraz ze zmianą wielkości okna nie odbywa się odświeżenie obrazu. W poprzednim przykładzie trzeba było go odtwarzać przez powtórne wybranie pozycji menu. Korzystanie z obiektu CPaintDC i umieszczanie wywołań grafiki w funkcji OnPaint() zmienia to zachowanie, dzięki czemu grafika jest ponownie wykreślana zaraz po wysyłaniu komunikatu ON_PAINT. Tak się dzieje we wszystkich dalszych przykładach. System operacyjny Windows ustawia specjalny znacznik, kiedy tylko okno uzyskuje kilka nowych pikseli. Windows wysyła komunikat WM_PAINT do okna, jeśli zachodzi potrzeba odświeżenia obszaru roboczego. Jeśli nie ma ważniejszych komunikatów do przetwarzania, przetwarzany jest komunikat WM_PAINT i następuje odświeżenie okna. Komunikat WM_PAINT jest wysyłany zawsze, kiedy tylko występuje jedno z następujących zdarzeń: • Okno zawiera jeden lub więcej nieważnych rejonów (spowodowane to jest przez ponowne wyświetlenie jednego lub więcej uprzednio ukrytych obszarów okna. Takie okno staje się ponownie widoczne wtedy, kiedy okna znajdujące się nad nim zostają zamknięte lub usunięte. Windows zapamiętuje wszystkie nieważne rejony od ostatniego odświeżania i odświeża prostokąt pokrywający wszystkie nieważne rejony). • Użytkownik zmienia rozmiary okna. • Część obszaru roboczego zostaje przewinięta. • Aplikacja uaktualnia obszar roboczy wywołując funkcje: CWnd::Invalidate(), CWnd::InvalidateRect() lub CWnd::InvalidateRgn(). 5. Mapy bitowe Mapa bitowa jest zbiorem wartości kolorów dla prostokątnego obszaru obrazu. Rzeczywiste dane obrazu wgrywa się piksel po pikselu. Każdy piksel może być innego koloru, zatem jeśli zapamięta się kolor każdego piksela, zapamięta się tym samym cały obraz. Ilość danych niezbędna do zapamiętania obrazu zależy od jego wielkości i liczby używanych przez mapę bitową kolorów. W systemach czarnobiałych do reprezentowania kolorów potrzebny jeden tylko jeden bit dla każdego piksela. Można go ustawiać na 1 dla koloru białego oraz na 0 dla koloru czarnego. W przypadku obrazów kolorowych potrzeba więcej bitów. Ekran wyświetlający informacje w trybie 16-bitowym VGA wymaga 4 bitów na jeden piksel. Mapy bitowe nie są najlepszym sposobem do przechowywania dużych obrazów. Na przykład zapamiętanie ekranu VGA, który może wyświetlić 16 kolorów wymaga 640 x 480 x 4 bitów, co daje w sumie 806400 bitów lub inaczej około 100 KB pamięci. Ekran kolorowy potrafiący wyświetlać 6 milionów kolorów potrzebuje 3 bajty (24 bity) na każdy piksel. Zapamiętanie zatem tego samego obszaru ekranu wymagałoby osiem razem więcej pamięci niż w przypadku obrazów 16-bitowych. Używanie kontekstu pamięci Windows wykorzystuje mechanizm zapamiętywania grafiki w postaci mapy bitowej w pamięci używając kontekstu urządzenia pamięci. Dzięki temu możliwa jest konwersja formatu map bitowych na format fizyczny używany przez ekran (lub drukarkę). Kontekst ten jest podobny do kontekstu dla ekranu (lub drukarki), z tym tylko wyjątkiem, że nie wiąże się z określonym urządzeniem. Tworzony jest blok w pamięci w celu przechowania wartości kolorów dla każdego piksela w prostokątnym obszarze ekranu, który zapamiętuje się jako mapę bitową. Mapę taką należy wybrać do kontekstu pamięci, zanim będzie można ją wyświetlić w fizycznym urządzeniu. Wybór mapy do kontekstu pamięci daje systemowi operacyjnemu możliwość zadecydowania, czy dane kolorów mają być zorganizowane w płaszczyzny kolorów (co jest stosowane w kartach graficznych VGA z 16 kolorami), czy też zorganizowane z wykorzystaniem sąsiadujących bitów (co stosuje się w kartach graficznych o większych rozdzielczościach). Do utworzenia obszaru pamięci, który będzie przechowywać mapę bitową i kopiować do niej piksele, potrzebny jest proces składający się z czterech kroków: • Wywoływana jest funkcja CDC::CreateCompatibleDC() w celu utworzenia kontekstu pamięci, który jest „kompatybilny" z kontekstem urządzenia dostarczonym jako argument (kontekst pamięci jest w rzeczywistości strukturą danych przechowującą między innymi atrybuty rysunku i wskaźnik do obszaru mapy bitowej. Ten kompatybilny kontekst będzie mieć taką samą liczbę bitów na jeden piksel co kontekst urządzenia wyświetlającego dane, którego wskaźnik jest przekazywany do funkcji CBitmap::CreateCompatibleBitmap()). • Wywoływana jest funkcja CBitmap::CreateCompatibleBitmap() w celu utworzenia bloku pamięci, który będzie przechowywać mapę bitową. Mapa bitowa składa się z nagłówka i wartości pikseli dla prostokątnego obszaru obrazu (argumenty tej funkcji określają kontekst urządzenia, dla którego musi być zachowana zgodność oraz wielkość (szerokość i wysokość) obszaru prostokątnego. Utworzona mapa bitowa jest obiektem graficznym). • Wywoływana jest funkcja CDC::SelectObject() w celu związania tego obiektu bitowego, podanego jako argument, z kontekstem pamięci. • Następnie wykorzystana zostaje funkcja CDC::BitBit() dla skopiowania pikseli, które znajdą się pod figurą, do bloku mapy bitowej (w rzeczywistości kopiowany jest obszar prostokątny. Wybiera się go tak, aby pokrywał wykreślaną figurę).