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

Podobne dokumenty