20.1.2002
V minulém pokračování jsme si ukázali ten nejjednodušší způsob, jak vykreslit bitmapu. V tomto pokračování si ukážeme některé další funkce pro kreslení grafických objektů, které mají více možností. Podívejme se na výsledek dnešního ukázkového příkladu. Je zde opět vykreslena bitmapa (jiným způsobem než v minulém článku) a dále ikona v různých režimech zobrazení, a nakonec ikona o velikosti 48x48.
Pokud chceme například na grafický objekt (včetně výpisu textu) aplikovat efekty jako je například "disabled", tedy vykreslení objektu tak jak bývá obvyklé u zakázaných prvků, jako tlačítka na panelu nástrojů nebo texty i obrázky u zakázaných položek menu, můžeme použít funkci DrawState:
BOOL DrawState( HDC hdc, // handle kontextu zařízení HBRUSH hbr, // handle štětce DRAWSTATEPROC lpOutputFunc, // callback funkce LPARAM lData, // informace o grafickém objektu WPARAM wData, // další info o objektu int x, // horizontální souřadnice int y, // vertikální souřadnice int cx, // šířka int cy, // výška UINT fuFlags // typ objektu a další volby );
Tato funkce nám například v případě bitmapy umožňuje její přímé vykreslení bez nutnosti vytvářet pro ni kontext zařízení. Stačí nám pouze mít platný handle bitmapy. Kresleným objektem může být kromě bitmapy také ikona, kurzor nebo text. V parametru fuFlags máme pak možnost například specifikovat tyto parametry:
Při použití této funkce navíc nemusíme uvádět rozměry kresleného objektu, pokud uvedeme hodnoty 0, funkce sama vypočítá velikost objektu a vykreslí jej celý. Typ grafického objektu určíme v parametru fuFlags, který může nabývat například následujících hodnot:
Dále si řekněme o univerzálnější a šikovnější funkci pro načítání bitmap, ikon a kurzorů, kterou je LoadImage:
HANDLE LoadImage( HINSTANCE hinst, // handle instance LPCTSTR lpszName, // grafický objekt UINT uType, // typ grafického objektu int cxDesired, // požadovaná šířka int cyDesired, // požadovaná výška UINT fuLoad // volby načtení );
Tato funkce umí například načítat všechny uvedené typy grafických objektů nejen ze zdrojů, ale také ze souboru. Uveďme si některé volby, které můžeme specifikovat v parametru fuLoad:
Dále máme možnost také u ikon a kurzorů specifikovat vlastní rozměry. Lze tak například načíst ikonu nebo kurzor rozměru 48x48, což je zejména ve Windows XP jeden z běžných rozměrů obrázku obsažených v ikoně.
V souvislosti s kreslením ikon či kurzorů si řekněme ještě o jedné funkci, kterou je DrawIconEx:
BOOL DrawIconEx( HDC hdc, // handle kontextu zařízení int xLeft, // x-ová souřadnice int yTop, // y-ová souřadnice HICON hIcon, // handle ikony (kurzoru) int cxWidth, // šířka ikony int cyWidth, // výška UINT istepIfAniCur, // pro animovaný kurzor index obrázku HBRUSH hbrFlickerFreeDraw, // brush pozadí, může být NULL UINT diFlags // volby kreslení );
Jak je patrné z parametrů, můžeme zde například vykreslit libovolný "krok" v animovaném kurzoru. Můžeme samozřejmě také specifikovat požadované výsledné rozměry obrázku, lze tak tedy ikonu či kurzor kreslit roztažené do libovolné velikosti.
Další možnosti všech uvedených funkcí naleznete samozřejmě v dokumentaci a můžete tedy sami dále experimentovat.
Nyní se podívejme na kód handleru WM_PAINT dnešního doprovodného příkladu:
void OnPaint(HDC hdc) { HBITMAP hBitmap = (HBITMAP)LoadImage(hInst, "eso.bmp", IMAGE_BITMAP, 0,0, LR_DEFAULTSIZE | LR_LOADFROMFILE); DrawState(hdc, NULL, NULL, (LPARAM)hBitmap, 0, 10, 10, 0, 0, DST_BITMAP); DeleteObject(hBitmap); DrawState(hdc, NULL, NULL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)), 0, 190, 10, 0, 0, DST_ICON); HBRUSH hBrush = CreateSolidBrush(0x00A0A0FF); DrawState(hdc, hBrush, NULL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)), 0, 190, 50, 0, 0, DST_ICON | DSS_MONO); DeleteObject(hBrush); DrawState(hdc, NULL, NULL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)), 0, 190, 90, 0, 0, DST_ICON | DSS_DISABLED); HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON2), IMAGE_ICON, 48,48, LR_SHARED); DrawIconEx(hdc, 190, 130, hIcon, 0, 0, 0, NULL, DI_NORMAL); }
Nejprve je zde ukázka načtení bitmapy ze souboru a její vykreslení (bez použití dalšího kontextu zařízení) pomocí funkce DrawState. Stejnou funkcí je také vykreslena ikona, v prvním případě v běžném stavu, ve druhém monochromaticky, přičemž je použit vlastní štětec definující monochromatickou barvu, a dále tatáž ikona jako "zakázaná". Na konec je nakreslena ikona obsahující obrázek velikosti 48 x 48 tak, že je načten právě tento obrázek. O tom, že je vybrán právě tento a nikoliv 32x32, který by byl roztažen, se lze přesvědčit z parametrů funkce DrawIconEx, kde jsou rozměry uvedeny jako 0, a tedy funkce použije velikost obrázku, který je načten.
Nakonec ještě důležitá poznámka pro spuštění projektu. Bitmapa "eso.bmp" musí být v adresáři, kde běží program, tedy obvykle \debug nebo \release. Já jsem ji přidal mezi zdrojové kódy a další soubory projektu. Samozřejmě můžete ve funkci LoadImage uvést libovolnou plnou cestu k vlastní bitmapě.
Doprovodný projekt je ke stažení zde: win_api_20.zip
Školení
Kontakt
739 219 991
live:radekchalupa_1
Nové články