Filozofia GDI
Utilizarea graficii sub Windows se realizeaza cu sprijinul direct al functiilor exportate din modulul GDI.EXE. Dar nu totul se realizeaza de aici. Unele actiuni sunt transmise diferitelor drivere care coopereaza cu acesta iar in unele cazuri regasim puncte de intrare ale unor functii utilizate in grafica chiar in modulul k9u19ub
USER.EXE. Suportul major pentru executia graficii e dat de driverele atasate
periferiei de iesire, in special pentru ecran si imprimanta. Datorita acestei
structuri pe doua nivele Windows poate determina, interogand driverul, care
sunt posibilitatile acestuia, asa incat pentru o anumita operatie grafica sa se ocupe nemijlocit sau sa cedeze driverului executia daca acesta e capabil de ea.
Deoarece exista o multitudine de ofertanti pe piata perifericelor si foarte putine standarde, GDI-ul trebuie sa functioneze intr-o maniera cat mai independenta de dispozitivul efectiv din configuratia calculatorului, acesta fiind unul din principalele aspecte care stau la baza conceptiei sale. Acest
aspect apropie GDI-ul de limbajele grafice independente de suport. Dar ceea
ce-l particularizeaza e forta operatiilor de manipulare la nivel de pixel, deci operatii in rastru.
Lumea dispozitivelor grafice se imparte in doua mari categorii: cele care opereaza in rastru si cele vectoriale. Majoritatea dispozitivelor conectate la PC-uri sunt de tip rastru, deci reprezinta imaginile printr-o matrice de
puncte. Din aceasta categorie fac parte adaptoarele video, imprimantele matriceale sau laser. A doua categorie e reprezentata doar de plotere.
Desi majoritatea dispozitivelor de iesire sunt de tip rastru, limbajele grafice se bazeaza doar pe vectori. GDI-ul face figura aparte intre acestea
operand atat vectorial cat si in rastru, din acesta privinta el asemanindu-se
cu pozitia oarecum particulara a limbajului C intre limbajele de nivel inalt, el
fiind dotat cu toate facilitatile acestei categorii de limbaje, dar avand in
plus si functii la fel de puternice si rapide ca un limbaj masina.
Si la nivelul sistemului de coordonate GDI-ul e deosebit. Avem posibilitatea sa lucram grafic in nu mai putin de 8 sisteme diferite intre care
exista si cele bazate pe pixeli.
Unii programatori considera ca a lucra la nivel de pixeli inseamna pierderea portabilitatii, dar acest lucru e fals caci GDI-ul a introdus si posibilitatea unui mod de lucru in raster independent de dispozitiv. Pentru
aceasta limbajul grafic al interfetei trebuie sa ofere facilitati de determinare a capacitatilor specifice ale dispozitivelor grafice atasate. La acest capitol
GDI-ul este f. bun, lucru ce va reiesi din exemplul de program inserat in acest laborator.
Totusi GDI-ul Windows-ului nu e inca un limbaj grafic complet. Trebuie stiut ca exista si limitari inerente, de altfel, oricarui inceput. Abia la versiunea 3.1 au aparut: suportul pentru curbe Bezier si tehnologia TrueType,
in timp ce alte facilitati visate de programatori cum ar fi suportul pentru grafica
3D si animatie urmeaza sa vina. De asemenea cu tote ca exista limbaje grafice
ce lucreaza intr-un sistem de coordonate exprimate prin reali, GDI-ul deocamdata
lucreaza, din motive de performanta, cu intregi pe 16 biti cu semn.
Device context DC
Atunci cind dorim sa desenam ceva la un periferic grafic, in primul rand trebuie sa obtinem din partea Windows-ului contextul grafic al acestuia,
Device Context (DC) intr-un handle. Acest handle desemneaza zona de memorie
ce contine informatiile despre "atributele curente" ale contextului precum
si capacitatile lui.
Obtinerea handle-ului de DC, pe care in continuare il vom numi hDC, poate fi facuta sub Windows in mai multe moduri.
*BeginPaint-EndPaint
Cel mai firesc este sa desenam atunci cand fereastra primeste mesajul
WM_PAINT.In acest caz procesarea mesajului va cuprinde:
A
PAINTSTRUCT ps; hdc=BeginPaint(hWnd,&ps);
// aici desenez
EndPaint(hwnd,&ps);
S
Functia BeginPaint incarca structura PAINTSTRUCT ce contine o suma de informatii considerate utile la tratarea WM_PAINT-ului. Intre acestea se gaseste dreptunghiul de clipping al zonei invalidate -deci cea care se presupune ca trebuie repictata. Handle-ul returnat de functie, hdc, permite desenarea doar in acest dreptunghi, asa incat daca se doreste pictarea intregii
ferestre este indicata apelarea functiei InvalidateRect asa cum se poate vedea
in sursa. Inainte de a termina procesarea lui WM_PAINT trebuie apelata functia
EndPaint care printre altele va elibera contextul dat de BeginPaint.
GET(WINDOW)DC-RELEASEDC
Putem sa desenam si pe parcursul procesarii altor mesaje. In acest caz putem obtine handle-ul contextului dispozitivului prin GetDC(hWnd), care returneaza
hDC-ul zonei client a ferestrei sau prin GetWindowDC(hWnd), care returneaza
hDC-ul intregului spatiu al ferestrei, deci inclusiv zona non-client. Dupa operatiile grafice pe care le-am facut contextul grafic trebuie eliberat prin ReleaseDC(hWnd,hDC).
CREATE(COMPATIBLE)DC-DELETEDC
Functiile parcurse pina aici regaseau contextul grafic asociat unei ferestre.
Putem insa obtine contextul general al unui dispozitiv prin functia
CreateDC(lpszDriver,lpszDevice,lpszOutput,lpData) cu care putem obtine contextul ecranului de exemplu:
hDC=CreateDC("DISPLAY",NULL,NULL,NULL);
Sirurile de caractere pentru parametrii acestei functii pot fi luati din sectiunile fisierului de initializari al Windows-ului, WIN.INI. Dupa incheierea lucrului contextul va trebui eliberat cu DeleteDC(), daca nu mai este necesar.
Cu aceasta operatie va fi eliberata si memoria alocata pentru context (aprox
800 octeti) nu numai invalidarea handle-ului lui.
De multe ori se intilneste situatia necesitatii unui context similar unui dispozitiv. Cazul cel mai tipic este transferul unui bitmap, care nu se poate
face direct din resurse in ecran ci doar prin intermediul memoriei, unde trebuie
sa creem un context compatibil cu cel al ferestrei in care vrem sa plasam desenul
.
Pentru aceasta folosim :
hMemDC=CreateCompatibleDC(hDC);
// operatii grafice
DeleteDC(hMemDC);
S-a introdus si in exemplul de program propus o exemplificare a acestei tehnici.
CreateMetafile-CloseMetafile
Un metafile este o colectie de apeluri la GDI, codificate intr-o forma binara. Este deci un fisier binar in limbaj GDI. Putem deschide un astfle de
fisier, moment din care toate apelurile la GDI vor fi copiate si in el, dupa care la inchidere vom obtine un handle al acestuia. Fisierul metafile poate fi apoi "derulat", pentru a relua executia pe care a inregistrat-o.
Vom reveni in viitor asupra acestor fisiere.
CreateIC
Atunci cind avem nevoie doar de informatii continute in contextul grafic fara sa trebuiasca sa desenam, putem sa le obtinem in modul urmator:
hdcInfo=CreateIC(lpszDriver,lpszDevice,lpszOutput,lpData);
// alte instructiuni
DeleteDC(hdcInfo);
Capabilitatile unui DC
Informatiile legate de diferitele aspecte functionale ale dispozitivelor grafice pot fi cerute de la GDI cu ajutorul functiei GetDeviceCaps(hDC,nIndex) unde nIndex specifica facilitatea dorita. Sursa prezentata insista asupra acestei
functii si a diferitelor informatii obtinute prin intermediul ei.
DEVCAPS.C
/****************************************************************************
Afisarea informatiilor despre capabilitatile dispozitivelor grafice
****************************************************************************/
#include <windows.h>
#include<string.h>
#include<stdio.h>
#include"devcaps.h"
void DoBasicInfo(HDC,HDC,short,short); void DoOtherInfo(HDC,HDC,short,short); voidDoBitCodeCaps(HDC,HDC,short,short,short); long FAR PASCAL WndProc(HWND,WORD,WORD,LONG); int PASCAL WindMain(HANDLE hInstance, HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
A static char szAppNameai = "DevCaps";
HWND hwnd;
MSG msg;
WNDCLASS wndclass; if(!hPrevInstance) A
wndclass.style =CS HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc =WndProc;
wndclass.cbClsExtra =0;
wndclass.cbWndExtra =0;
wndclass.hInstance =hInstance;
wndclass.hIcon =LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor =LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground =GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName =szAppName;
wndclass.lpszClassName =szAppName;
RegisterClass(&wndclass);
S hwnd=CreateWindow(szAppName,"Capabilitatile disp. grafice",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while(Getmessage(&msg,NULL,0,0)) A
TranslateMessage(&msg);
DispatchMessage(&msg);
S return msg.wParam;
S
/***********************************************************************/
HDC GetPrinterIC()
A char szPrintera64i; char *szDevice,*szDriver,*szOutput;
GetProfileString("windows","device"," ",szPrinter,64); if((szDevice=strtok(szPrinter,"."))&&
(szDriver=strtok(NULL,","))&&
(szOutput=strtok(NULL,","))) return CreateIC(szDriver,szDevice,szOutput,NULL0); return NULL;
S
/************************************************************************/ long FAR PASCAL WndProc(HWND hwnd,WORD message, WORD wParam, LONG lParam)
A static short cxChar, cyChar, nCurrentDevice = IDM_SCREEN, nCurentInfo = IDM_BASIC; static HANDLE hBmpScr, hBmpPrn;
HDC hdc, hdcInfo;
HMENU bMenu;
PAINTSTRUCT ps;
TEXTMETRIC tm;
switch(message) A case WM_CREATE: hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(hdc,&tm); cxChar = tm.tmAveCharWidth; cyChar = tm.Height + tm.tmExternalLeading; hBmpScr =LoadBitmap (GetWindowWord (hwnd,GWW_HINSTANCE ) , "screen"); hBmpPrn =LoadBitmap (GetWindowWord (hwnd,GWW_HINSTANCE ) , "printer");
ReleaseDC (hvnd, hdc); return 0; case WM_COMMAND; hMenu = GetMenu (hwnd); switch (wParam) A case IDM_SCREEN; case IDM_PRINTER;
CheckMenuItem (hMenu, nCurrentDevice, MF_UNCHECKED); nCurrentDevice = wParam;
CheckMenuItem (hMenu, nCurrentDevice, MF_CHECKED);
InvalidateRect (hwnd, NULL, TRUE);
RETURN 0; case IDM_CURVE; case IDM_LINE; case IDM_POLY; case IDM_TEXT;
CheckMenuitem (hMenu, nCurrentInfo, MF_UNCHECKED); nCurrentInfo = wParam;
CheckMenuItem(hMenu, nCurrentInfo, MF_CHECKED);
InvalidateRect (hwnd, NULL, TRUE); return 0;
S break; case WM_DEVMODECHANGE;
InvalidateRect (hwnd, NULL, TRUE); return 0; case WM_PAINT:
A HDC hMemDC;
HANDLE hbmpOld;
BITMAP bm;
RECT rc; hdc = BeginPaint (hwnd, &ps);
SelectObject(hdc, GetStockObject (SISTEM_FIXED_FONT)); hMemDC = CreateCompatibleDC( hdc ); if(nCurrentDevice = IDM_SCREEN) A hdcInfo = CreateIC("DISPLAY" , NULL, NULL, NULL); hbmpOld = SelectObject(hMemDC, hBmpScr);
GetObject(hBmpScr, sizeof (BITMAP) , &bm);
SelseA hdcInfo = GetPrinterIC(); hbmpOld = SelectObject (hMemDC, hBmpPrn);
GetObject (hBmpPrn, sizeof (BITMAP) , &bm);
S if (hdcInfo) A
GetClientRect( hwnd, &rc );
BitBlt(hdc, rc.right - bm.bmWidth, 0,bm.bmWidth, bm.bmHeight,hMemDC,
0 ,0, SRCCOPY);
SelectObject(hMemDC, hbmpOld);
DeleteDC(hMemDC); switch(nCurrentInfo) A case IDM_BASIC:
DoBasicInfo (hdc, hdcInfo, cxChar, cyChar); break; case IDM_OTHER:
DoOtherInfo (hdc, hdcInfo, cxChar, cyChar); break; case IDM_CURVE: case IDM_LINE: case IDM_POLY: case IDM_TEXT:
DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar, nCurrentInfo - IDM_CURVE); break;
S DeleteDC(hdcInfo);
S EndPaint(hwnd, &ps);
S return 0 ; case WM_DESTROY :
DeleteObject( hBmpScr );
DeleteObject( hBmpPrn );
PostQuitMessage(0); return 0 ;
S return DefWindowProc(hwnd, message, wParam, lParam);
S
/****************************************************************************/ typedef struct A short nMask; char *szMask; char *szDesc;
S BITS; void DoBasicInfo (HDC hdc, HDC hdcInfo, short cxChar, short cyChar)
A static struct A short nIndex; char *szDesc;
S info a i = A
HORZSIZE, "HORZSIZE Latime in milimetri:",
VERTSIZE, "VERTSIZE Inaltime in milimetri:",
HORZRES, "HORZRES Latime in pixeli:",
VERTRES, "VERTRES Inaltime in linii rastru:",
BITSPIXEL, "BITSPIXEL Biti de culoare/pixel:",
PLANES, "PLANES Numar plane de culoare:",
NUMBRUSHES, "NUMBRUSHES Numar de pensule:",
NUMPENS, "NUMPENS Numar de penite:",
NUMMARKERS, "NUMMARKERS Numar de marcaje:",
NUMFONTS, "NUMFONTS Numar de fonturi:",
NUMCOLORS, "NUMCOLORS Numar de culori:",
PDEVICESIZE, "PDEVICESIZE Marimea acestei structuri:",
ASPECTX, "ASPECTX Latime relativa pixel:",
ASPECTY, "ASPECTY Inaltime relativa pixel:",
ASPECTXY, "ASPECTXY Diagonala relativa pixel:",
LOGPIXELSX, "LOGPIXELSX Puncte orizontale pe inch:",
LOGPIXELSY, "LOGPIXLSY Puncte verticale pe inch:",
SIZEPALETTE, "SIZEPALETTE Numarul de intrari/paleta:",
NUMRESERVED, "NUMRESERVED Intrari de paleta rezervate:",
COLORRES, "COLORRES Rezolutia actuala a culorii:",
S; char szBuffera80i; short i; for(i = 0; i < sizeof info / sizeof info a0i ; i++)
TextOut(hdc, cxChar, i*cyChar, szBuffer, sprintf(szBuffer,
"%-40s%8d",infoaii.szDesc,GetDeviceCaps(hdcInfo,infoaii.nIndex)));
S void DoOtherInfo(HDC hdc, HDC hdcIfo, short cxChar, short cyChar)
A static BITS clipai = A
CP_RECTANGLE, "CP_RECTANGLE", "clipping la dreptunghi:"
S; static BITS rasterai = A
RC_BITBLT, "RC_BITBLT", "Suporta BitBlt:",
RC_BANDING, "RC_BANDING", "Necesita suport banding:",
RC_SCALING, "RC_SCALING", "Necesita suport de scalare:",
RC_BITMAP64, "RC_BITMAP64", "Suporta bitmap-uri > 64K:",
RC_GDI20-OUTPUT,"RC_GDI20_OUTPUT", "Apeluri compatib. v2.0:",
RC_DI_BITMAP, "RC_DI_BITMAP", "Suporta DIB-uri :",
RC_PALETTE, "RC_PALETTE", "Suporta palete:",
RC_DIBTODEV, "RC_DIBTODEV", "Suporta conversia bitmap:",
RC_BITFONT, "RC_BIGFONT", "Suporta font-uri > 64K:",
RC_STRETCHBLT, "RC_STRETCHBLT", "Suporta stretchBlt:",
RC_FLOODFILL, "RC_FLOODFILL", "Suporta FloodFill:",S; static char *szTech ai = A
"DT_PLOTTER (ploter,vectorial)",
"DT_RASDISPLAY (ecran,rastru)",
"DT_RASPRINTER (imprimanta,rastru)",
"DT_RASCAMERA (camera video, rastru)",
"DT_CHARSTREAM (sir caractere,PLP)",
"DT_METAFILE (metafile,VDM)",
"DT_DISPFILE (display-file)" S; char szBuffer a80i; short i;
TextOut (hdc, cxChar, 0, szBuffer, sprintf (szBuffer, "% -16s % -04xh",
"VERSIUNE :, GetDeviceCaps (hdcInfo, DRIVERVERSION) ));
TextOut (hdc, cxChar, 2*cyChar, szBuffer, sprintf (szBuffer, "%-16s%-20s",
"TEHNOLOGIE:" , szTechaGetDeviceCaps (hdcInfo, TECHNOLOGY) i));
TextOut (hdc, cxChar, 4*cyChar, szBuffer, sprintf (szBuffer, "CLIPCAPS (Capabilitati de clipping)")); for (i=0 ;i < sizeof clip / sizeof clip a0i ; i++)
TextOut(hdc, 9*cxChar, (i+6)*cyChar, szBuffer, sprintf (szBuffer, "%-16s%-28s %3s", clipaii.szMask, clipaii.szDesc,
GetDeviceCaps (hdcInfo, CLIPCAPS) & clipaii. nMask ? "Da": "Nu"
));
TextOut (hdc, cxChar, 8*cyChar, szBuffer, sprintf (szBufer, "RASTERCAPS (Capabilitati de rastru)" )); for (i=0; i< sizeof raster a0i ;i++)
TextOut (hdc, 9* cxChar, (i+10) *cyChar, szBuffer, sprintf (szBuffer, "%-16s %-28s %3s", rasteraii. szMask, rasteraii. szDesc, GetDeviceCaps (hdcInfo, RASTERCAPS ) & rasteraii. nMask ?"Da" :"Nu" ));
S void DoBitCodedCaps (HDC hdc, HDC hdcInfo, short cxChar, short cyChar, short
nType)
A static BITS curvesai=A
CC_CIRCLES, "CC_CIRCLES", "cercuri:",
CC_PIE, "CC_PIE", "placinte:",
CC_CHORD, "CC_CHORD", "arce intinse:",
CC_ELLIPSES, "CC_ELLIPSES", "elipse:",
CC_WIDE, "CC_WIDE", "chenare ample:",
CC_STYLED, "CC_STYLED", "chenare cu stil:",
CC_WIDESTYLED, "CC_WIDESTYLED", "chenare ample cu stil:",
CC_INTERIORS, "CC_INTERIORS", "interioare:" S ; static BITS linesai=A
LC_POLYLINE, "LC_POLYLINE", "polilinii:",
LC_MARKER, "LC_MARKER", "markeri:",
LC_POLYMARKER, "LC_POLYMARKER", "polymarkeri:",
LC_WIDE, "LC_WIDE", "linii ample:",
LC_STYLED, "LC_STYLED", "linii cu stil:",
LC_WIDESTYLED, "LC_WIDESTYLED", "linii ample cu stil:",
LC_INTERIORS, "LC_INTERIORS", "interioare:" S ; static BITS POLYai=A
PC_POLYGON, "PC_POLYGON", "polilinii:",
PC_RECTANGLE, "PC_RECTANGLE", "dreptunghiuri:",
PC_WINDPOLYGON, "PC_WINDPOLYGON", " fill dupa contur poligonal:",
PC_SCANLINE, "PC_SCANLINE", "linii ecran:",
PC_WIDE, "PC_WIDE", "chenare ample:",
PC_STYLED, "PC_STYLED", "chenare cu stil:",
PC_WIDESTYLED, "PC_WIDESTYLED", "chenare ample cu stil:",
PC_INTERIORS, "PC_INTERIORS", "interioare:" S ; static BITS textai=A
TC_OP_CHARACTER, "TC_PC_CHARACTER", "caracter precis la iesire:",
TC_OP_STROKE, "TC_PC_STROKE", "caracter precis la tiparire:",
TC_CP_STROKE, "TC_CP_STROKE", "clipping precis la tiparire:",
TC_CR_90, "TC_CR_90", "rotatia caracterului cu 90 grade:",
TC_CR_ANY, "TC_CR_ANY", " orice rotatie:",
TC_SF_X_WINDEP, "TC_SF_F_WINDEP", "scalare independenta pe x, y, :",
TC_SA_DOUBLE, "TC_SA_DOUBLE", "ingrosare (bold) la scalare:2,
TC_SA_INTEGER, "TC_SA_INTEGER", "multipl.intreaga la scalare:",
TC_SA_CONTIN, "TC_SA_CONTIN", "orice multipl.scalare exacta:",
TC_EA_DOUBLE, "TC_EA_DOUBLE", "caractere groase(bold):",
TC_IA_ABLE, "TC_IA_ABLE", "transformare in cursive:",
TC_UA_ABLE, "TC_UA_ABLE", "transformare in sublinitate:",
TC_SO_ABLE, "TC_SO_ABLE", "transformare in taiate:",
TC_RA_ABLE, "TC_RA_ABLE", "font rastru:",
TC_VA_ABLE, "TC_VA_ABLE", "font vectorial:" S; static struct A short nINDEX; char *szTitle;
BITS (*pbits)ai; short nSize;
S bitinfoai=A
CURVECAPS, "CURVCAPS (Capabilitati pentru curbe)",
(BITS (*) ai) curves, sizeof curves / sizeof curves a0i,
LINECAPS, "LINECAPS (Capabilitati pentru linii)",
(BITS (*) ai) lines, sizeof lines / sizeof lines a0i,
POLYGONALCAPS, "POLYGONALCAPS (Capabilitati pentru polgoane)",
(BITS (*) ai) poly, sizeof poly / sizeof poly a0i,
TEXCAPS, "TEXTCAPS (Capabilitati pentru texte)",
(BITS (*) ai) text, sizeof text /sizeof text a0i, static char szBuffer a80i
Bits (*pbits ai = bitinfo anTypei.pbits; short nDevCaps = GetDeviceCaps (hdcInfo, bitinfoanTypei.nIndex); short i;
TextOut (hdc, cxChar, 2*cyChar, bitinfoanTypei.szTitle, strlen(bitinfoanTypei.szTitle)); for(i=0; i<bitinfo anTypei.nSize;i++)
TextOut(hdc, cxChar, (i + 4)*cyChar, szBuffer, sprintf(szBuffer,
"%-16s %s %-32s", (*pbits)aii.szMask, "Poate face",
*pbits)aii.szDeac, nDevCaps & (*pbits)aii.nMask? "Da":"Nu"));
S
----------------------------------------------------------------------
DEVCAPS.H
#define IDM_SCREEN 1
#define IDM_PRINTER 2
#define IDM_BASIC 3
#define IDM_OTHER 4
#define IDM_CURVE 5
#define IDM_LINE 6
#define IDM_POLY 7
#define IDM_TEXT 8
--------------------------------------------------------------------- DEVCAPS.RC
DEVCAPS MENU DISCARDABLE
BEGIN
POPUP "&Dispozitiv"
BEGIN
MENUITEM "&Ecran", IDM_SCREEN, CHECKED
MENUITEM "&Imprimanta", IDM_PRINTER
END
POPUP "&Capabilitati"
BEGIN
MENUITEM "&Informatii de baza", IDM_BASIC, CHECKED
MENUITEM "&Alte informatii", IDM_OTHER
MENUITEM "Despre &Curbe", IDM_CURVE
MENUITEM "Despre &Linii", IDM_LINE
MENUITEM "Despre &Poligoane", IDM_POLY
MENUITEM "Despre &Texte", IDM_TEXT
END
END
screen BITMAP DISCARDABLE "ECRAN.BMP" printer BITMAP DISCARDABLE "PRINTER.BMP"
----------------------------------------------------------------------
Intre informatiile despre dispozitive, locul cel mai important il ocupa cele de marimea spatiului grafic si rezolutia acestuia, precum si marimea elementului de imagine-pixelul. Iata in continuare care sint aceste valori pentru doua adaptoare
grafice foarte populare:
ÚAAAAAAAAAAAAAAAAAAAAAAAAAA¿
³ Parametru ³ EGA ³ VGA ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
³ HORZSIZE(mm) ³ 240 ³ 208 ³
³ VERTSIZE(mm) ³ 175 ³ 156 ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
³HORZRES(pixel)³ 640 ³ 640 ³
³VERTRES(pixel ³ 350 ³ 480 ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
³ ASPECTX ³ 38 ³ 36 ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
³ ASPECTY ³ 48 ³ 36 ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
³ ASPECTXY ³ 61 ³ 51 ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
³ LOGPIXELX ³ 96 ³ 96 ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAa
³ LOGPIXELY ³ 72 ³ 96 ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAÙ
Primele doua valori specifica dimensiunea standard a monitoarelor legate la un astfel de adaptor (marime care pentru o configuratie specifica poate fi
alta). Urmatoarele doua dau marimea zonei utile, in pixeli, aceste valori fiind identice cu cele returnate de o alta functie, GetSystemMetrics. Valorile corespunzatoare indecsilor ASPECTX, ASPECTY, ASPECTXY, dau dimensiunea relativa a pixelului pe orizontala, verticala si diagonala. Ultimele doua valori reprezinta
numarul de pixeli pe un inch logic, acesta fiind diferit de cel fizic (25,4
mm)
Aceasta diferentiere se face datorita ecranului propriu-zis pe care trebuie
afisata o imagine putin marita, pentru ca programele care lucreaza in modul WYSIWYG
(What
You See Is What You Get) sa poata afisa o imagine de o acuratete multumitoare.
Putem masura cu rigla pe ecran si vom constata ca inch-ul de pe o rigla marcata
(de exemplu in Word) este de aproximativ o data si jumatata mai mare.
GetDeviceCaps ne spune cite culori suporta dispozitivul grafic. Unele adaptoare construiesc imaginea color folosind mai multe plane de culoare, fiecare corespunzind de obicei unei culori pure. In afara de acest aspect, pentru a
afla organizarea memoriei video mai trebuie sa stim citi biti sint alocati pe pixel
(in fiecare din posibilele plane de culoare). Numarul de culori poate fi atunci calculat in felul urmator:
nPlane = GetDeviceCaps(hDC, PLANES); nBitiPix = GetDeviceCaps(hDC, BITSPIXEL); nCulori = 1<<(nPlane*nBitiPix);
Aceasta valoare poate fi diferita de cea obtinuta ca in sursa:
nCulori = GetDeviceCaps(hDC, NUMCOLORS);
Pentru plottere nPlane=nBitPix=1 deci am obtine doar culori, insa plotterele pot avea mai multe penite asa incit acest numar va fi returnat pentru indexul
NUMCOLORS. De asemenea pentru adaptoarele video care pot sa lucreze pe baza
unei pelete incarcabile, de exemplu IBM8514/A, valorile obtinute sint 256 culori
pentru prima metoda deoarece adaptorul are 1 plan si 8 biti/pixel, si 20 culori daca
folosim metoda a doua. Cele 20 de culori sint rezervate pentru paleta Windows,
alte aplicatii care doresc pot sa selecteze la un moment dat oricare alta culoare
din cele 236 ramase. Nu toate culorile sint pure. O culoare impura corespunde
unei combinatii de culori pure pe care Windows o construieste intr-un aranjament
de puncte. Aceasta metoda de a afisa nuante ce nu pot fi afisabile se numeste dithering.
Culorile se exprima de obicei prin trei grupuri de cifre, indicindu-se pentru
fiecare culoare de compunere care este aportul ei (de exemplu Red = 192, Green
= 192 ,Blue = 192 dau culoarea gri deschis, culoare pura folosita pentru "fata"
butoanelor). Pentru a afla culoarea pura cea mai apropiata de un anumit cod,
putem utiliza functia:
rgbPureColor=NearestColor(hDC, rgbCuloare)
Atributele unui DC
Atributele contextului grafic al unui dispozitiv sint de fapt informatiile care guverneaza modul de executare a diferitelor functii grafice la acel dispozitiv.
Atunci cind un program obtine handle-ul unui DC, Windows aloca automat o valoare
implicita acestor atribute asa incit functiile grafice sa fie operabile. Aplicatia
poate sa consulte valoarea unui atribut sau sa-i modifice valoarea, functiile
corespunzatoare fiind prezentate in tabelul ce urmeaza:
ÚAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA¿
³ Atribut ³ Val implicita ³ F-ctii de consultare ³ F-ctii
de modificare ³
ÚAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³1 ³ Mod mapare ³ MM_TEXT ³ GetMapMode ³ SetMapMode
³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³2 ³ Origine ³ (0,0) ³ GetWindowOrg ³ SetWindowOrg
³
³ ³ Window ³ ³ OffsetWindowOrg ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³3 ³ Origine ³ (0,0) ³ GetViewportOrg ³ SetViewportOrg
³
³ ³ ViewPort ³ ³ OffsetViewportg ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³4 ³ Extindere ³ (1,1) ³ GetWindowExt ³ SetWindowExt
³
³ ³ Window ³ ³ SetMapMode ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³5 ³ Extindere ³ (1,1) ³ GetViewportExt ³ SetViewportExt
³
³ ³ ViewPort ³ ³ SetMapMode ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³6 ³ Penita ³ BLACK_PEN ³ SelectObject ³ CreatePen
³
³ ³ ³ ³ ³ CreatePenIndirect ³
³ ³ ³ ³ ³ SelectObject ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³7 ³ Pozitie ³ (0,0) ³ GetCurrentPosition ³ LineTo
³
³ ³ penita ³ ³ ³ MoveTo ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³8 ³ Pensula ³ WHITE_BRUSH ³ SelectObject ³ CreateBrushIndirect
³
³ ³ ³ ³ ³ CreateDIBPatternBrush³
³ ³ ³ ³ ³ CreateHatchBrush ³
³ ³ ³ ³ ³ CreatePatternBrush ³
³ ³ ³ ³ ³ CreateSolidBrush ³
³ ³ ³ ³ ³ SelectObject ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³9 ³ Origine ³ (0,0) coord de³ GetBrushOrg ³ SetBrushOrg
³
³ ³ pensula ³ ecran ³ ³ UnrealizeObject ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³10³ Bitmap ³ ³ SelectObject ³ CreateBitmap ³
³ ³ ³ ³ ³ CreateBitmapIndirect ³
³ ³ ³ ³ ³CreateCompatibleBitmap³
³ ³ ³ ³ ³ SelectObject ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³11³ Font ³ SYSTEM_FONT ³ SelectObject ³ CreateFont
³
³ ³ ³ ³ ³ CreateFontIndirect ³
³ ³ ³ ³ ³ SelectObject ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³12³ Paleta de ³DEFAULT_PALETTE³ SelectPalette ³ CreatePalette
³
³ ³ culori ³ ³ ³ RealizePalette ³
³ ³ ³ ³ ³ SelectPalette ³
³ ³ ³ ³ ³ UnrealizeObject ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³13³ Regiune ³ Suprafata ³ GetClipBox ³ ExcludeClipRect
³
³ ³ clipping ³ ecranului ³ PtVisible ³ IntersectClipRect
³
³ ³ ³ ³ RectVisible ³ OffsetClipRgn ³
³ ³ ³ ³ ³ SelectClipRgn ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³15³ Mod de ³STRETCH_ANDSCANS³ GetStretchBltMode ³
SetStretchBltMode ³
³ ³ scalare ³ ³ ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³16³ Umplere ³ ALTERNATE ³ GetPolyFillMode ³ SetPolyFillMode
³
³ ³ poligon ³ ³ ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³17³ Spatiere ³ 0 ³ GetTextCharacterExtra³ SetTextCharacterExtra³
³ ³ caractere ³ ³ ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³18³ Culoare ³ Negru ³ GetTextColor ³ SetTextColor
³
³ ³ text ³ ³ ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³19³ Culoare ³ Alb ³ GetBkColor ³ SetBkColor ³
³ ³ fundal ³ ³ ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
³20³ Afisare ³ OPAQUE ³ GetBkMode ³ SetBkMode ³
³ ³ fundal ³ ³ ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAÙ
Modurile de mapare
Acest paragraf va fi dedicat unor atribute care marcheaza esential modul de desenare intr-un context grafic. Acestea expliciteaza modul de mapare al
coordonatelor logice (puncte virtuale de desenare) pe cele fizice (punctele
efective ale dispozitivului rastru). Spatiul (plan) al coordonatelor logice
determina fereastra (Window) in care se manifesta functiile grafice in timp ce proiectia acesteia pe spatiul (plan) fizic se numeste port_de_vizualizare (Viewport).
Aici trebuie o subliniere pentru a elimina concluzia ca viewport-ul specific altor medii de programare grafica are corespondent in terminologia Windows in
Clipping Region - regiunea in care functiile grafice au un efect vizibil. Rezulta ca maparea este de fapt o translatie a spatiului virtual de desenare pe rastr-ul fizic al dispozitivului. Aceasta translatare respecta neconditionat urmatoarele
formule:
xViewExt xViewPort = (xWindow - xWinOrg) * ---------- + xViewOrg xWinExt
yViewExt yViewPort = (yWindow - yWinOrg) * ---------- + yViewOrg yWinExt
In aceasta formula, originea sistemului de coordonate este exprimata in valori relative la coltul stanga sus al ferestrei. Daca mutarea originii ViewPort pare naturala tinind seama de structura si adresarea fizica a ecranului, mutarea originii Window trebuie gandita ca redefinire a coordonatelor coltului stanga
sus al ferestrei. Coordonatele din Window si ViewPort sunt relative la originea
sistemului de coordonate iar aportul dintre extinderea in cele doua spatii (numarul de unitati pe fiecare dintre axe) reprezinta factorul de scalare la translatare.
Aceasta conversie a coordonatelor punctului logic in coordonatele (fizice) dispo zitivului este asigurata de functia LPtoDP (hDC, lpTablouPuncte, nNUMAR) care face transformarea pentru nNumar de puncte aflate in tabloul pointat de lpTablouPuncte.
In mod similar se pot scrie formulele de conversie inversa din coordonate fizice in coordonate logice, functia corespunzatoare fiind LPtoDP(hDC,lpTablouPuncte, nNUMAR).
Necesitatea acestor conversii vine din regula fireasca de a utiliza atunci cand sunt de specificat coordonatele unui punct de un singur sistem de referinta,
acesta fiind cel logic (Window). Toate functiile care necesita ca parametrii coordonate vor folosi in consecinta acest sistem.
Fiind un limbaj grafic suficient de complet prin grafica in 2D si GDI are nu mai putin de 8 moduri de mapare. Iata care sunt acestea pe scurt:
MM_TEXT(unitate_logica(ul)=pixel)
Acest mod este si cel implicit, fiind natural scrierii europene, deci de sus in jos si de la stanga la dreapta. Desi aceasta mapare poate avea si unele avantaje, ce decurg din faptul ca unitatile logice si cele fizice exista o corespondenta 1\1, totusi desenarea, mai ales daca suntem obisnuiti cu coordonatele carteziene, este oarecum ingreunata de sensul axei y. Cele cinci moduri care
urmeaza rezolva aceasta problema.
MM_LOENGLISH(ul=0.01"=0.254mm)
MM_LOMETRIC(ul=0.00394"=0.1mm)
MM_HIENGLISH(ul=0.001"=0.0254mm)
MM_TWIPS(ul=1/1440"=0.000694"=0.0176mm)
MM_HIMETRIC(ul=0.000394"=0.01mm)
In primul rand, aceste moduri au unitati de masura fizice pentru exprimare coordonatelor punctului logic. In al doilea rand, faptul ca originea initiala este in punctul (stanga, sus) determina automat obligativitatea de a lucra cu coordonate verticale negative. Pentru a obtine in fereastra noastra reprezentare in primul cadran, suntem nevoiti sa apelam functia
SetViewPortOrg(hDC,0,cyClient);
iar daca se doreste desenarea in toate cadranele, o solutie simpla este de
a muta originea ViewPortului in mijlocul spatiului client al ferestrei, de exemplu
SetViewPortOrg(hDC,cxClient/2,cyClient/2);
Obtinerea latimii (cxClient) respectiv a inaltimii (cyClient) s-a mai facut-o in labor anterioare. O astfel de secventa poate fi
GetClientRect(hDC,&rect); cxClient=rect.right; cyClient=rect.bottom;
Ne amintim ca GetClientRect returneaza in parametrul al doilea, dreptunghiul zonei client a ferestrei in pixeli, cu rect.left=rect.top=0. Deoarece
avem dimensiunile in pixeli (unitatea fizica a DC-ului) s-a mutat originea cu
SetViewPortOrg. Daca se doreste mutarea in spatiul logic, suntem obligati sa
facem in prealabil conversia coordonatei fizice in coordonata logica.
pt.x=cxClient/2; pt.y=cyClient/2;
DPtoLP(hDC,&pt,1);
SetWindowOrg(hDC,-pt.x,-pt.y);
Cand se doreste sa controlam totul asupra sistemului logic de coordonate, avem la dispozitie inca doua moduri de mapare:
MM_ISOTROPIC(ul=valoare oarecare,aceeasi pentru ambele axe)
MM_UNISOTROPIC(ul=valoare oarecare pentru fiecare axa)
Aceste moduri au orientarea axelor in mod cartezian si permit definirea unui interval propriu pentru valorile pe care le pot lua coordonatele logice sau fizice. Acest interval se mai numeste si extindere, numele functiilor pentru fixare respectiv consultare avand particula ext. Iata un exemplu prin care sistemul de coordonate va fi fixat cu originea ferestrei, coordonatele evoluand in intervalul
a-1000,1000i.
SetMapMode(hDC,MM_ISOTROPIC);
SetWindowExt(hDC,1000,1000);
SetViewportExt(hDC,cxClient/2,cyClient/2);
SetViewportOrg(hDC,cxClient/2,cyClient/2);
In privinta modului MM_UNISOTROPIC, lucrurile sunt la fel daca valorile pentru cele doua axe pot diferi.
Tema : exersati functiile de desenare care urmeaza pe diferitele moduri de
mapare.
Despre ustensile
Cand trebuie sa desenam ceva, prima grija ce o avem este ce ustensile avem la dispozitie pentru aceasta. GDI-ul Windows ne ofera posibilitatea de
a lucra la un moment dat cu o penita -Pen, o pensula -Brush, o imagine -Bitmap, o paleta de culor -Palette si un set de caractere - Font intr-un context grafic dat. Acestea sunt specificate in contextul grafic printr-un handle obtinut la crearea sau selectarea obiectului grafic respectiv. In principiu deci trebuie
sa alocam spatiu de memorie pentru un obiect de tip pen, brush,etc...,operatie care daca are loc cu succes returneaza handle-ul zonei respective, apoi selectam obiectul in contextul grafic dorit, ceea ce se traduce prin inlocuirea vechii ustensile cu cea noua -in context se memoreaza noul handle in locul vechiului, care se returneaza de catre functia de selectie pentru a fi memorat pina la
refacerea contextului. Este important deci sa ne folosim de un obiect doar atita timp
cit avem nevoie, dupa care se reface contextul la starea initiala si renuntam la
ustensilele folosite. Aceasta operatie de curatenie trebuie facuta cu mare atentie, altfel
riscam ca aplicatia noastra sa lase zone de memorie alocate si nefolosite care
pot sa diminueze in timp capacitatea de raspuns a sistemului datorita fragmentarii memoriei. In continuare se vor prezenta pe scurt citeva caracteristici ale acestora.
Pen-Penita este utilizata pentru trasarea liniilor, conturul diferitelor figuri, etc. Structura de date care memoreaza caracteristicile sale este actualizata
de aplicatie (in cazul crearii ei prin functia CreatePenIndiect) sau direct
prin parametrii functiei CreatePen. Dupa cum se va vedea o penita este definita prin stil, latime si culoare.
typedef struct tagLOGPEN A/*lgpn */
UINT lopnStyle;
POINT lopnWidth;
COLORREF lopnColor;
S LOGPEN;
Stilul penitei poate fi :
PS_SOLID-linie plina,
PS_DASH-linie intrerupta,
PS_DOT-linie punctata
PS_DASHDOT-linie liniuta-punct,
PS_DASHDOTDOT-linie liniuta-punct-punct,
PS_NULL-gol,
PS_INSIDEFRAME-linie in interiorul conturului figurii desenate.
Brush-Pensula este de fapt un obiect grafic puternic, el definind un
"model" cu care se poate umple un contur. La fel ca in cazul penitei,
pensulele pot fi create direct sau indirect, structura de date fiind:
typedef struct tagLOGBRUSH A/*lb*/
UINT lbStyle;
COLORREF lbColor; int lbHatch;
S LOGBRUSH;
La fel ca in cazul anterior, avem mai multe caracteristici, stil, culoare si hasura. Stilul unei pensule poate fi
BS_SOLID-plina,
BS_PATTERN cu model definit ca bitmap din memorie,
BS_DIBPATTERN-cu model definit ca bitmap independent de dispozitiv
(device-independent bitmap-DIB),
BS_HATCHED-cu hasura
BS_HOLLOW
BS_NULL-goala
In cazul unei pensule de hasura acestea pot fi diagonale in sus sau in jos :
HS_BDIAGONAL, HS_FDIAGONAL,
in cruce pe verticala sau diagonala:
HS_CROSS, HS_DIAGCROSS
sau orizontale, respectiv verticale:
HS_HORIZONTAL, HS_VERTICAL
Bitmap-Despre imaginile bitmap s-a mai vorbit cu ocazia parcurgeii resurselor.
Informatiile din acel labor se completeaza acum cu noile cunostinte despre GDI.
Palette-paleta de culori este definita printr-o structura de date in felul urmator:
typedef struct tagLOGPALETTEA/*lgpl*/
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntrya1i;
S LOGPALETTE;
In aceasta structura palVersion specifica versiunea Windows (=0x300 pentru Windows 3.0 si urmatoarele) palNumEntries numarul de culori din paleta iar palPalEntry este un tablou de structuri PALETTEENTRY definite dupa cum urmeaza:
typedef struct tagPALETTEENTRYA/* pe */
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags;
S PALETTEENTRY;
unde primii trei membri definesc culoarea prin componentele Rosu,Verde,Albastru
(peRed,peGreen,peBlue) iar peFlags defineste modul de utilizare al intrarii.
Acest flag poate fi
PC_EXPLICIT-intrarea specificand in acest caz prin cuvantul low un index in paleta dispozitivului hardware,
PC_NOCOLLAPSE-precizeaza ca acea culoare va fi plasata intr-o intrare utilizata a paletei sistem in loc sa fie plasata in intrarea culorii cea mai apropiata de aceasta
PC_RESERVED-care specifica utilizarea intrarii pentru o schimbare frecventa a culorii in functie de necesitati, proces ce se numeste animarea paletei.
Este bine ca in tabloul de culori culorile sa apara in ordinea importantei lor asa incat primele sa poata fi transferate la nevoie in paleta sistem.
FONT-Pentru fonturi si functiile de desenare a textului vom rezerva explicatii ulterioare.
Utilizarea acestor obiecte este sustinuta si de cateva functii cu caracter general. Aceste functii sunt prezentate pe scurt in continuare.
EnumObjects-enumera penitele si pensulele dintr-un context grafic;
GetObject-returneaza informatiile legate de un anume obiect;
GetStockObject-returneaza handle-ul unui obiect predefinit (pen, brush, sau font);
IsGDIObject-determina daca un handle apartine unui obiect GDI;
SelectObject-selecteaza un obiect intr-un context grafic;
UnrealizeObject-initializeaza originea unei pensule sau a unei palete.
Despre regiuni
Regiunea poate fi definita ca suprafata de afisare obtinuta prin combinarea
unor dreptunghiuri, elipse, poligoane. Acestea pot fi folosite pentru desenare
sau pentru decupaj. Regiunea trebuie vazuta ca un obiect GDI si in consecinta aplicate toate regulile de utilizare a lor presupunand crearea, selectarea si
stergerea lor dupa utilizare.
Functiile de creare a unei regiuni de o anumita forma sunt:
CreateEllipticRgn,
CreateElipticRgnIndirect-pentru regiuni eliptice definite de un dreptunghi,
CreatePoligonRgn-pentru regiuni definite de o linie poligonala sau mai multe astfel de linii,
CreateRectRgn,
CreateRectRgnIndirect-crearea unei regiuni dreptunghiulare si a uneia care are colturile rotunjite CreateRoundRectRgn-crearea unei regiuni dreptunghiulare care are colturile rotunjite
Regiunile astfel create pot face in continuare obiectul unor operatii cu ajutorul functiilor prezentate pe scurt in continuare:
CombineRgn-creaza o regiune prin combinarea a doua regiuni.
EqualRgn-compara egalitatea a doua regiuni
FillRgn-umple o regiune cu pensula specificata
FrameRgn-desenseaza un chenar in jurul regiuni dorite
GetRgnBox-returneaza dreptungiul care margineste regiunea
InvertRgn-inverseza culorile dintr-o regiune
OffsetRgn-muta regiunea cu un anumit offset
PaintRgn-umple regiunea cu pensula contextului grafic
PtInRegion-verifica apartenenta unui punct la o regiune
RectInRegion-verifica apartenenta unui dreptunghi la o regiune
SetRectRgn-transforma regiunea intr-un dreptunghi
Utilizare adecvata a acestor functii presupune un "antrenement"
de grafica sustinut, care in final poate sa ofere surprize deosebite.
Despre desenare
Pentru a desena intr-un context grafic oarecare trebuie in primul rand sa obtinem handle-ul acestuia. Modalitatile de a obtine un context grafic sau de a incepe desenarea le-am parcurs in labor precedent. Trebuie doar reamintit acum cat de importante sunt operatiile de initiere si respectiv terminare a desenarii, acestea implicand de fapt cerere de blocuri de memorie si apoi eliberarea lor. In sfarsit avand contextul grafic, iar in cazul lui
WM_PAINT si o structura (PAINTSTRUCT) incarcata cu diverse informatii utile, putem desena in aceasta folosindu-ne de diversele ustensile prezentate deja.
Nu trebuie uitat ca toate operatiile sunt relative la regiunile care sunt definite la un moment dat in contextul grafic, ele definind regiunile vizibile respectiv invizibile de manifestare a functiilor grafice. Dupa aceste
faze preliminare putem apela in sfarsit functiile grafice de desenare pentru diverse obiecte grafice: puncte, linii, linii poligonale, dreptunghiuri, arce
de cerc, elipse, etc., lista acestora fiind sintetizata in finalul laboratorului.
DESENARE PUNCTE
SetPixel Modifica culoarea unui pixel
DESENARE LINII
Arc Deseneaza un arc de cerc
LineDDA Calculeaza ounctele succesive ale unei linii si apeleaza o functie definita de noi pentru desenarea punctului
LineTo Deseneaza o linie plecand de la pozitia curenta
MoveTo Muta pozitia curenta
MoveToEx Muta pozitia curenta returnand punctul anterior
Polyline Deseneaza o linie poligonala definita printr-o succesiune de puncte
DESENARE FIGURI SI OPERATII CU ELE
Polygon Deseneaza un poligon
PolyPolygon Deseneaza o serie de poligoane
Chord Deseneaza o coarda (determinata de doua puncte de de pe circumferinta unei elipse)
Ellipse Deseneaza o elipsa
Pie Deseneaza o felie de "placinta"
Rectangle Deseneaza un dreptunghi
RoundRect Deseneaza un dreptunghi cu colturile rotunjite
DrawFocusRect Deseneaza un dreptunghi ca si cel de marcaj focus
CopyRect Copiaza dimensiunile unui dreptunghi
EqualRect Determina egalitatea a doua dreptunghiuri
FrameRect Deseneaza un chenar cu pensula curenta
FillRect Umplerea unui dreptunghi
GetBoundsRect Returneaza dreptunghiul cuprinzator
InflateRect Modifica dimensiunile unui dreptunghi
IntersectRect Calculeaza intersectia a doua dreptunghiuri
InvertRect Inverseaza culorile dintr-un dreptunghi
IsRectEmpty Determina daca dreptunghiul este gol
OffsetRect Muta dreptunghiul la un anumit offset
PtlnRect Determina apartenenta unui punct la un dreptunghi
SetBoundsRect Modifica dreptunghiul de cuprindere
SetRect Fixeaza coordonatele unui dreptunghi
SetRectEmpty Creaza un dreptunghi gol
SubtracRect Creaza un dreptunghi prin diferenta a doua dreptunghiuri
UnionRect Creaza un dreptunghi prin uniunea a doua dreptunghiuri