Sunteți pe pagina 1din 19

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Facultatea Calculatoare, Informatic i Microelectronic

RAPORT
Lucrarea de laborator nr. 2
la disciplina:Programarea in Windows
Tema: Interfata GDI

A efectuat: Meralov Dmitrii


A verificat: Cojocaru Svetlana

Chiinu 2015

LUCRARE DE LABORATOR NR. 2

1.Tema : Interfaa GDI


2.Scopul lucrarii : Studierea primitivelor oferite de interfaa GDI.
3.Sarcina lucrrii: Scriei un program care afieaz n zona client un desen animat, utiliznd
toate primitivele GDI.

Noiuni teoretice

Interfaa pentru dispozitive grafice (GDI - Graphics Device Interface) este o component a
sistemului de operare Windows i are ca sarcin afiarea elementelor grafice (inclusiv a textului)
pe ecran i la imprimant.
De asemenea, trebuie s tii c interfa Windows GDI i are limitele ei. Cel puin n acest
moment, interfa GDI nu poate s fac tot ce v-ai putea dori de la o interfa grafic. Dei putei
s mutai pe ecran obiecte grafice, GDI este, n general, un sistem de afiare static, ce permite
numai animaii limitate. Aa cum este implementat n Windows 95, interfa GDI nu asigur un
suport direct pentru afiarea tridimensional sau pentru rotirea obiectelor. De exemplu, atunci
cnd desenai o elips, axele acesteia trebuie s fie paralele cu axele sistemului de coordonate.
Dei unele limbaje grafice folosesc numere n virgul mobil pentru coordonatele virtuale.
Windows 95 - din motive legate de performan - folosete numai numere ntregi pe 16 bii
aceasta este una dintre deficienele sistemului de operare Windows 95. Windows NT permite
folosirea coordonatelor pe 32 de bii.
Din punctul de vedere al programatorului, interfaa GDI este format din cteva sute de apeluri
de funcii i unele tipuri de date, macroinstruciuni i structuri asociate acestor funcii, nainte de a
studia n detaliu cteva dintre aceste funcii, haidei s vedem care este structura general a
interfeei GDI.

Tipuri de apeluri de funcii


n general, apelurile de funcii GDI pot fi clasificate n mai multe categorii. Chiar dac nu sunt
foarte stricte i exist unele suprapuneri, aceste categorii pot fi enunate astfel:
o
o
o
o
o

Funcii care obin (sau creeaz) i elibereaz (sau distrug) un context de dispozitiv.
Funcii care obin informaii despre contextul de dispozitiv.
Funcii care deseneaz ceva.
Funcii care stabilesc sau obin atribute ale contextului de dispozitiv.
Funcii care lucreaz cu obiecte GDI.

Elementele grafice pe care le afiai pe ecran sau le tiprii la imprimant pot fi mprite n mai
multe categorii, numite primitive". Iat care sunt aceste categorii:

Linii i curbe. Liniile reprezint baza oricrui sistem de desenare vectorial. GDI permite
folosirea liniilor drepte, a dreptunghiurilor, a elipselor (inclusiv subsetul de elipse
cunoscute sub numele de cercuri), a arcelor - care sunt curbe reprezentnd poriuni din
circumferina unei elipse sau a curbelor Bezier. Liniile sunt desenate folosind penia
curent selectat n contextul de dispozitiv.
Suprafee pline. Dac o serie de linii sau de curbe nchid o suprafa, aceasta poate fi
umplut" folosind pensula GDI curent. Aceast pensul poate fi o culoare compact,
un model (hauri orizontale, verticale sau pe diagonal) sau o imagine bitmap repetat
pe vertical sau pe orizontal.
Imagini bitmap. Imaginile bitmap sunt matrice dreptunghiulare de bii, care corespund
pixelilor unui dispozitiv de afiare. n general, acestea sunt folosite pentru afiarea
imaginilor complexe (deseori preluate din lumea real) pe ecran sau pentru tiprirea
acestora la imprimant. De asemenea, imaginile bitmap sunt folosite pentru afiarea unor
mici imagini (cum ar fi pictograme, indicatoare de mouse i butoane de pe barele cu
instrumente de lucru ale aplicaiilor) care trebuie afiate foarte rapid.
Text. Textul este mai puin matematic" dect alte aspecte ale graficii pe calculator.
Structurile create pentru definirea fonturilor i pentru obinerea informaiilor despre fonturi
sunt printre cele mai mari din Windows. ncepnd cu versiunea Windows 3.1, interfaa
GDI accept fonturile TrueType, bazate pe contururi umplute, care pot fi manipulate de
alte funcii GDI. Windows 95 accept n continuare i fonturile mai vechi, de tip bitmap
(cum este fontul sistem prestabilit) pentru compatibilitate i pentru economisirea spaiului
de memorie.

Alte aspecte ale interfeei GDI nu sunt la fel de uor de clasificat. Printre acestea se numr:
o

Moduri de mapare i transformri. Modurile de mapare GDI v permit s desenai


folosind ca unitate de msur inci (sau fraciuni de inci), milimetri sau orice alt unitate de
msur. De asemenea. Windows 95 asigur suportul pentru o transformare real"
exprimat printr-o matrice 3x3. Aceast transformare permite deformarea i rotirea
obiectelor grafice. Din pcate, aceast transformare nu este acceptat sub Windows 95.
Metafiiere (metafiles). Un metafiier este o colecie de comenzi GDI stocate ntr-o
form binar. Metafiierele sunt folosite pentru transferarea reprezentrilor unor elemente
grafice vectoriale prin intermediul memoriei temporare (clipboard).
Regiuni (regions). O regiune este o suprafa complex de orice form, definit ca o
combinaie boolean de regiuni mai simple. n general, regiunile sunt stocate intern de
GDI ca o serie de linii de scanare, diferite de combinaia de linii folosit iniial pentru
definirea regiunii. Putei s folosii regiunile pentru contururi, pentru umplere sau pentru
decupare.
Ci (paths). O cale este o colecie de linii drepte i curbe stocate intern de GDI. Cile
pot fi folosite pentru desenare, pentru umplere sau pentru decupare. De asemenea, cile
pot fi transformate n regiuni.
Decupare (clipping). Desenarea poate fi limitat la o anumit seciune a zonei client,
numit zon de decupare, care poate fi dreptunghiular sau poate avea o alt form,
definit printr-o serie de linii. Zona de decupare este definit, n general, de o cale sau de
o regiune.

Palete (palettes). Folosirea paletelor proprii este limitat, n general, numai la


monitoarele care pot reda 256 de culori. Windows rezerv 20 dintre aceste culori pentru
sistemul de operare. Celelalte 236 de culori pot fi modificate pentru afiarea
corespunztoare a imaginilor din lumea real, stocate ca imagini bitmap.
Tiprire (printing). Dei discuiile din acest capitol sunt limitate doar la afiarea pe
ecran, tot ceea ce nvai n acest capitol poate fi aplicat i operaiilor de tiprire. (Vezi
Capitolul 15 pentru alte informaii despre tiprire.)

Contextul de dispozitiv
Atunci cnd vrei s desenai la un dispozitiv de ieire grafic (cum ar fi ecranul sau imprimanta)
trebuie s obinei mai nti o variabil handle a contextului de dispozitiv (DC - device context).
Variabila handle este apoi inclus ca parametru n apelul unei funcii GDI, identificnd dispozitivul
Ia care vrei s desenai. Contextul de dispozitiv conine mai multe atribute curente, care
specific modul de lucru al funciilor GDI pentru dispozitivul respectiv. Aceste atribute permit ca la
apelarea funciilor GDI s fie specificate numai coordonatele de nceput sau dimensiunea, nu i
toate celelalte informaii de care sistemul de operare are nevoie pentru desenarea obiectelor pe
dispozitivul folosit. Atunci cnd dorii s modificai unul dintre aceste atribute ale contextului de
dispozitiv, apelai o funcie specializat.

Obinerea variabilei handle a contextului de dispozitiv


Sistemul de operare Windows v pune la dispoziie mai multe metode pentru obinerea variabilei
handle a contextului de dispozitiv. Dac obinei o variabil handle a contextului de dispozitiv n
timpul prelucrrii unui mesaj, ar trebui s tergei aceast variabil nainte de ieirea din
procedura de fereastr. Dup ce este tears, variabila handle nu mai poate fi folosit (nu mai
este valid).
Cea mai cunoscut metod de obinere i de tergere a variabilei handle a contextului de
dispozitiv implic folosirea funciilor BeginPaint i EndPaint n timpul prelucrrii mesajului
WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
[alte linii de program]
EndPaint (hwnd, &ps);
Variabila ps este o structur de tip PAINTSTRUCT. Cmpul hdc al acestei structuri conine
variabila handle a contextului de dispozitiv. Folosind variabila handle a contextului de dispozitiv,
obinut prin apelarea funcieiBeginPaint, nu putei s desenai dect n regiunea invalid a
ferestrei. Funcia BeginPaint valideaz regiunea invalid.

Programele Windows pot s obin variabila handle a contextului de dispozitiv i n timpul


prelucrrii altor mesaje dect WM_PAINT:
hdc = GetDC (hwnd);
(alte linii de program]
ReleaseDC (hwnd, hdc);
Acest context de dispozitiv se aplic zonei client a ferestrei care are variabila
handle hwnd. Principala diferen ntre apelul de mai sus i metoda folosirii
funciilor BeginPaint i EndPaint este c variabila handle returnat de funcia GetDC v permite
s desenai n toat zona client a ferestrei. n plus, funciile GetDC i ReleaseDC nu valideaz
eventualele regiuni invalide ale zonei client.
Un program Windows poate s obin i o variabil handle a unui context de dispozitiv care se
aplic ntregii ferestre, nu numai zonei client a ferestrei:
hdc = GetWindowDC (hwnd);
[alte linii de program]
ReleaseDC (hwnd, hdc);
[alte linii de program]
DeleteDC (hdc);

Obinerea informaiilor despre culori


Funcia GetDeviceCaps v permite s determinai modul de organizare a memoriei n
adaptoarele video i numrul de culori care pot fi reprezentate. Apelul de mai jos returneaz
numrul de planuri de culoare:
iPlanes = GetDeviceCaps (hdc, PLANES);
Apelul urmtor returneaz numrul de bii de culoare folosii pentru fiecare pixel:
iBitsPixel = GetDeviceCaps (hdc, BITSPIXEL);
Majoritatea adaptoarelor video care pot afia culori folosesc fie mai multe planuri de culoare, fie
mai muli bii de culoare pentru fiecare pixel, dar nu pe amndou; cu alte cuvinte, unul dintre
cele dou apeluri de mai sus va returna valoarea 1. Numrul de culori care pot fi redate de o
plac video se poate calcula cu formula urmtoare:

iColors = 1<<(iPlanes * iBitsPixel);


Aceast valoare poate s nu fie identic cu numrul de culori obinut prin apelarea
funciei GetDeviceCaps cu parametrul NUMCOLORS:
iColors = GetDeviceCaps (hdc, NUMCOLORS);
Windows folosete pentru reprezentarea culorilor o valoare ntreag fr semn, pe 32 de bii.
Tipul de date folosit pentru culori se numete COLORREF. Ultimii trei octei ai numrului (cei mai
puin semnificativi) specific valorile pentru culorile rou, verde i albastru, de la O la 255, aa
cum se poate vedea n Figura 4-3. Rezult o palet potenial de 224 culori (aproximativ 16
milioane de culori).
Valoarea pe 32 de bii de mai sus e numit deseori culoare RGB". n fisierele antet din Windows
sunt definite mai multe macroinstruciuni pentru lucrul cu valorile RGB. Macroinstructiunea RGB
accept trei argumente, care reprezint valorile pentru culorile rou, verde i albastru i le
combin ntr-o valoarea ntreag pe 32 de bii, fr semn.
Astfel, valoarea
RGB (255, 0, 255)
este de fapt 0x00FF00FF, valoarea RGB pentru magenta. Dac toate cele trei argumente au
valoarea 0, se obine negrul, iar dac au valoarea 255, se obine albul. Macroinstruciunile
GetRValue, GetGValue i GetBValue extrag valorile pentru culorile primare, sub forma unor octei
fr semn, din valoarea RGB a culorii. Aceste macroinstructiuni sunt utile atunci cnd apelai
funcii Windows care returneaz culori RGB.

Salvarea contextului de dispozitiv


n mod normal, Windows creeaz un nou context de dispozitiv cu valori prestabilite atunci cnd
apelai una dintre funciile GetDC sau BeginPaint. Toate modificrile fcute n atributele
contextului de dispozitiv se pierd atunci cnd contextul de dispozitiv este ters din memorie prin
apelarea funciei ReleaseDC sau a funciei EndPaint. Dac programul trebuie s foloseasc un
atribut cu o valoarea diferit de cea prestabilit va trebui s iniializai contextul de dispozitiv de
fiecare dat cnd obinei o variabil handle:
caseWM_Paint:
hdc = BeginPaint (hwnd, &ps);
[iniializeaz atributele contextului de dispozitiv]
[deseneaz zona client a ferestrei]

EndPaint (hwnd, &ps);


return 0;
Dei aceast abordare este n general satisfctoare, s-ar putea s preferai s salvai
modificrile fcute asupra contextului de dispozitiv ia distrugerea acestuia, astfel nct valorile
salvate s redevin active la apelarea funciilorGetDC sau BeginPaint.

Desenarea liniilor
Interfaa Windows GDI conine i funciile SetPixel i GetPixel. Dei vom folosi funcia SetPixel n
programul CONNECT din Capitolul 7, n programele de grafic propriu-zis aceste funcii sunt
rareori folosite. n majoritatea cazurilor, cea mai simpl primitiv grafic vectorial trebuie s fie
considerat linia.
Windows poate s deseneze linii drepte, linii eliptice (linii curbe, pe circumferina unei elipse) i
curbe Bezier. Cele apte funcii acceptate de Windows 95 pentru desenarea liniilor
sunt LineTo (linii drepte), Polyline i PolylineTo (o serie de linii drepte conectate), PolyPolyline
(mai multe linii poligonale), Arc (linii eliptice), PolyBezier i PolyBezierTo. (Interfaa GDI din
Windows NT accept nc trei funcii pentru desenarea liniilor: ArcTo,
AngleArc iPolyDraw. Aceste funcii nu sunt ns acceptate n Windows 95.) Aspectul liniilor
desenate cu aceste funcii poate fi influenat de cinci atribute ale contextului de dispozitiv: poziia
curent a peniei (numai pentru funciile LineTo,PolylineTo i PolyBezierTo), penia selectat,
modul de afiare a fondului (numai pentru peniele care nu deseneaz cu o culoare compact),
culoarea fondului (pentru modul OPAQUE de afiare a fondului) i modul de desenare.
Funcia LineTo este una dintre puinele funcii GDI care nu are nevoie de dimensiunile complete
ale obiectului ce urmeaz s fie desenat. Funcia LineTo deseneaz o linie de la poziia curent"
definit n contextul de dispozitiv pan la punctul specificat la apelarea funciei (exclusiv acest
punct). Poziia curent este folosit ca punct de plecare i de alte funcii GDI. n contextul de
dispozitiv prestabilit, poziia curent are iniial valoarea (0,0). Dac apelai funcia LineTo fr s
stabilii mai nti poziia curent, funcia deseneaz o linie pornind din colul din stnga-sus al
zonei client.
Dac dorii s desenai o linie din punctul (xStart, yStart) pan n punctul (xEnd, yEnd) trebuie s
apelai mai nti funcia MoveToEx ca s stabilii ca poziie curent punctul (xStart, ySfart):
MoveToEx (hdc, xStart, yStart, &pt) ;
unde pt este o structur de tip POINT, definit n fiierele antet.
Funcia MoveToEx nu deseneaz nimic, ci doar schimb poziia curent. Poziia curent
anterioar este stocat n structura de tip POINT. Putei apoi s folosii funcia LineTo ca s
desenai linia:

LineTo (hdc, xEnd, yEnd);


Apelul de mai sus deseneaz o linie pn n punctul (xEnd, yEnd), exclusiv acest punct. Dup
apelul funcieiLineTo, poziia curent devine (xEnd, yEnd).
Putei s obinei poziia curent a peniei apelnd funcia GetCurrentPosition astfel:
GetCurrentPositionEx (hdc, &pt) ;
Atunci cnd avei o matrice de puncte pe care vrei s le conectai prin linii, putei s desenai mai
uor liniile folosind funcia Polyline. Instruciunea de mai jos deseneaz acelai dreptunghi ca i
secvena de cod din exemplul anterior:
Polyline (hdc, pt, 5);
Ultimul parametru reprezint numrul de puncte. Aceast valoare putea fi reprezentat i prin
expresia (sizeof(pt) / sizeof(POINT)). Funcia Polyline are acelai efect ca i o
funcie MoveToEx urmat de mai multe funcii LineTo,exceptnd faptul c funcia Polyline nu
schimb poziia curent. Funcia PolylineTo este puin diferit. Aceasta folosete ca punct de
plecare poziia curent i stabilete ca poziie curent sfritul ultimei linii desenate. Codul de
mai jos deseneaz acelai dreptunghi folosit ca exemplu i mai sus:
MoveToEx (hdc, pt[0].x, pt[0].y, NULL) ;
PolylineTo (hdc, pt + 1,4) ;
Dei putei s folosii funciile Polyline i PolylineTo i pentru un numr mic de funcii, acestea
sunt mai utile atunci cnd desenai o curb complex format din sute sau chiar mii de linii.
n continuare a vrea s discutm despre funcia Arc, funcie care deseneaz o curb eliptic.
Dar funcia Arc nu prea are sens dac nu discutm mai nti despre funcia Ellipse, care, la
rndul ei, nu are sens fr o discuie despre funcia Rectangle. Si dac discutm despre
funciile Rectangle i Ellipse, putem la fel de bine s discutm i despre funciile RoundRect,
Chord i Pie.
Problema este c funciile Rectangle, Ellipse, RoundRect, Chord i Pie nu sunt tocmai nite
funcii de desenare a liniilor. Desigur, ele deseneaz i linii, dar i coloreaz zona nchis, cu
pensula curent de colorare a suprafeelor. n mod prestabilit, aceast pensul are culoarea alb,
aa c s-ar putea ca operaia s nu fie att de evident atunci cnd ncercai pentru prima dat
s utilizai aceste funcii. Dei, n sens strict, funciile aparin unei alte seciuni din capitolul de
fa, Desenarea suprafeelor pline", vom discuta acum despre fiecare.
Funciile de mai sus sunt asemntoare prin faptul c sunt construite pe baza unui dreptunghi
de ncadrare" (bounding box"). Dumneavoastr definii o caset care ncadreaz obiectul dreptunghiul de ncadrare - i Windows deseneaz obiectul n acest dreptunghi.
Cea mai simpl dintre aceste funcii deseneaz un dreptunghi:

Rectangle (hdc, xLeft, yTop, xRight, yBottom) ;


Punctu cu coordonatele (xLeft, yTop) este punctul din stnga sus, iar punctul cu coordonatele
(xRight, yBottom) este punctul din dreapta jos.
Dup ce ai aflat cum se deseneaz un dreptunghi, folosind aceiai parametri, vei putea, la fel
de simplu, s desenai i o elips:
Ellipse (hdc, xLeft, yTop, xRight, yBottom) ;
Funcia pentru desenarea unui dreptunghi cu colurile rotunjite folosete acelai dreptunghi de
ncadrare ca i funciile Rectangle i Ellipse, dar are nc doi parametri:
RoundRect (hdc, xLeft, yTop, xRight, yBottom, xCornerEllipse, yCornerEllipse);
Pentru desenarea colurilor rotunjite, Windows folosete o mic elips. Limea elipsei
este xCornerEllipse iar nlimea acesteia este yCornerEllipse. Colurile dreptunghiului sunt cu
att mai rotunjite cu ct valorile parametrilorxCornerEllipse i yCornerEllipse sunt mai mari.
Dac xCornerEllipse este egal cu jumtate din diferena
dintre xLefti xRight iar yCornerEllipse este egal cu jumtate din diferena dintre yTop i yBottom,
atunci funcia RoundRect va desena o elips.
Funciile Arc, Chord i Pie primesc aceiai parametri:
Arc (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
Chord (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
Pie (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd);
n cazul funciei Arc, Windows i-a terminat treaba, deoarece arcul este o linie eliptic, nu o
suprafa plin. n cazul funciei Chord, Windows unete capetele arcului, iar n cazul funciei Pie,
unete capetele arcului cu centrul elipsei. Interioarele suprafeelor nchise obinute astfel sunt
colorate cu pensula curent.

Folosirea penielor de stoc


Atunci cnd apelai oricare dintre funciile de desenare a liniilor, Windows folosete pentru
desenarea liniilor penia" (pen) curent selectat n contextul de dispozitiv. Penia selectat
determin culoarea, limea i tipul de linie (acestea pot fi continue, punctate sau ntrerupte).
Penia din contextul prestabilit de dispozitiv se numete BLACK_PEN. Aceasta deseneaz o linie
compact, de culoare neagr, cu grosimea de un pixel, indiferent de modul de mapare.
BLACK_PEN este una dintre cele trei penie de stoc" (stock pen) furnizate de Windows.
Celelalte dou penie de stoc sunt WHITE_PEN i NULL_PEN. NULL_PEN este o peni care nu
deseneaz nimic. n plus, putei s creai penie proprii.

Penie sunt determinate de propriile variabile handle. n fiierele antet din Windows este definit
tipul de date HPEN, care reprezint o variabil handle a unei penie. Putei s definii o variabil
(de exemplu, hPen) folosind aceast definiie de tip:
HPEN hPen ;
Putei s obinei variabila handle a uneia dintre peniele de stoc apelnd
funcia GetStockObject. De exemplu, s presupunem c vrei s folosii penia de stoc numit
WHITE_PEN. Obinei variabila handle a acesteia astfel:
hPen = GetStockObject (WHITE_PEN);
Apoi trebuie s selectai n contextul de dispozitiv penia a crei variabil ai obinut-o, apelnd
funciaSelectObject:
SelectObject (hdc, hPen) ;
Dup acest apel toate liniile pe care le desenai vor folosi penia WHITE_PEN, pn cnd
selectai o alt peni n contextul de dispozitiv sau tergei contextul de dispozitiv.
n loc s definii explicit variabila hPen, putei s combinai
funciile GetStockObject i SelectObject ntr-o singur instruciune:
SelectObject (hdc, GetStockObject (WHITE_PEN)) ;
Dac apoi vrei s revenii la penia BLACK_PEN, putei s obinei o variabil handle a acesteia
i s o selectai n contextul de dispozitiv tot cu o singur instruciune:
SelectObject (hdc, GetStockObject (WHITE_PEN));
Funcia SelectObject returneaz variabila handle a peniei selectate anterior n contextul de
dispozitiv. Dac deschidei un nou context de dispozitiv i executai instruciunea:
hPen = SelectObject (hdc, GetStockObject (WHITE_PEN)) ;
atunci penia curent selectat n contextul de dispozitiv va fi WHITE_PEN i hPen va fi variabila
handle a peniei BLACK_PEN. Putei apoi s selectai penia BLACK_PEN n contextul de
dispozitiv cu urmtoarea instruciune:
SelectObject (hdc, hPen) ;
Pentru a crea o peni proprie apelai funcia:
hPen = CreatePen (iPenStyle, iWidth, rgbColor) ;

Parametrul iPenStyle precizeaz dac se deseneaz o linie continu, o linie punctat sau una
ntrerupt. Parametrul iPenStyle poate fi unul dintre identificatorii definii n fiierele antet din
Windows.
Parametrul rgbColor din funcia CreatePen este un numr ntreg fr semn reprezentnd
culoarea peniei. Pentru toate stilurile de penie, exceptnd PS_INSIDEFRAME, atunci cnd
selectai penia n contextul de dispozitiv, Windows convertete acest parametru la cea mai
apropiat culoare pur pe care o poate reprezenta dispozitivul de afiare. PS_INSIDEFRAME
este singurul stil care poate folosi culori amestecate, dar numai pentru grosimi mai mari de un
pixel.

Desenarea suprafeelor pline


Cele apte funcii Windows pentru desenarea figurilor sunt prezentate n tabelul urmtor:

Funcia

Figura

Rectangle

Dreptunghi cu coluri drepte

Ellipse

Elips

RoundRect

Dreptunghi cu coluri rotunjite

Chord

Arc pe circumferina unei elipse,


avnd capetele unite printr-o coard

Pie

Suprafa de forma unei felii de


plcint, reprezentnd un segment
de elips.

Polygon

Figur geometric avnd mai multe

laturi

PolyPolygo
n

Mai multe figuri geometrice cu mai


multe laturi

Windows deseneaz conturul figurilor folosind penia curent selectat n contextul de dispozitiv.
Pentru acest contur sunt folosite atributele stabilite pentru modul de desenare a fondului,
culoarea fondului i modul de desenare, ca i n cazul desenrii unei linii simple. Tot ceea ce ai
nvat despre linii se aplic i n cazul contururilor.
Figurile sunt umplute folosind pensula selectat n contextul de dispozitiv. n mod prestabilit,
aceasta este pensula de stoc WHITE_BRUSH, ceea ce nseamn c interiorul figurilor va fi
umplut cu alb. Windows definete ase pensule de stoc: WHITE-_BRUSH, LTGRAY_BRUSH,
GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH i NULL_BRUSH (sau HOLLOW_BRUSH).
Putei s selectai una dintre aceste pensule n contextul de dispozitiv la fel cum selectai o
peni de stoc. Windows definete tipul HBRUSH ca variabil handle a unei pensule, aa c
putei s definii mai nti o variabil de acest tip:
HBRUSH hBrush ;
Putei s obinei variabila handle a pensulei de stoc GRAY_BRUSH apelnd
funcia GetStockObject:.
hBrush = Get&toCkObject (GBAY_BRUSH) ;
Putei s o selectai apoi n contextul de dispozitiv folosind funcia SelectObject:
SelectObject (hdc, hBrush) ;
Din acest moment, figurile desenate vor avea interiorul gri.
Dac vrei s desenai o figur fr contur, selectai n contextul de dispozitiv penia NULL_PEN:
SelectObject (hdc, GetStockObject (NULL_PEN)) ;
Dac vrei s desenai o figur fr s i umplei interiorul, selectai n contextul de dispozitiv
pensula NULL_BRUSH:
SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
Aa cum putei s creai penie proprii, putei s creai i pensule proprii.

Sistemele de coordonate ale dispozitivului


Windows mapeaz coordonatele logice specificate n funciile GDI la coordonatele dispozitivului.
nainte de a discuta despre sistemele de coordonate logice folosite de diferitele moduri de
mapare, vom discuta despre diferitele sisteme de coordonate de dispozitiv definite n Windows
pentru zona de afiare. Dei n general am lucrat doar n zona client a ferestrei, n anumite
situaii Windows folosete alte dou sisteme de coordonate de dispozitiv. n toate sistemele de
coordonate de dispozitiv sunt folosii pixelii ca unitate de msur. Valorile de pe axa
orizontal(x) cresc de la stnga la dreapta iar valorile de pe axa vertical (y) cresc de sus n jos.
Atunci cnd folosim ntregul ecran, spunem c lucrm n coordonate ecran". Colul din stngasus este punctul de coordonate (0, 0). Coordonatele ecran sunt folosite n mesajul WM_MOVE
(pentru alte ferestre dect ferestrele descendent) i n urmtoarele funcii
Windows: CreateWinriow i MoveWindow (ambele pentru alte ferestre dect ferestrele
descendent), GetMessagePos, GetCursorPos, SetCursorPos, GetWindowRect,
WindowFromPoint iSetBrushOrgEx. Acestea sunt funcii care fie nu au o fereastr asociat
(cum ar fi cele dou funcii pentru cursor), fie trebuie s mute (sau s gseasc) o fereastr pe
baza unui punct de pe ecran. Dac folosii funcia CreateDCcu parametrul DISPLAY ca s
obinei un context de dispozitiv pentru ntregul ecran, atunci coordonatele logice specificate la
apelarea funciilor GDI vor fi mapate la coordonatele ecranului.
Coordonatele de fereastr" se refer la ntreaga fereastr a ecranului, inclusiv bara de titlu,
meniu, barele de derulare i chenarul ferestrei. Pentru o fereastr normal, punctul (0, 0) este
colul din stnga-sus al chenarului de redimensionare. Coordonatele de fereastr sunt folosite
mai rar n Windows, dar dac obinei un context de dispozitiv cu ajutorul funciei GetWindowDC,
atunci coordonatele logice specificate la apelarea funciilor GDI vor fi mapate la coordonatele
ferestrei.
Al treilea sistem de coordonate de dispozitiv - cu care vom lucra cel mai des -folosete
coordonatele zonei client". Punctul (0,0) este colul din stnga-sus al zonei client. Dac obinei
un context de dispozitiv cu ajutorul funcieiGetDC sau al funciei BeginPaint, atunci coordonatele
logice specificate Ia apelarea funciilor GDI vor fi mapate la coordonatele zonei client.
Putei s transformai coordonatele zonei client n coordonatele ecranului i invers folosind
funciile ClientToScreeni ScreenToClient. De asemenea, putei obinei poziia i dimensiunea
ntregii ferestre n coordonate ecran folosind funcia GetWindowRect.

4. Listingul Programului
#include <windows.h>
int i,j,dir;
int a[3][6] ={ {123,343,100,163,232,166},{128,15,129,74,234,255},{1,2,3,4,1,4} };
int circle(HWND hwnd,HDC hdc,int i, int j, int dir, RECT rect,int nr)
{
HPEN
hBluePen,hRedPen,hYellowPen,hGreenPen,hVioletPen,hOrangePen;

HBRUSH
hRedBrush,hBlueBrush,hYellowBrush,hGreenBrush,hVioletBrush,hOrangeBrush;
hBluePen = CreatePen ( PS_SOLID, 1, RGB(255,0,255) );
hRedPen = CreatePen ( PS_SOLID, 1, RGB(255,0,0) );
hGreenPen = CreatePen ( PS_SOLID, 1, RGB(0,255,0) );
hYellowPen = CreatePen ( PS_SOLID, 1, RGB(255,255,0) );
hVioletPen = CreatePen ( PS_SOLID, 1, RGB(255,0,255) );
hOrangePen = CreatePen ( PS_SOLID, 1, RGB(255,90,0) );
hRedBrush = CreateSolidBrush (RGB(255,0,0));
hBlueBrush = CreateSolidBrush (RGB(0,0,255));
hGreenBrush = CreateSolidBrush (RGB(0,255,0));
hYellowBrush = CreateSolidBrush (RGB(255,255,0));
hVioletBrush = CreateSolidBrush (RGB(255,0,255));
hOrangeBrush = CreateSolidBrush (RGB(255,90,0));
if(j+150>rect.bottom)
{
if(dir==1)a[2][nr]=2;else
}
if(i+150>rect.right)
{
if(dir==2)a[2][nr]=3;else
}
if(j+50<rect.top)
{
if(dir==3)a[2][nr]=4;else
}
if(i+50<rect.left)
{
if(dir==4)a[2][nr]=1;else
}
switch(a[2][nr])
{

a[2][nr]=3;

a[2][nr]=4;

a[2][nr]=1;

a[2][nr]=2;

case 1:{
a[0][nr]++; a[1][nr]++;break;
}
case 2:{
a[0][nr]++; a[1][nr]--;break;
}
case 3:{
a[0][nr]--; a[1][nr]--;break;
}
case 4:{
a[0][nr]--; a[1][nr]++;break;
}
switch(nr)
{
case 0:{SelectObject(hdc,hYellowPen); SelectObject(hdc,hRedBrush); break;}
case 1:{SelectObject(hdc,hBluePen); SelectObject(hdc,hGreenBrush); break;}
case 2:{SelectObject(hdc,hRedPen) ; SelectObject(hdc,hYellowBrush); break;}
case 3:{SelectObject(hdc,hGreenPen); SelectObject(hdc,hBlueBrush); break;}
case 4:{SelectObject(hdc,hOrangePen); SelectObject(hdc,hVioletBrush); break;}
case 5:{SelectObject(hdc,hVioletPen); SelectObject(hdc,hOrangeBrush); break;}
}
Ellipse (hdc,a[0][nr]+50,a[1][nr]+50,a[0][nr]+150,a[1][nr]+150);
DeleteObject(hBluePen);
DeleteObject(hRedPen);
DeleteObject(hYellowPen);
DeleteObject(hGreenPen);
DeleteObject(hVioletPen);
DeleteObject(hOrangePen);
DeleteObject(hRedBrush);

DeleteObject(hGreenBrush);
DeleteObject(hYellowBrush);
DeleteObject(hBlueBrush);
DeleteObject(hVioletBrush);
DeleteObject(hOrangeBrush);
return dir;
}
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Windows - Lab2") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
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 = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
RegisterClass(&wndclass);
hwnd = CreateWindow (szAppName,
TEXT ("Bubble"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;
i=1; dir=1;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
static int cxclient, cyclient;
PAINTSTRUCT ps ;
RECT rect;
GetClientRect(hwnd,&rect);
switch (message)
{
case WM_SIZE:
cxclient=LOWORD(lParam);
cyclient=HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;

[0],rect,0);
[1],rect,1);
[2],rect,2);

InvalidateRect (hwnd,NULL,TRUE);
circle(hwnd,hdc,a[0][0],a[1][0],a[2]
circle(hwnd,hdc,a[0][1],a[1][1],a[2]
circle(hwnd,hdc,a[0][2],a[1][2],a[2]

circle(hwnd,hdc,a[0][3],a[1][3],a[2]

[3],rect,3);

circle(hwnd,hdc,a[0][4],a[1][4],a[2]

[4],rect,4);

circle(hwnd,hdc,a[0][5],a[1][5],a[2]

[5],rect,5);

return 0 ;

Sleep(15);
EndPaint (hwnd, &ps) ;

case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
#include <windows.h>
int i,j,dir;
int a[3][6] ={ {123,343,100,163,232,166},{128,15,129,74,234,255},{1,2,3,4,1,4} };
int circle(HWND hwnd,HDC hdc,int i, int j, int dir, RECT rect,int nr)
{
HPEN
hBluePen,hRedPen,hYellowPen,hGreenPen,hVioletPen,hOrangePen;
HBRUSH
hRedBrush,hBlueBrush,hYellowBrush,hGreenBrush,hVioletBrush,hOrangeBrush;
hBluePen = CreatePen ( PS_SOLID, 1, RGB(255,0,255) );
hRedPen = CreatePen ( PS_SOLID, 1, RGB(255,0,0) );
hGreenPen = CreatePen ( PS_SOLID, 1, RGB(0,255,0) );
hYellowPen = CreatePen ( PS_SOLID, 1, RGB(255,255,0) );
hVioletPen = CreatePen ( PS_SOLID, 1, RGB(255,0,255) );
hOrangePen = CreatePen ( PS_SOLID, 1, RGB(255,90,0) );
hRedBrush = CreateSolidBrush (RGB(255,0,0));
hBlueBrush = CreateSolidBrush (RGB(0,0,255));
hGreenBrush = CreateSolidBrush (RGB(0,255,0));
hYellowBrush = CreateSolidBrush (RGB(255,255,0));
hVioletBrush = CreateSolidBrush (RGB(255,0,255));
hOrangeBrush = CreateSolidBrush (RGB(255,90,0));
if(j+150>rect.bottom)
{
if(dir==1)a[2][nr]=2;else
}
if(i+150>rect.right)
{
if(dir==2)a[2][nr]=3;else
}
if(j+50<rect.top)
{
if(dir==3)a[2][nr]=4;else
}
if(i+50<rect.left)
{
if(dir==4)a[2][nr]=1;else
}
switch(a[2][nr])
{

a[2][nr]=3;

a[2][nr]=4;

a[2][nr]=1;

a[2][nr]=2;

case 1:{
a[0][nr]++; a[1][nr]++;break;
}
case 2:{
a[0][nr]++; a[1][nr]--;break;
}

case 3:{
a[0][nr]--; a[1][nr]--;break;
}
case 4:{
a[0][nr]--; a[1][nr]++;break;
}
}

switch(nr)
{
case 0:{SelectObject(hdc,hYellowPen); SelectObject(hdc,hRedBrush); break;}
case 1:{SelectObject(hdc,hBluePen); SelectObject(hdc,hGreenBrush); break;}
case 2:{SelectObject(hdc,hRedPen) ; SelectObject(hdc,hYellowBrush); break;}
case 3:{SelectObject(hdc,hGreenPen); SelectObject(hdc,hBlueBrush); break;}
case 4:{SelectObject(hdc,hOrangePen); SelectObject(hdc,hVioletBrush); break;}
case 5:{SelectObject(hdc,hVioletPen); SelectObject(hdc,hOrangeBrush); break;}
}
Ellipse (hdc,a[0][nr]+50,a[1][nr]+50,a[0][nr]+150,a[1][nr]+150);
DeleteObject(hBluePen);
DeleteObject(hRedPen);
DeleteObject(hYellowPen);
DeleteObject(hGreenPen);
DeleteObject(hVioletPen);
DeleteObject(hOrangePen);
DeleteObject(hRedBrush);
DeleteObject(hGreenBrush);
DeleteObject(hYellowBrush);
DeleteObject(hBlueBrush);
DeleteObject(hVioletBrush);
DeleteObject(hOrangeBrush);
return dir;

}
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Windows - Lab2") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
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 = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
RegisterClass(&wndclass);
hwnd = CreateWindow (szAppName,
TEXT ("Bubble"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;
i=1; dir=1;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
static int cxclient, cyclient;
PAINTSTRUCT ps ;
RECT rect;
GetClientRect(hwnd,&rect);
switch (message)
{
case WM_SIZE:
cxclient=LOWORD(lParam);
cyclient=HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
InvalidateRect (hwnd,NULL,TRUE);
circle(hwnd,hdc,a[0][0],a[1][0],a[2]
[0],rect,0);
[1],rect,1);
[2],rect,2);
[3],rect,3);
[4],rect,4);

circle(hwnd,hdc,a[0][1],a[1][1],a[2]
circle(hwnd,hdc,a[0][2],a[1][2],a[2]
circle(hwnd,hdc,a[0][3],a[1][3],a[2]
circle(hwnd,hdc,a[0][4],a[1][4],a[2]
circle(hwnd,hdc,a[0][5],a[1][5],a[2]

[5],rect,5);
Sleep(15);
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

Rezultatele de executie :

5. Concluzie:
La elaborarea lucrrii de laborator am luat cunotin cu interfaa GDI i cu cteva funcii
ale sale. Am desenat i redesenat cteva figurii astfel nct s obinem o animaiei.Eu am
afacut vizualizarea a 6 figuri geometrice ce se misca in diferite directii

S-ar putea să vă placă și