Nie bêdê omawia³ tej funkcji, ale nieco informacji na jej
temat mo¿na znaleŸæ w Knowledge Base article Q80080.
Sekcja DIB
Mam nadziejê, ¿e teraz dobrze czujesz ró¿nicê miêdzy bitmapami zale¿nymi od
urz¹dzeñ a bitmapami od nich niezale¿nymi. DIB mo¿e mieæ jedn¹ z kilku orga-
ruzacji kolorów; DDB musi byæ albo monochromatyczna, albo mieæ taki sam for-
mat jak rzeczywiste urz¹dzenie wyjœciowe. DIB jest plikiem lub blokiem pamiê-
ci; DDB jest bitmapowym obiektem GDI i jest reprezentowana przez uchwyt bit-
mapy. DIB mo¿e byæ wyœwietlons lub konwertowana na DDB i z powrotem, lecz
to wi¹¿e siê z procesem konwersji miêdzy bitmapami niezale¿nymi od urz¹dzeñ
a bitmapami charakterystycznymi dla urz¹dzenia.
Teraz zbli¿amy siê do poznania funkcji, która zdaje siê ³amaæ te zasady. Zosta³a
wprowadzona w 32-bitowych wersjach Windows i nazywa siê CreateDIBSection.
Oto jej sk³adnia:
hBitmap = CreateDIBSection (
hdc, // uchwyt kontekstu urzddzenia
pInfo, // wskaŸnik do informacji o DIB
fColorUse, // okreœlenie rodzaju danych koloru
ppBits, // wskaŸnik do zmiennej wskaŸnikowej
hSection, // uchwyt obiektu odwzorowania pliku
dwOffset) ; // offset do bitów w obiekcie odwzorowania pliku
CreateDIBSection to jedna z najwa¿niejszych funkcji w Windows API (a przynaj-
mniej, je¿eli du¿o pracujesz z bitmapami), lecz jest tak niesamowita, ¿e mo¿e zostaæ
uznana za nader ezoteryczn¹ i trudn¹ do zrozumienia.
Rozpoczrujmy od samej nazwy funkcji. Wiemy, co to jest DIB, lecz czym do dia-
b³a jest "sekcja DIB"? Kiedy po raz pierwszy spojrza³eœ na funkcjê CreateDIBSec-
tion, mo¿e zacz¹³eœ siê zastanawiaæ, czy nie pracuje ona jedynie na jakiejœ czêœci
728 Czêœæ II: Grafika
DIB. Jest to bliskie prawdy. To, co robi CreateDIBSection, to istotnie utworzenie
czêœci (sekcji) DIB - bloku pamiêci na bity pikseli bitmapy.
Spójrzmy teraz na wartoœæ zwracan¹. Jest to uchwyt do obiektu bitmapowego
GDI. Ta wartoϾ zwracana jest przypuszczalnie najbardziej zwodniczym aspek-
tem wywo³ania CreateDIBSection zdaje siê sugerowaæ, ¿e ta funkcja dzia³a podobnie
do CreateDIBitmap. Tak, s¹ podobne, ale zarazem ca³kowicie odmienne. W rze-
czywistoœci uchwyt bitmapy zwracany z CreateDIBSection znacznie ró¿ni siê od
uchwytu bitmapy zwracanego ze wszystkich funkcji tworz¹cych bitmapy, jakie
napotkaliœmy rozdziale w tym i poprzednim.
Gdy ju¿ zrozumiesz charakter funkcji CreateDIBSection, mo¿esz zastanowiæ siê,
dlaczego wartoœæ zwracana nie zosta³a zdefiniowana jakoœ inaczej. Mo¿e nawet
dojdziesz do wniosku, ¿e CreateDIBSection powinna by³a byæ nazwana CreateDl-
Bitmap, a ta z kolei powinna by³a zostaæ nazwana, jak wczeœniej wspomnia³em,
CreateDDBitmap.
W pierwszym podejœciu do funkcji CreateDIBSection zastanówmy siê, jak mo¿emy
j¹ uproœciæ i natychmiast jej u¿yæ. Po pierwsze, ostatnim dwóm argumentom, hSec-
tion i dwOffset, mo¿esz nadaæ wartoœci, odpowiednio, NULL i 0. Wykorzystanie tych
argumentów omówiê pod koniec rozdzia³u. Po drugie, parametr hdc u¿ywany jest
jedynie wówczas, gdy parametr fColorUse ma wartoœæ DIB- PAL COLORS. Jeœli
fColorUse wynosi DIB RGB COLORS (lub 0), hdc jest ignorowane. (Nie jest tak
w przypadku CreateDIBitmap, gdzie parametr hdc jest u¿ywany do uzyskania for-
matu koloru urz¹dzenia, z którym ma byæ kompatybilna DDB).
Zatem w swojej najprostszej postaci CreateDIBSection wymaga jedynie drugiego
i czwartego argumentu. Drugi argument to wskaŸnik do struktury BITMAPIN-
FO. Z takim wskaŸnikiem mieliœmy ju¿ poprzednio do czynienia. Mam nadziejê,
¿e zdefiniowanie wskaŸnika do wskaŸnika w czwartym argumencie nie odebra-
³o ci zapahx. W rzeczywistoœci jest to doœæ proste, gdy siê u¿ywa funkcji.
Za³ó¿my, ¿e chcesz utworzyæ DIB 384X256 bitów, 0 24 bitach na piksel. Format
24-bitowy jest najprostszy, poniewa¿ nie wymaga tablicy kolorów, zatem dla pa-
rametru BITMAPINFO mo¿emy zastosowaæ strukturê BITMAPINFOHEADER.
Definiujesz trzy zmienne: strukturê BITMAPINFOHEADER, wskaŸnik do BYTE
i uchwyt bitmapy:
BITMAPINFOHEADER bmih ;
BYTE * pBits ;
HBITMAP hBitmap ;
Teraz zainicjuj pola struktury BITMAPINFOHEADER:
bmih->biSize = sizeof (BITMAPINFOHEADER) ;
bmih->biWidth = 384 ;
bmih->biHeight = 256 ;
bmih->biPlanes = 1 ;
bmih->biBitCount = 24 ;
bmih->biCompression = BIþRGB ;
bmih->biSizeImage = 0 ;
bmih->biXPelsPerMeter = 0 ;
bmih->biYPelsPerMeter = 0 ;
bmih->biClrUsed = 0 ;
bmih->biClrImportant = 0 ;
Rozdzia³ 15: Bitmapa niezale¿na od urz¹dzeñ 72g
Po tych ograniczonych do minimum przygotowaniach gotowi jesteœmy do wy-
wo³ania funkcji:
hBitmap = CreateDIBSection (NULL, (BITMAPINFO *) &bmih, 0, &pBits, NULL, 0) ;
Zauwa¿, ¿e jako drugi argument bierzemy jak zwykle adres struktury BITMA-
PINFOHEADER, lecz tak¿e, co jest niezwyk³e, adres pBits - wskaŸnika do BYTE.
Tak wiêc czwarty argument jest wskaŸnikiem do wskaŸnika, jak tego wymaga
funkcja.
Oto co robi funkcja CreateDIBSection: bada strukturê BITMAPINFOHEADER i alo-
kuje blok pamiêci, który mo¿e pomieœciæ bity pikseli DIB. (W tym szczególnym
przypadku blok ma rozmiar 384x256x3 bajtów). W parametrze pBits, który do-
starczy³eœ, zapisuje wskaŸnik do tego bloku pamiêci. Funkcja zwraca tak¿e
uchwyt do bitmapy, który jak powiedzia³em, nie jest dok³adnie taki sam, jak
uchwyt zwracany przez funkcjê CreateDIBitmap i inne funkcje tworz¹ce bitmapy.
Jednak jeszcze nie skoñczyliœmy. Piksele bitmapy s¹ niezainicjowane. Czytaj¹c j
plik DIB, mo¿esz po prostu przekazaæ parametr pBits do funkcji ReadFile i wczy-
taæ je. Mo¿esz je te¿ ustawiæ "rêcznie" w kodzie programu.
Program DIBSECT przedstawiony na rysunku 15-11 jest podobny do programu
DIBCONV, z t¹ ró¿nic¹, ¿e wywo³uje funkcjê CreateDIBSection zamiast CreateDl-
Bitmap.
DIBSECT.C
/*
DIBSECT.C - Wyœwietla sekcjê DIB w obszarze roboczym okna



 

 

 

 

 

 

 

 

 

 

 

 

   
 
  BLOWUP w rozdziale 14...
Pomodliłem się do każdego boga jaki istniał bym był w wstanie wkurzyć tę kobietę do granic możliwości.