Nie chcesz mnie, Ben. Składam się z siedmiu warstw popieprzenia okraszonych odrobiną gównianego szaleństwa.
Program METAFILE
Program pokazuje zastosowanie czterech funkcji niezbêdnych do utworzenia me-
tapliku w pamiêci. Pierwsz± z nich, CreateMetaFile, program wywo³uje z argu-
mentem NULL w czasie obs³ugiwania komunikatu WM CREATE. Funkcja zwraca
uchwyt kontekstu urz±dzenia metapliku. Nastêpnie program rysuje dwie niebie-
skie linie i niebiesk± elipsê, u¿ywaj±c kontekstu urz±dzenia metapliku. Dotych-
czasowe wywo³arua funkcji s± umieszczane w postaci binarnej w metapliku. Funk-
cja CloseMetaFile zwraca uchwyt nowo powsta³ego pliku. Zauwa¿, ¿e uchwyt ten
jest przechowywany w postaci zmiennej statycznej, gdy¿ bêdzie pó¼niej potrzebny.
Metaplik zawiera binarn± reprezentacjê wywo³añ funkcji GDI - w tym wypadku
dwa wywo³ania MoveToEx, dwa LineTo, jedno wywo³anie SelectObject (okre¶laj±-
ce niebieski kolor pêdzla) oraz jedno Ellipse. Nie zastosowano ani trybu odwzo-
rowania, ani transformacji wspó³rzêdnych obiektów. S± one przechowywane
w metapliku w postaci liczb.
W trakcie obs³ugi komunikatu WMþPAINT METAFILE ustala tryb odwzorowa-
nia i wywo³uje funkcje PlayMetaFile, aby utworzony obraz narysowaæ w oknie
100 razy. W trakcie wywo³ania tej funkcji wszystkie instrukcje miêdzy CreateMe-
taFile i CIoseMetaFile wydane podczas obs³ugi komunikatu WM CREATE powta-
rzane s± sekwencyjnie 100 razy.
Rozdziat 18: Metapliki
Podobnie jak inne obiekty GDI, metapliki musz± byæ usuniête z pamiêci przed
zakoñczeniem programu. Zajmuje siê tym funkcja DeleteMetaFile w czasie obs³u-
giwania komunikatu WMþDESTROY.
Wynik dzia³ania programu METAFILE przedstawiono na rysunku 18-2.
Rysunek 18-2. Wynik dzia³ania programu METAFILE
Zapisywanie metaplików na dysku
W powy¿szym przyk³adzie argument NLJLL przyjmowany przez funkcjê Create-
MetaFile oznacza³, ¿e metaplik ma byæ przechowywany w pamiêci. Oczywi¶cie
mo¿liwe jest rówrue¿ zapisanie metapliku na dysku. Metoda ta jest korzystniej-
sza w wypadku wielkich metaplików ze wzglêdu na niewielkie zu¿ycie pamiêci
operacyjnej. Z drugiej strony, dostêp do metapliku zapisanego na dysku trwa
znacznie d³u¿ej ni¿ do metaplików przechowywanych w pamiêci.
Chc±c, by program METAFILE utworzy³ metaplik na dysku, wystarczy zamieniæ
argument NULL funkcji CreateFileName na nazwê pliku. Po zakoñczeniu sekwencji
obs³uguj±cej komunikat WMþCREATE nale¿y wywo³aæ funkcjê DeleteMetaFile,
przyjmuj±c± jako argument uchwyt utworzonego metapliku. Po tej operacji usu-
niêty zostanie uchwyt, lecz na dysku pozostanie plik.
W trakcie obs³ugi komunikatu WMþPAINT mo¿esz pobraæ uchwyt pliku dysko-
wego przez wywo³anie GetMetaFile:
hmf = GetMetaFile (szFileName) ;
Teraz mo¿esz odtworzyæ metaplik w taki sam sposób jak poprzednio. Po zakoñ-
czeniu obs³ugi komunikatu WMþPAINT mo¿esz usun±æ uchwyt metapliku:
DeleteMetaFile (hmf)
Obs³uga komunikatu WMþDESTROY nie wymaga usuniêcia metapliku, gdy¿ sta³o
siê to ju¿ po zakoñczeniu obshxgi komunikatów WMþCREATE oraz WM PAINT.
g7g Czþ¶æ II: Grafika
Powiniene¶ jednak usun±æ plik dyskowy w nastêpuj±cy sposób:
DeleteFile (szFileName) ;
oczywi¶cie je¶li rue chcesz go zatrzymaæ.
Mo¿esz utworzyæ defiruowan± przez u¿ytkownika bibliotekê metaplików (oma-
wia³em to w rozdziale 10). Maj±c blok danych w formacie metapliku, mo¿esz na
jego podstawie utworzyæ metaplik za pomoc± funkcji:
hmf = SetMetaFileBitsEx (iSize, pData) :
SetMetaFileBitsEx ma bli¼niacz± funkcjê GetMetaFileBitsEx, która kopiuje zawar-
to¶æ metapliku do pamiêci w postaci bloku danych.
Stary format metapliku i Schowek
Stary format metaplików ma powa¿na wadê: dysponuj±c jedynie uchwytem
metapliku nie jeste¶ w stanie wyznaczyæ jego rozmiarów w trakcie odtwarzania.
Jedyny sposób to dok³adne przyjrzenie siê jego strukturze.
Co wiêcej, kiedy program otrzymuje metaplik za po¶rednictwem Schowka, naj-
wiêksz± elastyczno¶æ w pracy z tym metaplikiem uzyskuje siê, je¶li zosta³ zapro-
jektowany do odtwarzania w trybie odwzorowania MM ISOTROPIC lub
MM ŽMSOTROPIC. Program otrzymuj±c metaplik mo¿e skalowaæ obraz przez
ustalenie rozmiarów pola widzenia przed odtworzeniem metapliku. Je¶li jednak
tryb odwzorowania MM ISOTROPIC lub MMþAMSOTROPIC zosta³ ustawio-
ny wewn±trz metapliku, program, otrzymuj±c go do odtworzenia, blokuje siê.
Mo¿e wywo³aæ funkcje GDI jedynie przed lub po odtworzeniu metapliku, nie
mo¿e natomiast obs³ugiwaæ wywo³ania GDI z poziomu metapliku.
Aby temu zaradziæ, uchwyty metaplików zapisanych w starym formacie nie s±
bezpo¶rednio wklejane do Schowka i odbierane przez inne programy. Staj± siê
natomiast czê¶ci± obrazu metapliku, który jest struktur± typu METAFILEPICT.
Pozwala ona programowi, otrzymuj±cemu obraz metapliku ze Schowka, na usta-
wienie trybu odwzorowania i rozmiarów pola widzenia jeszcze przed odtworze-
niem samego metapliku.
Struktura METAFILEPICT ma d³ugo¶æ 16 bajtów i jest zdefiniowana nastêpuj±-
co:
typedef struct tagMETAFILEPICT
(
LONG mm; // tryb odwzorowania
LONG xExt ; // szeroko¶æ obrazu metapliku
LONG yExt ; // wysoko¶æ obrazu metapliku
LONG hMF ; // uchwyt metapliku
)
METAFILEPICT
We wszystkich trybach odwzorowania z wyj±tkiem MMþISOTROPIC i MM ŽM-
SOTROPIC warto¶ci xExt i yExt reprezentuj± rozmiary obrazu w jednostkach trybu
odwzorowania okre¶lonych w polu mm. Program wyposa¿ony w tak± informa-
cjê, kopiuj±c strukturê zwi±zan± z obrazem metapliku ze Schowka, mo¿e okre-
¶liæ, ile miejsca na ekranie zajmie odtwarzany metaplik. Program tworz±cy meta-
plik mo¿e ustaliæ maksymalne warto¶ci wspó³rzêdnych x i y u¿ywanych przez
funkcje GDI.
Rozdzia³ 18: Metapliki
Pola xExt i yExt funkcjonuj± nieco inaczej w trybach odwzorowania MM_ISO-
TROPIC i MM ŽNISOTROPIC. Jak pisa³em w rozdziale 5, program korzysta
z tych trybów, gdy musi u¿yæ jednostek logicznych dla funkcji GDI ruezale¿nie
od rzeczywistych rozmiarów obrazu. Stosuje tryb MMþISOTROPIC, chc±c zacho-
waæ proporcje obrazu bez wzglêdu na rozmiary obserwowanej sceny, a MM-AM-
SOTROPIC - gdy proporcje rozmiarów nie maj± ¿adnego znaczenia. W rozdziale
5 pisa³em równie¿, ¿e po ustawieniu jednego z tych dwóch trybów odwzorowa-
rua program wywohzje funkcje SetWindowExtEx i SetViewportExtEx
|
WÄ…tki
|