Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




GDI (Graphical Device Interface)

Maghiara


GDI (Graphical Device Interface)

Ebben a fejezetben ismertetni szeretnénk a Windows alatti rajzolással rajzolással kapcsolatos problémákat. Mivel a nyomtatás a Windows alatt teljesen ugyanúgy végezhető el mint a képernyőre való rajzolás, ezért a nyomtatással kapcsolatos tudnivalókat is ebben a fejezetben ismertetjük.

Windows-ban a rajzolási rutinok a "gdi.exe" DLL-ben helyezkednek el. Ez a DLL kb 200 rutint tartalmaz és a Windows indításakor töltődik be a memóriába. Amikor a mi programunk egy kört vagy egy négyszöget rajzol, akkor ennek a DLL-nek valamelyik függvényét hívja meg. Természetesen a GDI nem egyedül végzi ezeket a műveleteket, hiszen a fizikai ezsközöket kezelő driverek fölött helyezkedik el (13. ábra). Ezek a driverek transzformálják a GDI függvényeket a fizikai eszköz által érthető nyelvvé. Ez eredményezi az eszköz függetlenségi programozást a Windows alatt. Ugyanaz a GDI függvény tud rajzolni pl. egy négyszöget egy EGA monitoron mint VGA-n vagy SVGA-n vagy nyomtatón. Amikor egy új pl. VGA kártyát akarunk betenni a gépünkbe, általában az a szokás, hogy a kártyához a saját driverét installáljuk fel. Az új driver kezeli le 17217j94r gjobban az új kártyát, hiszen erre van optimalizálva. Az új driver installálása után nem kell törődnünk azzal, hogy ez hogyan kezeli a kártyát és természetesen a programunkat sem kell módosítani. A GDI-nek az a hátránya, hogy nem támogatja az animációt, csak kétdimenziós és csak egész számokat használ.



A GDI függvények a következő csoportokba sorolhatók :

vektor rajzolási függvények (line, rectangle, ellipse, stb.)

bitmap manipulálási függvények

szöveg megjelenítési függvények

paletták menedzselése ( ez általában az SVGA esetén van szerepe)

A GDI által támogatott eszköz függetlenségnek egyik fontos előnye, hogy segítségével könnyen lehet transzformálni a rajzokat egyik eszközről a másikra, hiszen az eszközöknek a felbontása különböző (Pl. Nyomtató és képernyő). Ennek megvalósítására a GDI koordináta leképezést használ. Ez a leképezés lehetővé teszi, hogy a rajzainkat olyan koordinátákban adjuk meg, amelyek a számunkra legkényelmesebbek a feladat megvalósításához. Az egész rajzolási művelet úgy végezhető el, mintha papíron rajzolnánk.

16.1. Device Context (DC)(eszközkapcsolat)

A DC a kulcsa a GDI-nek az eszköz függetlenség megvalósításához. Minden GDI függvény egy handle-t (integer) igényel argumentumként. A DC-t úgy foghatjuk fel mint egy általánosított modellje az output eszköznek. Valójában a DC egy adat struktúra, amely az eszközön való rajzoláshoz szükséges információkat tartalmazza. Pl. Háttérszín, toll, font, kitöltési minta, stb. Mivel a DC egy grafikus eszközt reprezentál, ezért megosztott eszközként használható. Ahhoz, hogy tudjunk rajzolni, szükségünk van olyan függvényre, amely visszaadja a DC leíróját (HDC) ennek a függvénynek kell megelőznie bármilyen rajzolási függvényt. A rajzolás végén fel kell szabadítani a leírót. A Windows egyszerre 5 DC-t enged meg. Természetesen nem applikációnként, hanem összesen . A következő tábla összefoglalja a DC elemeit és a default értékeit.

Név

Default érték

Megjegyzés

Background color

fehér

A háttérszíne

Background mode

OPAQUE

A háttér festi a háttérszínnel

Bitmap

Brush

WHITE_BRUSH

ecset (festési) szín

Brush origin

Device origin

Bal felső sarok

Color palette

DEFAULT_PALETTE

Drawig mod

R2_COPYPEN

hogyan kombinálja a pen színét a meglévő színnel

Font

SYSTEM_FONT

Mapping mode

MM_TEXT

1 logikai egység = 1 pixel

Pen

BLACK_PEN

Text color

Black

Viewport origin

Window origin

Eszközkapcsolatot hozhatunk létre:

az érvénytelen területek újrafestésére,

az ablak aktív területének újrafestésére,

a teljes ablak újrafestésére,

az egész képernyő újrafestésére,

nyomtatók használatára,

információ szerzésre

virtuális memória eszközre

metafájl használatára

16.1.1. Az eszközkapcsolat meghatározása

Mint említettem az előbb, a rajzolás általában egy eszközkapcsolat meghatározásával kezdődik. Az eszközkapcsolat meghatározása a céltól függ, vagyis főleg attól, hogy a fent felsorolt 8 eset közül melyiket akarjuk használni. Minden esetben más-más függvényt kell használnunk a kapcsolat létrehozására és megszüntetésére. Általában az ablak illetve képernyő frissítést a WM_PAINT üzenet kezelésében szokás megvalósítani. Tehát minden esetben a rutinunk a következőképpen néz ki:

hdc=létrehozás(...,...,..., );

rajzolás(hdc,....);

kapcsolatfelbontás(...,...);

az érvénytelen területek újrafestése esetén

hdc=BeginPaint(hwnd, &ps);// a ps egy PAINTSTRUCT típusú, amely tartalmazza az újrafestendő terület nagyságát is. A hwnd az ablak leíró.

EndPaint(hwnd, &ps);

az ablak aktív területének újrafestése esetén

hdc = GetDC(hwnd);// ha a hwnd NULL, akkor a képernyő átveszi az aktív ablak szerepét

int ReleaseDC(hwnd, hdc); (az aktív ablak a menü alatti rész). A visszatérési érték 1 ha sikerült a felbontás, különben 0

a teljes ablak területének újrafestése esetén

hdc = GetWindowDC(hwnd);

ReleaseDC(hwnd, hdc); //ilyenkor a nem aktív területeket is újra kell festeni, tehát kezelni kell a WM_NCPAINT üzenetet is

a teljes képernyő újrafestése esetén

hdc = CreateDC(LPCSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszOutput, const void FAR * lpInitData);

DeleteDC(hdc);

lpszDriver : a meghajtóprogramot tartalmazó fájlneve

lpszDevice : az eszköz neve

lpszOutput : a fizikai output eszköz specifikálja pl LPT1:

lpInitData : DEVMODE típusú struktúrára mutató pointer. NULL-t kell használni ha az eszköz nem igényel beállításokat.

a nyomtatás esetén

ugyanaz mint az előző esetben. Majd visszatérünk rá.

a virtuális memória használata



Sok esetben hasznos, ha létrehozunk a memóriában egy a specializált eszközzel kompatibilis memória eszközt. Arra használható, hogy előkészítsük a rajzot a megjelenítése előtt.

hdc = CreateCompatibleDC(hwnd);

DeleteDC(hwnd, hdc);

a metafájl használata

A metafájl nem más, mint grafikus adatok tárolása binárisan kódolt, paraméterezett grafikus rutinok segítségével. A metafájlban tárolt utasítások akármilyen eszközkapcsolatra kiküldhetők

HDC hdc; HMETAFILE hmf;

hdc=CreateMetaFile(NULL);

rajzolás();

hmf=CloseMetaFile(hdc);

hdc=BeginPaint(hwnd, &ps);

PlayMetaFile(hdc,hmf);

DeleteMetaFile(hmf);

EndPaint(hwnd, ps);

16.1.2. A DC elmentése és visszatöltése

Amikor egy HDC-t létrehozunk és beállítjuk annak paramétereit, akkor ezek a beállítások addig érvényesek, amíg nem bontjuk fel a kapcsolatot. A jól beállított HDC elmentésére és visszanyerésére a SaveDC és RestoreDC függvények használhatók.

nSaveDC = SaveDC(HDC hdc);

RestoreDC(hdc, nSaveDC)

Érdemes itt megemliteni, hogy lehetőség van arra, hogy az eszköz lehetőségeit lekérdezzük. Erre a GetDeviceCaps függvény szolgál.

int GetDeviceCaps(hdc, iCapability)

Az iCapability argumentumtól függ az, hogy mit akarunk lekérdezni. Pl. HORZSIZE és VERTSIZE esetén a visszatérési érték a fizikai eszköz vízszintes és függőleges mérete mm-ben. A HORZRES és VERTRES esetén pedig a fizikai eszköz vízszintes és függőleges mérete pixelben.

16.1.3. A DC használata

Ahhoz, hogy tudjunk rajzolni a DC-re, ki kell választani a rajzolási objektumot. Ez azt jelenti, hogy ha a default beállításoktól eltérő stílussal akarunk rajzolni, akkor az adott az objektumot ki kell választani és a paramétereit beállítani. A grafikus objektumok a következők:

Pen (toll)  : meghatározza a vonalak színét, vastagságát és stílusát

Brush(ecset)  : a rajzok feltöltési színét és stílusát állítja be

Font : betűtípus (nagysága, szélessége, vastagsága, stb..)

Palette : szín tömb. A tömb indexe azonosítja a szint.

Bitmap

Region (régiók)

Az adott objektum kiválasztására a SelectObject függvényt használjuk.

Minden objektumra a következő állítások érvényesek:

Az objektum típusa általában az objektum nevéből és előtte egy "H" betűből áll (természetesen nagybetűvel). HPEN, HBRUSH, HFONT, HPALETTE, HBITMAP, HRGN.

Az objektum létrehozásához Createxxxx() függvény létezik. CreatePen, CreateSolidBrush, CreateHatchBrush, CreatePalette, CreateFont, CreateBitmap, CreateRectRgn. Mindegyik függvény visszatérési értékének a típusa megegyezik az objektum típusával. A függvények argumentumai különbözőek, de általában az objektum szükséges beállításait tartalmazzák.

Minden objektum a SelectObject függvénnyel választható ki.

A kiválasztás addig érvényes, amíg nem választunk ki egy másikat.

Minden objektumot törölni kell, ha már nincs szükségünk rá. Erre a DeleteObject függvényt használjuk.

A SelectObject visszatérési értéke mindig az előzőleg beállított objektumot adja vissza. Érdemes ezt a végén visszaállítani.

Minden objektum esetén vannak előre definiált konstansok, amelyeket különböző beállításokra lehet használni. Ezek általában több szóból állnak. A szavak között "_" jel található és az utolsó szó mindig az objektum neve. Pl. BLACK_PEN, WHITE_BRUSH, SYSTEM_FONT, DEFAULT_PALETTE.

16.1.3.1. Pen (Toll)

A toll létrehozásához a

HPEN CreatePen(int style, int width, COLORREF clrref)

függvényt használjuk, ahol a width a vonal vastagságát határozza meg, a COLORREF struktúrának 3 eleme van RGB, ami a színt határozza meg( Lásd példa). A Style pedig meghatározza a toll stílusát ,ez lehet:

PS_SOLID : folytonos vonal

PS_DASH : szaggatott vonal

PS_DOT : pontozott vonal

PS_DASHDOT : pont-vonal

PS_DASHDOTDOT : pont-pont-vonal

PS_NULL : láthatatlan vonal

PS_INSIDEFRAME : ha a vonalvastagság nagyobb mint 1, akkor a folytonos vonal a poligonok belsejébe kerül.

Példa: A következő példa létrehoz kétpontos vastagságú piros szaggatott tollat és ezzel rajzol egy téglalapot.

HDC hdc; HPEN hOldPen, hPen;

hdc=GetDC(hwnd);

hPen= CreatePen(PS_DASH, 2, RGB(255,0,0);

hOldPen=SelectObject(hdc,hPen);

Rectangle(hdc, 20,20,120,120);

SelectObject(hdc,hOldPen);

DeleteObject(hPen);

ReleadeDC(hwnd);

16.1.3.2. Brush (Ecset)

Az ecset létrehozásához a

HBRUSH CreateSolidBrush(COLORREF clrref) illetve

HBRUSH CreateHatchBrush(int nstyle, COLORREF clrref)

függvényt használjuk. A COLORREF a színt határozza meg. Az nstyle a sraffozási stílust határozza meg , ez lehet:

BS_HATCHED  : Az ecset sraffozott területet fest.

BS_HOLLOW  : Hézagosan fest az ecset.

BS_PATTERN  : A memóriában elhelyezett bittérkép definiálja az ecsetet.

BS_SOLID  : Egyszínű területeket fest az ecset.

BS_DIBPATTERN  : Az ecset bittérképe eszköz független módon definiált.

Példa: A következő példa létrehoz kétpontos vastagságú piros szaggatott tollat kék ecsetet és ezzel rajzol egy téglalapot.

HDC hdc; HPEN hOldPen, hPen; HBRUSH hOldBrush, hBrush;

hdc=GetDC(hwnd);

hPen= CreatePen(PS_DASH, 2, RGB(255,0,0);

hOldPen=SelectObject(hdc,hPen);

hBrush=CreateSolidBrush(RGB(0,0,255));

hOldBrush=SelectObject(hdc,hBrush);

Rectangle(hdc, 20,20,120,120);

SelectObject(hdc,hOldPen);

DeleteObject(hPen);

SelectObject(hdc,hOldBrush);

DeleteObject(hBrush);

ReleadeDC(hwnd);

16.1.3.3. Region (Régió)

A régió egy képernyő terület, amely poligonok, téglalapok és ellipszisek kombinációjaként jön létre. Ezt a területet a GDI önállóan használja kifestésre, vágások elvégzésére, stb. Ezt úgyis foghatjuk fel, mintha külön viewport lenne. A GDI ugyanúgy kezeli a régiót mint bármilyen más rajzolási objektumot. Létrehozzuk, használjuk, és töröljük. Létrehozására sok függvény létezik attól függ, hogy milyen alakú régiót akarunk létrehozni. Itt csak egyet említünk a sok közül. Egy téglalap alakú régió létrehozásához a következő függvényt használjuk.

HRGN CreateRectRgn(int nLeft, int nTop, int nRight, int nBottom)

16.1.3.4. Font

Létrehozására a CreateFont függvényt használjuk. Később a szöveg megjelenitésnél részletesebben foglalkozunk vele

16.1.3.5. Palette (Paletta)

Létrehozására a CreatePalette függvényt használjuk. Később részletesebben fejtjük ki

16.2. GDI koordináta rendszerek

A GDI 2 fajta koordináta rendszert támogat: A fizikai és a logikai. Az eszközkapcsolat koordináta rendszer (amit a BeginPaint, GetDC, GetWindowDC, CreateDC függvényekkel hoztuk létre) az eszköztől függ és rögzítve van. Egy adott ablak esetén a képernyőn a kliens terület bal felső sarka képezi az eszközkapcsolat középpontját, az x tengely pozitív iránya jobb felé mutat az y-é pedig lefelé. A mértékegysége képpont vagy pixel. A fizikai rendszernek a középpontja mindig megadható az eszközkapcsolat középpontjához képest. A Windows a grafikus alakzatok megjelenítése előtt a logikai koordinátákat fizikai koordináta rendszerbe képezi le. A GDI függvényekben szereplő koordináták mind logikai rendszerben értendők. Két fogalmat vezetünk be : viewport és window. A viewport a fizikai koordináta rendszert jelenti, egy képernyő téglalap, amelynek az origója az eszközkapcsolathoz képest megadható fizikai egységekben (pixelek). A window egy téglalap alakú képernyő terület, amely logikai rendszer és az egységei logikai egységek. A logikai koordináta rendszer origója a fizikai koordináta rendszerben definiálható. A leképezési mód meghatározására nyolc lehetőség kínálkozik:

leképezési mód

logikai egység

x tengely iránya

y tengely iránya

MM_TEXT(default)

képpont

jobbra

lefelé

MM_LOMETRIC

0,1mm

jobbra

felfelé

MM_HIMETRIC

0,01mm

jobbra

felfelé

MM_LOENGLISH

0,1 inch

jobbra

felfelé

MM_HIENGLISH

jobbra

felfelé

MM_TWIPS

1/1440 inch

jobbra

felfelé

MM_ISOTROPIC

x=y

választható

választható

MM_ANISOTROPIC



x<>y

választható

választható

A leképezési mód a SetMapMode függvény segítségével állítható be.

int SetMapMode(hdc, int fnmode)

a visszatérési értéke a régi mód. A lekérdezése pedig a GetMapMode(hdc) függvénnyel történhet. Beállíthatjuk azt, hogy a fizikai koordináta rendszer (0,0) pontja milyen logikai koordinátának feleljen meg, a SetWindowOrg függvénnyel.

DWORD SetWindowOrg(HDC hdc, int nxOrigin, int nyOrigin)

A SetViewportOrg függvénnyel beállíthatjuk azt, hogy a fizikai koordináta rendszernek, hol legyen a középpontja az eszközkapcsolat középpontjához képest.

DWORD SetViewportOrg(HDC hdc, int nxOrigin, int nyOrigin)

16.3. Rajzolás GDI-vel

A GDI számos rajzolási függvényt tartalmaz. Ezek pontok, vonalak, zárt alakzatok, stb. rajzolására szolgálnak. A GDI függvények közös jellemzője, hogy az első paramétere az eszköz leíró (HDC típusú változó). A pontok rajzolására a SetPixel, a vonalakra, MoveTo és LineTo, körív illetve zárt alakzatokra pedig az : Arc, Circle, Ellipse, Rect, RoundRect, Polygon, stb. függvények alkalmasak.

16.3.1. Megjelenítési mód

Amikor rajzolunk a megjelenítési mód határozza meg azt, hogy milyen módon kombinálódjanak a toll illetve az ecset színek a meglévő színekkel. A Windows 16 előre definiált konstanst használ. Ezek a konstansok R2_-vel kezdődnek. A default érték az R2_COPYPEN.

16.3.2. A színek kezelése a GDI-ben

A színek leírására a Windows API a COLORREF típust definiálja. Ez egy 32 bites érték, amely tartalmazza a szín RGB kombinációit. Az alsó byte reprezentálja a pirost (R) ,utána jön a zöld (G) és utána a kék (B). A felső byte jelzi a szín típusát. (0=explicit RGB szín, 1 =logikai paletta index, 2=RGB a palettából). Tehát ez a szám 0x00bbggrr felépítésű. A Windowsban gyakran használjuk az RGB makrót, amely az RGB intenzitásokból adja vissza a COLORREF (32 bites számot). Pl. Az RGB (255,0,0) a következőt adja vissza: 0x000000ff.

16.3.2.1. A rendszer paletta (system palette)

A VGA, SVGA, XVGA és 8514/A videó kártyák megfelelő jeleket generálnak, hogy sok szín jelenjen meg egy színes monitoron. Az egyszerre megjeleníthető színek száma hardver okok miatt korlátozott. Ezeknek a száma attól függ, hogy hány biten tároljuk a pixel színét. A standard VGA esetén minden pixelt 4 biten tárolunk. Ez azt jelenti, hogy egyszerre 16 szint láthatunk. Az SVGA esetén a bitek száma 8, tehát a színek száma 256. A videó kártya konvertál minden pixel tartalmat egy színre és ez nem más mint egy tábla index. Ezt a táblát szin palettának hívjuk.

A Windows definiál olyan speciális palettát, amelyet rendszer palettának (system palette) hívunk. Ez a paletta 16 előredefiniált színt tartalmaz az EGA és VGA esetén és húszat az SVGA esetén.

16.3.2.2. logikai paletta

A Windows 3.0-tól felfelé a Windows támogatja a logikai paletta fogalmát. Ennek az az előnye, hogy segítségével olyan színeket is meg tudunk jeleníteni, amelyek nincsenek benne a rendszer palettában. A Windows támogatja a kiterjesztett paletta használatát, amely utánozza a hardver palettát. A Windows automatikusan 20 belépést foglal az új palettában, amely megfelel a rendszer palettában levő színeknek. Amikor egy logikai palettát hozunk létre, akkor a Windows leképezi az összes logikai paletta színeit a kiterjesztett palettába a következőképpen:

ha a szín létezik a rendszer palettában, akkor ezt oda képezi le

ha nincsen benne, akkor hozzáadja

ha a rendszer paletta tele lett, akkor a logikai paletta színe a hozzá legközelebb eső szinre lesz leképezve a rendszer palettában.

16.3.3. Szöveg megjelenítése

A szöveg megjelenítése előtt be lehet állítani a háttérszínét (SetBkColor), a szöveg színét (SetTextColor) valamint a font paramétereit (SelectObject(hdc, CreateFont(...)). A szöveg megjelenítéséhez használhatók a következő függvények:

int DrawText( HDC hdc, LPCSTR lpsz, int cb, RECT FAR* lprc, UINT fuFormat)

BOOL TextOut(HDC hdc, int nxStart, int nyStart, LPCSTR lpsz, int cb)

Továbbá használható a TabbedTextOut függvény, amely tabulátorokkal ellátott sztringeket jeleníti meg. A tabulátorok pozíciói logikai koordinátákban adhatók meg. A font létrehozása során testreszabott paraméterű fontot is kialakíthatunk. Megadhatjuk a magasságát, szélességét, a betű dőlési szögét, vastagságát, a szöveg irányát, stb.

16.3.4. A Bitmapek megjelenítése

Gyakran felmerülhet az az igény, hogy egy bitmapet jelenítsünk meg a képernyőn. Természetesen az erőforrások tárgyalásánál említettük azt, hogy a bitmap is egy erőforrás és az erőforrásfájlban kell szerepelnie. Mivel erőforrás, a betöltésére a LoadBitmap függvényt használjuk. A bitmap megjelenítése kicsit több munkát igényel mint az ikoné vagy a kurzoré. A betöltés után a függvény visszatérési értéke egy HBITMAP típusú változó, amely tartalmazza az adott bitmap leíróját. A megjelenítéshez a következő lépések szükségesek.

Eszközkapcsolat létrehozása a képernyőn való megjelenítéshez.

Egy képernyő eszközkapcsolattal ekvivalens memória eszközkapcsolat létrehozása, ami a bitmap tárolására szolgál annak megjelenítéséig.

A bitmap behelyezése a memória eszközkapcsolatba.

A bitmapnek a memória eszközkapcsolatból az ablak eszközkapcsolatba másolása. Ez a lépés eredményezi a bitmap tényleges megjelenítését a képernyőn.

A következő példa szemlélteti a bitmap megjelenítését végző lépéseket:

HBITMAP hBitmap1;

HDC hdc, hmemdc;

hBitmap1=LoadBitmap(hInstance,"MYBITMAP) // lásd resource fejezet

hdc=GetDC(hwnd);

memdc=CreateCompatibleDC(hdc);

SelectObject(hmemdc, hBitmap1);

BitBlt(hdc,10,10,200,200,hmemdc,0,0,SRCCOPY);

ReleaseDC(hwnd,hdc);

DeleteDC(hmemdc);

a CreateCompatibleDC létrehozza az ablak eszközkapcsolattal kompatibilis memória eszközkapcsolatot.

HDC CreateCompatibleDC(HDC)

A SelectObject hozzárendeli a betöltött bitmapet a memória eszközkapcsolathoz. A BitBlt függvény másolja a memória eszközkapcsolat tartalmát az ablak eszközkapcsolatra.

BOOL BitBlt(HDC hDest, int X, int Y, int Width, int Height, HDC hSource, int Sourcex, int Sourcey, DWORD dwRaster)

a dwRaster értéke azt határozza meg, hogy a bitmap bitről bitre adott tartalma milyen módszerrel kerül kirajzolásra. Néhány leggyakoribb értéke a következők:

SCRCOPY  A bitmapet a képernyőre másolja az információ felülírásával

SCRAND  AND kapcsolat

SCRPAINT  OR kapcsolat

SCRINVERT  XOR kapcsolat

Amikor eltakarjuk az ablakot és újból előhozzuk, akkor az ablakunk egy WM_PAINT üzenetet kap. Ezt az üzenetet programból is tudjuk generálni a

BOOL InvalidateRect (HWND hwnd, CONST RECT *lpRect ,BOOL bErase)

függvény segítségével. A WM_PAINT üzenet kezelésében gondoskodnunk kell az újra frissítésről, hogy az ablakunk tartalma újból látható legyen.

Felmerül ilyenkor az a kérdés, vajon minden esetben amikor frissíteni kell az ablakot (pl. egy üzenetablak -MessageBox- után) újra kell-e rajzolnom vagy létezik egy másik módszer, ami esetleg gyorsabb megjelenítést biztosít nekünk?

Az ablak tartalmának visszanyerésére több módszer kínálkozik. Az első módszer az újrarajzolás, ami kis rajzok esetén nem okoz problémát. Ez a módszer nem használható, ha a rajzoló ciklus időigényes. Ilyenkor ajánlatos a virtuális ablakok módszere. Mit is jelent ez? Ez azt jelenti, hogy a rajzolást egyszer hajtjuk végre erre a virtuális ablakra és amikor kell, akkor átmásoljuk ennek az ablaknak a tartalmát a képernyőre. Tehát ez a módszer a következő lépésekből áll:

Létrehozunk egy ablak eszközkapcsolatot, ahova szeretnénk rajzolni.

Ezzel kompatibilis memória eszközkapcsolatot hozunk létre.

Minden rajzolás és más GDI függvényt erre a memória eszközkapcsolatra rajzoljuk

A WM_PAINT üzenet kezelésében ennek a memória eszközkapcsolatnak a tartalmát másoljuk az ablak eszközkapcsolatra.

Mielőtt rátérnénk a virtuális ablak módszerének szemléltetésére szolgáló példára érdemes megemlíteni a PatBlt és CreateCompatibleBitmap függvényeket, amelyekre szükségünk lesz a példa során. A CreateCompatibleBitmap egy eszközkapcsolattal kompatibilis bitmapet hoz létre. Ezt a bitmapet bármelyik CreateCompatibleDC függvénnyel létrehozott memória eszközkapcsolat használhatja. A PatBlt egy ecsettel specifikált minta és szín segítségével ,egy négyszöget tölt ki.

HBITMAP CreateCompatibleBitmap(HDC hdc, int width, int height)

BOOL PatBlt(HDC hdc, int X, int Y, int width, int Height, DWORD dwRaster)

A dwRaster értéke azt adja meg, hogy az ecsetet hogyan kell használni a kitöltés során. A lehetséges értékei:

BLACKNESS  A tartomány fekete (az ecset nem számít)

WHITENESS  A tartomány fehér (az ecset nem számít)

PATCOPY  másolás

PATINVERT  XOR kapcsolat

DSTINVERT  A tartomány invertálódik (az ecset nem számít)

A virtuális ablak módszere esetén a létrehozás általában a WM_CREATE üzenet kezelésében szokás megvalósítani. Természetesen máshol is lehetséges. A virtuális ablakba való rajzolás bárhol lehetséges a programunkban. A megjelenítést a WM_PAINT üzenet kezelésében érdemes megvalósítani.

Példa: a következő példa szemlélteti a virtuális ablak módszer megvalósítását.

// a létrehozás

case WM_CREATE:

// a képernyő koordináták lekérdezése

maxX=GetSystemMetrics(SM_CXSCREEN);

maxY= GetSystemMetrics(SM_CYSCREEN);

// egy képtároló memóriarész létrehozása

hdc=GetDC(hwnd);

hmemdc=CreateCompatibleDC(hdc);

hbit=CreateCompatibleBitmap(hdc,maxX,maxY);

SelectObject(hmemdc,hbit);

hbrush=GetSockObject(WHITE_BRUSH);

SelectObject(hmemdc, hbrush);

PaltBlt(hmemdc,0,0,maxX,maxY,PATCOPY);

ReleaseDC(hwnd,hdc);

break;

// a rajzolás

hPen=CreatePen(PS_SOLID,2,RGB(255,0,0));

SelectObject(hmemdc,hPen);

Rectangle(hmemdc,20,20,200,200);

SetTextColor(hmemdc,RGB(0,0,255));

SetBkColor(hmemdc, RGB(0,255,0));

TextOut("Üdvözlöm a Szoftvertechnika csapatot",36);

//frissítsük a képernyőt

InvalidateRect(hwnd,NULL,1); //a NULL= teljes képernyő frissítés, 1= //törölje előtte a képernyőt

//megjelenítés

case WM_PAINT:

hdc=BeginPaint(hwnd, &ps);

BitBlt(hdc, 0, 0, maxX, maxY, memdc, 0, 0, SRCCOPY);

EndPaint(hwnd, &ps);

break;

16.4. Nyomtatás Windows alatt

A nyomtatás esetén be kell inkludolni a "print.h" fájlt a programunk elején, amelyben printelési rutint írunk. A rajzolás és a nyomtatás hasonló műveletek a Windows alatt csak más eszközre rajzolunk és más driverrel kommunikálunk. A nyomtatás során a GDI modullal és a Print Managerrel állunk kapcsolatban. Miután létrehoztuk az eszközkapcsolatot a majdnem mindegy, hogy hova írányítjuk a rajzolást a képernyőre vagy nyomtatóra.

A VC++ részben a nyomtatást részletesebben fogjuk tárgyalni, ezért itt csak röviden említjuk meg.

Vázlatosan a nyomtatási folyamat a következő lépésekből áll:

A CreateDC függvénnyel hozzuk létre a nyomtató eszközkapcsolat leíróját. Ennek a függvénynek a paramétereit általában a win.ini fájlból lehet kiolvasni. Az ini fájlok kezelésére a GetProfileStringe, WriteProfileString, GetPrivateProfileString WritePrivateProfile függvények használhatók. Ilyenkor a vezérlő program betöltődik a memóriába, ha addig nem volt bent.

Az Escape  függvény meghívása a STARTDOC jelzővel. A nyomtatási folyamat kezdődik. Innentől kezdve minden rajzolási művelet ugyanúgy hajtható végre, mintha a képernyőre rajzolnánk. A nyomtatandó adatok a lemezen metafájl szerkezetben tárolódnak.

Az Escape függvény meghívása a NEWFRAME jelzővel, jelezve a tényleges nyomtatás kezdete

Az Escape függvény meghívása az ENDDOC jelzővel jelezve a nyomtatás végét.

Az Escape függvény szintaxisa a következő:

int Escape(hdc, nEscape, cbInput, lpszInData, lpvOutData)

HDC hdc; /* handle of device context */

int nEscape; /* specifies escape function */

int cbInput; /* size of structure for input */

LPCSTR lpszInData; /* address of structure for input */

void FAR* lpvOutData; /* address of structure for output */

The Escape function allows applications to access capabilities of a particular device that are not directly available through the graphics device interface (GDI). Escape calls made by an application are translated and sent to the driver.

Parameter  Description

hdc Identifies the device context.

nEscape Specifies the escape function to be performed.

cbInput Specifies the number of bytes of data pointed to by the lpszInData parameter.

lpszInData Points to the input structure required for the specified escape.

lpvOutData Points to the structure that receives output from this escape. This parameter should be NULL if no data is returned.

Returns

The return value specifies the outcome of the function. It is greater than zero if the function is successful, except for the QUERYESCSUPPORT printer escape, which checks for implementation only. The return value is zero if the escape is not implemented. A return value less than zero indicates an error.



Errors

If the function fails, the return value is one of the following:

Value Meaning

SP_ERROR General error.

SP_OUTOFDISK Not enough disk space is currently available for spooling, and no more space will become available.

SP_OUTOFMEMORY Not enough memory is available for spooling.

SP_USERABORT User terminated the job through Print Manager.

Az Escape függvény jelzői, nEscape argumentumként:

ABORTDOC

Superseded: use AbortDoc function

BANDINFO

Obsolete in Windows 3.1

BEGIN_PATH

Opens a path

CLIP_TO_PATH

Defines clip region bounded by path

DEVICEDATA

Same as PASSTHROUGH escape

DRAFTMODE

Superseded: Use DEVMODE structure

DRAWPATTERNRECT

Creates pattern on PCL printers

ENABLEDUPLEX

Superseded: use DEVMODE structure

ENABLEPAIRKERNING

Enables or disables kerning

ENABLERELATIVEWIDTHS

Enables or disables relative char widths

ENDDOC

Superseded: Use EndDoc function

END_PATH

Ends a path

ENUMPAPERBINS

Superseded: Use DeviceCapabilities function

ENUMPAPERMETRICS

Superseded: Use DeviceCapabilities function

EPSPRINTING

Allows EPS printing only

EXT_DEVICE_CAPS

Superseded: Use GetDeviceCaps function

EXTTEXTOUT

Superseded: Use ExtTextOut function

FLUSHOUTPUT

Obsolete in Windows 3.1

GETCOLORTABLE

Obsolete in Windows 3.1

GETEXTENDEDTEXTMETRICS

Gets extended text metrics

GETEXTENTTABLE

Superseded: Use GetCharWidth function

GETFACENAME

Gets face name of current font

GETPAIRKERNTABLE

Gets kerning-pair structures

GETPHYSPAGESIZE

Gets size of physical page

GETPRINTINGOFFSET

Gets offset where printing starts

GETSCALINGFACTOR

Gets scaling factors for printer

GETSETPAPERBINS

Superseded: Use DeviceCapabilities function

GETSETPAPERMETRICS

Superseded: Use ExtDeviceMode function

GETSETPRINTORIENT

Superseded: Use ExtDeviceMode function

GETSETSCREENPARAMS

Gets or sets halftoning parameters

GETTECHNOLOGY

Gets technology type

GETTRACKKERNTABLE

Gets track-kerning table

GETVECTORBRUSHSIZE

Gets size of plotter brush

GETVECTORPENSIZE

Gets size of plotter pen

MFCOMMENT

Adds comment to metafile

MOUSETRAILS

Enables or disables mouse trails

NEWFRAME

Superseded: Use StartPage and EndPage functions

NEXTBAND

Finished band, get next band

PASSTHROUGH

Sends data directly to printer

POSTSCRIPT_DATA

Same as PASSTHROUGH escape

POSTSCRIPT_IGNORE

Flag for suppressing output

QUERYESCSUPPORT

Queries whether escape is supported

RESTORE_CTM

Restores current transformation matrix

SAVE_CTM

Saves current transformation matrix

SELECTPAPERSOURCE

Superseded: Use DeviceCapabilities function

SETABORTPROC

Superseded: Use SetAbortProc function

SETALLJUSTVALUES

Superseded: Use ExtTextOut function

SET_ARC_DIRECTION

Sets arc-drawing direction

SET_BACKGROUND_COLOR

Sets and gets background color

SET_BOUNDS

Sets bounding rectangle

SET_CLIP_BOX

Sets or restores clipping rectangle

SETCOLORTABLE

Sets RGB color-table entry

SETCOPYCOUNT

Superseded: Use ExtDeviceMode function

SETKERNTRACK

Sets kerning track

SETLINECAP

Sets line-end style

SETLINEJOIN

Sets line-intersection style

SETMITERLIMIT

Sets line-intersection bevel angle

SET_POLY_MODE

Sets mode for Polygon and Polyline functions

SET_SCREEN_ANGLE

Sets current screen angle

SET_SPREAD

Sets trapping for spot separations

STARTDOC

Superseded: Use StartDoc function

STRETCHBLT

Superseded: Use StretchBlt function

TRANSFORM_CTM

Modifies current transformation matrix




Document Info


Accesari: 1258
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2025 )