Sunteți pe pagina 1din 17

66.

Modurile de mapare. Coordonate de dispozitiv i coordonate


logice. Sistemele de coordonate ale dispozitivului. Vizorul i fereastra.
Folosirea modului de mapare MM_TEXT.
Modurile de mapare
Un atribut al contextului de dispozitiv care afecteaz aproape toate operaiile de desenare din
zona client este modul de mapare" (mapping mode"). Alte patru atribute ale contextului de
dispozitiv - originea ferestrei, originea vizorului (viewport), extensia ferestrei i extensia vizorului sunt strns legate de modul de mapare.
Majoritatea funciilor GDI primesc coordonate sau dimensiuni ca parametri. Iat, ca exemplu,
funcia TextOut:
TextOut (hdc, x, y, szBuffer, iLength) ;
Parametrii x i y indic poziia n care ncepe textul. Parametrul x reprezint poziia pe axa
orizontal, iar parametrul y reprezint poziia pe axa vertical. Deseori, pentru indicarea acestui punct
este folosit notaia (x, y).
n funcia TextOut i, de fapt, n toate funciile GDI, coordonatele sunt furnizate n uniti logice".
Windows trebuie s transforme unitile logice" n uniti de dispozitiv", adic n pixeli. Aceast
transformare este guvernat de modul de mapare, de originile ferestrei, ale vizorului i de extensiile
ferestrei i ale vizorului. De asemenea, modul de mapare stabilete i orientarea axelor x i y, adic
determin sensul n care cresc valorile coordonatelor x i y.
Windows definete opt moduri de mapare. Acestea sunt prezentate n tabelul urmtor, folosind
identificatorii definii n fiierele antet din Windows:
Mod de mapare

Uniti logice

Creterea valorilor axax axay

MM_TEXT
MM_LOMETRIC
MM_HIMETRIC
MM_LOENGLISH
MM_HIENGLISH
MM_TWIPS
MM_ISOTROPIC
MM_ANISOTROPIC

Pixel
0,1 mm
0,01mm
0,01 mei
0,001 inci
1/1440 inci
Arbitrar (x = y)
Arbitrar (x != y)

Spre dreapta
Spre dreapta
Spre dreapta
Spre dreapta
Spre dreapta
Spre dreapta
Selectabil
Selectabil

n jos
n sus
n sus
n sus
nsus
n sus
Selectabil
Selectabil

Putei s selectai modul de mapare folosind funcia SetMapMode:


SetMapMode (hdc, iMapHode) ;
unde iMapMode este unul dintre cei opt identificatori definii pentru modurile de mapare. Putei s
obinei modul de mapare curent folosind funcia GefMapMode:
iMapMode = GetMapMode (hdc) ;
Modul de mapare prestabilit este MM_TEXT. n acest mod de mapare unitile logice sunt aceleai
cu unitile fizice, ceea ce v permite (sau, privind dintr-o alt perspectiv, v foreaz) s lucrai n
pixeli. ntr-un apel al funciei TextOut care arat astfel:
TextOut (hdc, 8, 16, szBuffer, iLength) ;
textul ncepe la o distan de opt pixeli fa de marginea din stnga a zonei client i de 16 pixeli fa
de marginea de sus a acesteia.
Coordonate de dispozitiv i coordonate logice
modul de mapare fiind un atribut al contextului de dispozitiv, are efect numai atunci cnd folosii
funcii GDI care primesc o variabil handle a contextului de dispozitiv ca parametru.
GetSystemMetrics nu este o funcie GDI, aa c va returna n continuare dimensiunile n uniti de
dispozitiv, adic n pixeli. Dei GetDeviceCaps este o funcie GDI care primete ca parametru o
variabil handle a contextului de dispozitiv, Windows continu s returneze uniti de dispozitiv pentru
identificatorii HORZRES i VERTRES, deoarece unul dintre scopurile acestei funcii este s furnizeze
programului dimensiunea n pixeli a dispozitivului.
Totui, valorile din structura TEXTMETRIC pe care le obinei prin apelarea funciei GetTextMetrics
sunt furnizate n uniti logice. Dac modul de mapare este MM_LOENGLISH n momentul apelrii

funciei, GetTextMetrics returneaz limea i nlimea caracterelor, n sutimi de inci. Atunci cnd
apelai funcia GetTextMetrics ca s obinei nlimea i limea caracterelor, modul de mapare
trebuie s fie acelai cu cel pe care l vei folosi atunci cnd afiai textul pe baza acestor dimensiuni
Sistemele de coordonate ale dispozitivului
Atunci cnd folosim ntregul ecran, spunem c lucrm n coordonate ecran". Colul din stnga-sus
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 i SetBrushOrgEx.
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 -folosete coordonatele zonei client". Punctul (0,0)
este colul din stnga-sus al zonei client. Dac obinei un context de dispozitiv cu ajutorul funciei
GetDC 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
ClientToScreen i ScreenToClient. De asemenea, putei obinei poziia i dimensiunea ntregii
ferestre n coordonate ecran folosind funcia GetWindowRect.
Vizorul i fereastra
Modurile de mapare definite n Windows stabilesc modul n care sunt mapate coordonatele logice
specificate n funciile GDI la coordonatele de dispozitiv, pe baza faptului c sistemul de coordonate de
dispozitiv folosit depinde de funcia folosit pentru obinerea contextului de dispozitiv. se spune c
modul de mapare definete maparea coordonatelor de fereastr" (window) -coordonate logice - la
coordonatele vizorului (viewport) - coordonate de dispozitiv.
n alte limbaje pentru interfeele grafice, termenul viewport se refer la o regiune de decupare
(clipping region). Termenul window definete, n general, zona pe care o ocup un program pe ecran.
n timpul discuiilor de fa va trebui s renunm la vechile definiii ale acestor termeni.
Pentru vizor se folosesc coordonatele de dispozitiv (pixeli). De cele mai multe ori, vizorul coincide
cu zona client a ferestrei, dar poate s nsemne i coordonatele ntregii ferestre sau coordonatele
ntregului ecran, dac ai obinut contextul de dispozitiv prin apelarea funciilor GetWindowDC sau
CreateDC. Punctul de coordonate (0, 0) este colul din stnga-sus al zonei client (sau al ferestrei, ori al
ecranului). Valorile coordonatei x cresc ctre dreapta, iar valorile coordonatei y cresc n jos.
Pentru fereastr se utilizeaz coordonatele logice, care pot fi,exprimate n pixeli, milimetri, inci sau
orice alt unitate de msur dorii. Coordonatele logice ale ferestrei sunt specificate la apelarea
funciilor GDI.
Pentru toate modurile de mapare, Windows transform coordonatele ferestrei (coordonate logice)
n coordonate ale vizorului.
Windows poate s transforme i coordonatele vizorului (coordonate de dispozitiv) n coordonate ale
ferestrei (coordonate logice.
Windows include dou funcii care v permit s convertii punctele de dispozitiv n puncte logice i
invers. Funcia urmtoare convertete punctele de dispozitiv n puncte logice:
DPtoLP (hdc, pPoints, iNumber) ;
Variabila pPoints este o matrice de structuri POINT, iar iNumber este numrul de puncte ce
urmeaz s fie convertite. Vei vedea c aceast funcie este foarte util pentru convertirea
dimensiunii zonei client obinute prin apelarea funciei GetClientRect (care returneaz valorile n
uniti de dispozitiv) n coordonate logice:
GetClientRect (hwnd, &rect);
DPtoLP (hdc, (PPoint) &rect, 2);
Funcia urmtoare convertete punctele logice n puncte de dispozitiv:
LPtoDP (hdc, pPoints, iNumber) ;
Folosirea modului de mapare MM_TEXT

Pentru modul de mapare MM_TEXT, originile i extensiile prestabilite sunt urmtoarele:


Originea ferestrei:
Originea vizorului:
Extensia ferestrei:
Extensia vizorului:

(0,
(0,
(1,
(1,

0)
0)
1)
1)

Poate fi modificat
Poate fi modificat
Nu poate fi modificat
Nu poate fi modificat

Raportul din extensia ferestrei i extensia vizorului este 1, aa c nu este necesar nici o operaie
de scalare pentru transformarea coordonatelor logice n coordonate de dispozitiv.
Acest mod de mapare se numete mapare de tip text", nu fiindc este cea mai potrivit pentru
text, ci datorit orientrii axelor. n general, citim textul de la stnga spre dreapta i de sus n jos, iar
n modul de mapare MM_TEXT, valorile cresc n acelai sens:

Windows furnizeaz funciile SetViewportOrgEx i SetWindowOrgEx pentru modificarea originii


vizorului i a ferestrei. Aceste funcii au ca efect deplasarea axelor, astfel nct punctul de coordonate
(0, 0) nu se mai refer la colul din stnga-sus al ecranului. n general, vei folosi ori funcia
SetViewportOrgEx, ori SetWindowOrgEx, dar nu pe amndou.
De exemplu, s presupunem c zona client are limea cxClient i nlimea cyClient. Dac vrei ca
punctul logic de coordonate (0, 0) s se afle n centrul zonei client, putei s apelai funcia urmtoare:
SetViewportOrgEx (hdc, cxClient/2, cyClient/2, NULL) ;
Argumentele funciei SetViewportEx sunt exprimate ntotdeauna n uniti de dispozitiv. Punctul
logic (0, 0) va fi acum mapat la punctul .de dispozitiv (cxClient/2, cyClient/2). Din acest moment
folosii zona client ca i cum ar avea urmtorul sistem de coordonate:

Valorile logice ale axei x sunt cuprinse n intervalul de la -cxClient/2 la +cxClient/2 iar valorile
logice ale axei y sunt cuprinse n intervalul de la -cyClient/2 la +cyClient/2. Colul din dreapta-jos al
zonei client are coordonatele (cxClient/2, cyClient/2). Dac vrei s afiai text ncepnd din colul din
stnga-sus al zonei client, care are coordonatele de dispozitiv (0, 0), trebuie s folosii coordonate
logice negative:
TextOut (hdc, -cxClient/2, -cyClient/2, "Hello", 5) ;

67. Obinerea informaiilor despre culori. PLANES, BITSPIXEL,


NUMCOLORS: Tipul COLORREF.

Obinerea informaiilor despre culori


Pentru afiarea culorilor este nevoie de mai muli bii. Cu ct se folosesc mai muli bii, cu att pot
fi afiate mai multe culori. Sau, mai precis, numrul culorilor care pot fi afiate simultan este egal cu 2
la o putere egal cu numrul de bii folosii. De obicei, biii sunt organizai n planuri de culori - un plan
pentru rou, un plan pentru verde, unul pentru albastru i unul pentru intensitatea culorii. Adaptoarele
video cu 8, 16 sau 24 de bii pentru fiecare pixel au un singur plan de culoare, n care un numr de bii
adiaceni reprezint culoarea fiecrui pixel.
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);
Aceste valori pot fi diferite i n cazul adaptoarelor video care permit ncrcarea paletelor de culori.
Funcia GetDeviceCaps apelat cu parametrul NUMCOLORS returneaz numrul de culori rezervate de
Windows, adic 20. Celelalte 236 de culori pot fi stabilite de program folosind un manager de palete.
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 0 la 255. 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 fiierele antet din Windows
sunt definite mai multe macroinstruciuni pentru lucrul cu valorile RGB. Macroinstruciunea 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:
Dac toate cele trei argumente au valoarea 0, se obine negrul, iar dac au valoarea 255, se
obine albul.
Numrul de culori returnat de funcia GetDeviceCaps reprezint numrul de culori pure pe care le
poate afia dispozitivul respectiv.

68. Obinerea variabilei handle a contextului de dispozitiv. Obinerea


informaiilor despre contextul de dispozitiv.
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.
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 Unii 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. Structura PAINTSTRUCT conine i o structur de tip RECT numit
rcPaint, care definete dreptunghiul ce cuprinde regiunea invalid a zonei client a ferestrei.
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);
Contextul de dispozitiv include, n afar de zona client, bara de titlu a ferestrei, barele de derulare
i chenarul.
O funcie mai general pentru obinerea variabilei handle a unui context de dispozitiv este
CreateDC:
hdc = CreateDC (pszDriver, pszDevice, pszOutput, pData);
[alte linii de program]
DeleteDC (hdc);
De exemplu, putei s obinei variabila handle a contextului de dispozitiv pentru tot spaiul de
afiare, cu urmtorul apel:
hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
Uneori avei nevoie de unele informaii despre un context de dispozitiv fr s desenai nimic. n
aceast situaie putei s obinei o variabila handle a contextului de informaii (information context")
folosind funcia CreateIC. Parametrii sunt aceiai ca i pentru funcia CreateDC:
hdclnfo = CreatelC ("DISPLAY", NULL, NULL, NULL);
[alte linii de program]
DeleteDC (hdclnfo);
Atunci cnd lucrai cu imagini bitmap, poate fi uneori util obinerea unui context de dispozitiv n
memorie":
hdcMem = CreateCompatibleDC (hdc);
[alte linii de program]
DeleteDC (hdcHem)
Acesta este un concept destul de abstract.
Putei s creai un metafiier prin obinerea unui context de dispozitiv pentru metafiiere:
hdcMeta = CreateMetaFile (pszFilename);
[alte linii de program] hmf = CloseMetaFile (hdcMeta);
Obinerea informaiilor despre contextul de dispozitiv
GetDeviceCaps (get device capabilities"):
iValue = GetDeviceCaps (hdc, iIndex) ;
Parametrul iIndex este unul dintre cei 28 de identificatori definii n fiierele antet din Windows. De
exemplu, dac iIndex are valoarea HORZRES funcia GetDeviceCaps returneaz limea dispozitivului
n pixeli; VERTRES returneaz nlimea dispozitivului n pixeli.

69. Parametrul PitchAndFamily. Funcia SetTextAlign.


Pentru fonturile cu dimensiune fix, cxCaps este egal cu cxChar. Pentru fonturile cu dimensiune
variabil, cxCaps este 150% din cxChar. Bitul cel mai puin semnificativ al cmpului tmPitchAndFamily
din structura TEXTMETRIC are valoarea 1 pentru fonturile cu dimensiune variabil i valoarea 0 pentru
fonturile cu dimensiune fix. Programul SYSMETS1 folosete acest bit ca s calculeze valoarea cxCaps
din cxChar:
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
Toate operaiile de desenare n fereastr sunt fcute n timpul prelucrrii mesajului WM_PAINT.
Nu ar fi mai simplu dac am putea s afim o coloan de numere aliniate la dreapta prin
specificarea poziiei n care se termin numerele, n locul poziiei la care ncep acestea? Dup ce
programul SYSMETS apeleaz funcia:
SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
coordonatele transmise funciilor TextOut care urmeaz specific localizarea colului din dreapta-sus al
irului de caractere, n locul colului din stnga-sus.
Funcia TextOut care afieaz coloana de numere are ca al doilea parametru urmtoarea expresie:
cxChar + 22 * cxCaps + 40 * cxChar

Valoarea 40 x cxChar reprezint limea nsumat a coloanelor doi i trei. Dup apelarea funciei
TextOut este apelat din nou funcia SetTextAlign, pentru a readuce la normal modul de aliniere a
textului.

70. Pensule haurate". Stiluri de haura. Funcia CreatePatternBrush.


Putei s creai i o pensul haurat" cu linii orizontale, verticale sau oblice. Acest stil de pensule
este folosit frecvent pentru colorarea barelor din diagrame sau grafice i pentru desenele executate de
plottere. Funcia care creeaz o pensul haurat este:
hBrush = CreateHatchBrush (iHatchStyle, rgbColor) ;
Parametrul iHatchStyle precizeaz aspectul haurii i poate avea una dintre urmtoarele valori:
HS_HORIZONTAL, HS_VERTICAL, HS_FDIAGONAL, HS_BDIAGONAL, HS_CROSS i HS_DIAGCROSS.
Parametrul rgbColor din funcia CreateHatchBrush reprezint culoarea liniilor cu care se face
haurarea. Atunci cnd selectai pensula n contextul de dispozitiv, Windows convertete aceast
culoare n cea mai apropiat culoare pur. Spaiul dintre liniile de haur sunt colorate n funcie de
modul de desenare a fondului i de culoarea fondului, definite n contextul de dispozitiv. Dac modul
de desenare a fondului este OPAQUE, culoarea fondului este folosit pentru umplerea spaiilor dintre
linii, n acest caz, nici liniile de haur, nici culoarea de umplere nu pot fi culori amestecate. Dac
modul de desenare a fondului este TRANSPARENT, Windows deseneaz liniile de haura fr s umple
spaiile dintre acestea.
Deoarece pensulele sunt ntotdeauna imagini bitmap 8x8, aspectul pensulelor haurate va depinde de
rezoluia dispozitivului pe care se face afiarea.
Cu ajutorul funciei CreatePatternBrush putei s creai pensule proprii, bazate pe o imagine
bitmap:
hBrush = CreatePatternBrush (hBitmap) ;

71. Redesenarea zonei client. Ciclul de mesaje. Structura de tip MSG.


Funciile GetMessage, TranslateMessage, DispatchMessage.
Afiarea ferestrei
Dup executarea funciei CreateWindow, fereastra a fost creat de Windows, dar nc nu este
afiat pe ecran. Pentru aceasta mai sunt necesare nc dou apeluri de funcii. Primul este:
ShowWindow (hwnd, iCmdShow) ;
Primul parametru este o variabil handle a ferestrei create de funcia CreateWindow. Al doilea
parametru este variabila iCmdShow, transmis funciei WinMain. Dac iCmdShow este
SW_SHOWNORMAL (egal cu 1), fereastra este afiat normal. Dac iCmdShow este
SW_SHOWMINNOACTIVE (egal cu 7), atunci fereastra nu este afiat, dar numele i pictograma
acesteia apar pe bara de taskuri.
n programul HELLOWIN funcia ShowWindow afieaz fereastra pe ecran. Dac al doilea
parametru al funciei este SW_SHOWNORMAL, Windows terge zona client a ferestrei folosind pensula
specificat n clasa ferestrei. Apelul:
UpdateWindow (hwnd) ;
determin redesenarea zonei client. Acest lucru se face prin trimiterea ctre procedura de
fereastr (funcia WndProc din HELLOWIN.C) a unui mesaj WM_PAINT. Vom vedea imediat cum
trateaz funcia WndProc aceste mesaje.
Ciclul de mesaje
Dup apelarea funciei UpdateWindow, fereastra devine vizibil pe ecran. Programul trebuie s fie
acum pregtit s citeasc intrrile de la mouse i de la tastatur. Windows formeaz o coad de
mesaje" pentru fiecare program rulat concurenial. Atunci cnd apare un eveniment exterior, Windows
convertete acest eveniment ntr-un mesaj pe care l plaseaz n coada de ateptare.
Un program preia mesajele din coada de ateptare prin executarea unei secvene de cod numit
ciclu de mesaje" (message loop"):
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
Variabila msg este o structur de tip MSG, definit n fiierele antet din Windows astfel:
typedef struct tagMSG
{

HWND
hwnd ;
UINT
message ;
WPARAM wParam ;
LPARAM lParam ;
DWORD time ;
POINT
pt ;
}
MSG ,
Tipul de date POINT este tot o structur, definit astfel:
typedef struct tagPOINT
{
LONG x ;
LONG y ;
}
POINT ;
Funcia GetMessage apelat la nceputul ciclului de mesaje preia un mesaj din coada de ateptare:
GetMessage (&msg, NULL, 0, 0)
Acest apel transmite sistemului de operare un pointer, numit msg, la o structur de tip MSG. Al
doilea, al treilea i al patrulea parametru au valoarea NULL sau 0, ceea ce indic faptul c programul
vrea s preia toate mesajele, pentru toate ferestrele create de program. Windows completeaz
cmpurile structurii de mesaje cu urmtorul mesaj din coada de ateptare. Cmpurile acestei structuri
sunt:
hwnd - variabila handle a ferestrei creia i este destinat mesajul. n programul HELLOWIN, aceasta
este aceeai cu valoarea hwnd returnat de funcia CreateWindow, deoarece aceasta este singura
fereastr a programului.
message - identificatorul mesajului. Acesta este un numr folosit pentru identificarea mesajului.
Pentru fiecare mesaj n fiierele antet din Windows este definit un identificator care ncepe cu
prefixul WM_ (window message"). De exemplu, dac poziionai indicatorul mouse-ului n zona
client a programului HELLOWIN i apsai butonul din stnga, Windows va insera n coada de
ateptare un mesaj pentru care cmpul message conine identificatorul WM_LBUTTONDOWN, adic
valoarea 0x0201.
wParam - un parametru pe 32 de bii a crui valoare depinde de mesajul trimis.
lParam - un alt parametru pe 32 de bii dependent de mesaj.
time - momentul inserrii mesajului n coada de mesaje.
pt - coordonatele poziiei mouse-ului n momentul inserrii mesajului n coada de mesaje.
Instruciunea:
TranslateMessage (&msg) ;
retransmite structura msg sistemului de operare, pentru convertirea unor mesaje de la tastatur.
Instruciunea:
DispatchMessage (&msg) ;
ca i funcia TranslateMessage, retransmite structura msg sistemului de operare. Windows trimite apoi
mesajul ctre procedura de fereastr corespunztoare, n vederea prelucrrii - cu alte cuvinte,
Windows apeleaz procedura de fereastr. n programul HELLOWIN, procedura de fereastr este
WndProc. Dup ce prelucreaz mesajul, funcia WndProc pred controlul sistemului de operare, care
nc elaboreaz rspunsul la apelul DispatchMessage. Atunci cnd Windows returneaz controlul
programului HELLOWIN, dup executarea apelului DispatchMessage, ciclul de tratare a mesajelor
continu cu urmtorul apel al funciei GetMessage.
Funcia DispatchMessage transmite mesajul procedurii de fereastr corespunztoare. ntre cele dou
funcii este apelat funcia TranslateMessage, care transform mesajele generate de acionarea
tastelor n mesaje caracter. Dac mesajul este WM_KEYDOWN sau WM_SYSKEYDOWN i dac tasta
apsat, n funcie de starea tastelor de modificare, genereaz un caracter, atunci funcia
TranslateMessage insereaz un mesaj caracter n coada de ateptare.

72. Sistemul i cronometrul. Timpul Windows standard.


Sistemul i cronometrul
Cronometrul din Windows este o extensie relativ simpl a logicii de ceas imple mentat hardware
n calculatoarele personale i n sistemul ROM BIOS. Sistemul ROM BIOS iniializeaz un circuit de
ceas care genereaz o ntrerupere de ceas, numit uneori tact de ceas" sau tact de
cronometru". Aceste ntreruperi sunt generate la fiecare 54,925 milisecunde, adic de 18,2 ori pe

secund. Unele programe scrise pentru MS DOS intercepteaz aceast ntrerupere pentru
implementarea unor ceasuri sau a unor cronometre.
Programele Windows nu fac acest lucru. ntreruperile hardware sunt tratate chiar de sistemul de
operare, aa c aplicaiile nu mai trebuie s fac acest lucru. Pentru fiecare program care creeaz
un cronometru, Windows trateaz ntreruperile de ceas decrementnd contorul transmis prin apelarea
funciei SetTimer. Atunci cnd aceast valoare ajunge la 0, Windows plaseaz n coada de ateptare
a aplicaiei un mesaj WM_TIMER i atribuie contorului valoarea original.
Deoarece programele Windows preiau mesajele WM_TIMER din coada de ateptare nu trebuie s v
facei probleme privind ntreruperea unei operaii de prelucrare prin sosirea unui mesaj WM_TIMER.
Din acest punct de vedere, cronometrul se aseamn cu tastatura i cu mouse-ul: driverul trateaz
evenimentele asincrone generate de ceasul hardware, iar Windows transform aceste evenimente n
mesaje structurate i serializate.
Cronometrul Windows are aceeai rezoluie de 54,925 milisecunde ca i ceasul hardware al
calculatorului, pe care de fapt se bazeaz. Acest lucru are dou implicaii importante:

O aplicaie Windows nu poate s primeasc mesaje WM_TIMER cu o rat mai mare de 18,2
ori/secund dac folosete un singur cronometru.

Intervalul de timp pe care l specificai la apelarea funciei SetTimer este rotunjit la un


multiplu ntreg de tacturi de ceas.

73. Tipul PAINTSTRCUT, MM_TEXT. Regiuni de decupare (clipping region).


Fontul sistem SYSTEM_FONT.
Structura de informaii pentru desenare
Am vorbit anterior despre structura de informaii pentru desenare" (paint information structure")
pstrat de Windows pentru fiecare fereastr. Aceast structur este definit astfel:
typedef struct tagPAINTSTRUCT
{
HDC
hdc;
BOOL
fErase;
RECT
rcPaint;
BOOL
fRestore;
BOOL
fIncUpdate;
BYTE
rgbReserved[32];
}
PAINTSTRCUT;
Windows completeaz cmpurile acestei structuri atunci cnd programul dumneavoastr apeleaz
funcia BeginPaint. Programul poate s foloseasc numai primele trei cmpuri, celelalte fiind folosite
intern de sistemul de operare.
Cmpul hdc reprezint variabila handle a contextului de dispozitiv. Deoarece redundana este tipic
pentru sistemul de operare Windows, valoarea returnat de funcia BeginPaint este aceeai variabil
handle.
n majoritatea cazurilor, cmpul fErase va avea valoarea TRUE (diferit de zero), ceea ce nseamn
c Windows a ters fondul dreptunghiului invalid. Pentru tergerea fondului, Windows folosete
pensula specificat n cmpul hbrBackground al structurii WNDCLASSEX, pe care ai folosit-o la
nregistrarea clasei n timpul iniializrilor, din funcia WinMain. Multe programe Windows folosesc o
pensul de culoare alb:
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
Totui, dac programul invalideaz un dreptunghi din zona client apelnd funcia InvalidateRect,
ultimul parametru al funciei specific dac vrei ca fondul s fie ters. Dac acest parametru este
FALSE (0), Windows nu va terge fondul i cmpul fErase va avea valoarea FALSE.
Cmpul rcPaint al structurii PAINTSTRUCT este o structur de tip RECT. Aa cum ai aflat din
Capitolul 2, structura RECT definete un dreptunghi. Cele patru cmpuri ale structurii sunt left, top,
right i bottom. Cmpul rcPaint al structurii PAINTSTRUCT definete limitele unui dreptunghi invalid,
aa cum se poate vedea n figura 3.1. Valorile sunt date n pixeli, i se raporteaz la colul din stngasus al zonei client a ferestrei. Dreptunghiul invalid este suprafaa pe care ar trebui s o redesenai.
Dei un program Windows ar putea s redeseneze ntreaga zon client a ferestrei de fiecare dat cnd
primete un mesaj WM_PAINT, redesennd numai poriunea ferestrei definit de dreptunghi programul
economisete timp.
Dreptunghiul rcPaint din structura PAINTSTRUCT nu este un simplu dreptunghi invalid, ci un
dreptunghi de decupare" (clipping rectangle). Aceasta nseamn c Windows restricioneaz
desenarea n interiorul dreptunghiului. Atunci cnd folosii variabila handle a contextului de dispozitiv
din structura PAINTSTRUCT, Windows nu deseneaz n afara dreptunghiului rcPaint.
Pentru desenarea n afara dreptunghiului rcPaint n timpul prelucrrii mesajului WM_PAINT, facei
urmtorul apel: InvalidateRect (hWnd, NULL, TRUE); naintea apelrii funciei BeginPaint. Apelul de

mai sus invalideaz ntreaga zon client i terge fondul acesteia. Dac ultimul parametru are
valoarea FALSE, fondul nu este ters i desenul va fi fcut peste ceea ce exist deja.
n Windows exist diferite moduri de mapare care controleaz transformarea coordonatelor logice
transmise funciilor GDI n coordonate fizice ale pixelilor afiai pe ecran. Modul de mapare este definit
n contextul de dispozitiv. Modul de mapare prestabilit este MM_TEXT (folosind identificatorul definit n
fiierele antet Windows). n modul de mapare MM_TEXT, unitile logice sunt aceleai cu unitile
fizice, adic pixelii; ele se raporteaz la colul din stnga-sus al zonei client, iar valorile coordonatei y
cresc pe msur ce cobori n zona client a ferestrei (vezi Figura 3.2). Sistemul de coordonate
MM_TEXT este acelai cu sistemul de coordonate folosit de Windows pentru definirea dreptunghiului
invalid din structura PAINTSTRUCT.
Contextul de dispozitiv definete i o regiune de decupare (clipping region). Aa cum ai vzut,
regiunea prestabilit de decupare este ntreaga zon client, pentru o variabil handle a contextului de
dispozitiv obinut prin apelarea funciei GetDC, sau numai regiunea invalid, pentru o variabil
handle a contextului de dispozitiv obinut prin apelarea funciei BeginPaint. Windows nu afieaz
partea care se afl n afara regiunii de decupare i care aparine irului de caractere, ci numai
poriunile care sunt cuprinse n regiunea de decupare. Scrierea n afara zonei client a unei ferestre
este o operaiune dificil, aa c nu v speriai - nu este posibil s facei acest lucru din greeal.
Fontul sistem
Tot n contextul de dispozitiv este definit i fontul pe care sistemul de operare Windows l folosete
pentru scrierea textului n zona client. Fontul prestabilit este numit font sistem" sau (folosind
identificatorul definit n fiierele antet Windows) SYSTEM_FONT. Fontul sistem este fontul pe care
Windows l folosete pentru textul din barele de titlu, barele de meniu i casetele de dialog.
La nceputurile sistemului de operare Windows, fontul sistem era un font cu dimensiune fix, ceea
ce nseamn c toate caracterele aveau aceeai lime, ca la mainile de scris. ncepnd cu versiunea
Windows 3.0 i continund pan la Windows 95, fontul sistem este un font cu dimensiune variabil,
ceea ce nseamn c fiecare caracter are o alt dimensiune. De exemplu, W" este mai lat dect i".
Este foarte clar c un text scris cu un font avnd dimensiune variabil este mai uor de citit dect un
font cu dimensiune fix.
Fontul sistem este un font de tip rastru", ceea ce nseamn c fiecare caracter este definit ca un
bloc de pixeli. Fontul sistem trebuie proiectat astfel nct pe ecran s ncap cel puin 25 de linii cu
cte 80 de caractere. Aceasta este singura garanie privind compatibilitatea ntre dimensiunea
ecranului i dimensiunea fontului.

74. Umplerea golurilor. Modul de desenare a fondului OPAQUE. Funciile


SetBkColor, SetBkMode.
Umplerea golurilor
Folosirea penielor pentru linii punctate sau pentru linii ntrerupte ridic o ntrebare interesant: ce
se ntmpl cu pauzele dintre puncte sau dintre liniue? Culoarea acestor spaii depinde de atributele
pentru culoarea fondului i de modul de desenare a fondului, definite n contextul de dispozitiv.
Modul prestabilit de desenare a fondului este OPAQUE, ceea ce nseamn c Windows umple
spaiile cu culoarea fondului, care n mod prestabilit este alb. Rezultatele sunt aceleai n cazul
pensulei WHITE_BRUSH, folosit de majoritatea programelor n clasa ferestrei pentru tergerea
fondului.
Putei s schimbai culoarea fondului pentru completarea spaiilor goale dintre linii, prin apelarea
funciei SetBkColor:
SetBkColor (hdc, rgbColor) ;
Ca i n cazul valorii rgbColor folosit pentru culoarea peniei, Windows convertete valoarea
specificat ntr-o culoare pur. Putei s obinei culoarea defint n contextul de dispozitiv prin
apelarea funciei GetBkColor.
De asemenea, putei s mpiedicai colorarea spaiilor stabilind modul TRANSPARENT de desenare
a fondului:
SetBkMode (hdc, TRANSPARENT) ;
Windows va ignora culoarea fondului i nu va mai colora spaiile goale. Modul de desenare a
fondului (TRANSPARENT sau OPAQUE) poate fi obinut cu ajutorul funciei GetBkMode.

75. Utilizarea cronometrului pentru a realiza un ceas.


Obinerea orei i a datei

n funcia WndPaint, programul DIGCLOCK folosete funciile C time i localtime ca s determine


data i ora curente. Funcia localtime stocheaz toate informaiile de care avem nevoie ntr-o
structur; mai multe macroinstruciuni definite n partea superioar a programului fac apelurile
funciei wsprintf mai uor de citit.

Internaionalizarea programului
Windows asigur suportul pentru internaionalizarea programelor. Fiierul WIN .INI - creat n timpul
instalrii sistemului de operare - conine o seciune cu titlul [intl]. n aceast seciune sunt incluse
informaii legate de formatul datei, al orei, al monedei naionale i al numerelor. Putei s afiai data
n unul dintre urmtoarele trei formate: lun-zi-an, an-lun-zi sau zi-lun-an. Separatorul dintre cele
trei numere poate fi caracterul slash, liniua de desprire, punctul sau orice alt caracter dorii.
Putei s afiai ora n formatul pe 12 sau pe 24 de ore; de obicei, pentru separarea orelor,
minutelor sau a secundelor este folosit caracterul dou puncte.
Funcia Setlnternational din programul DIGCLOCK obine informaii de formatare din fiierul WIN.INI
folosind funciile GetProfilelnt (pentru numere ntregi) i GetProfileString (pentru iruri de caractere).
La apelarea acestor funcii trebuie s fie incluse valori prestabilite, pentru cazurile n care Windows
nu poate gsi valorile cutate n fiierul WIN.INI. Funcia Setlnternational stocheaz valorile obinute
n variabile globale care au ca nume irurile de caractere folosite n fiierul WIN.INI pentru
identificarea valorilor respective. Funcia WndPaint folosete valorile obinute din fiierul WIN.INI
pentru formatarea datei i a orei afiate, apoi apeleaz funcia DrawText pentru centrarea celor
dou linii de text n fereastr.
Aa cum este de ateptat, de fiecare dat cnd procedura de fereastr primete un mesaj
WM_TIMER, programul DIGCLOCK invalideaz fereastra pentru generarea unui mesaj WM_PAINT. Dar
funcia WndProc invalideaz fereastra i atunci cnd primete un mesaj WM_WININICHANGE. Orice
program care modific fiierul WIN.INI trimite mesaje WM_WININICHANGE tuturor aplicaiilor Windows
active.
Atunci cnd primete un mesaj WM_TIMER, programul DIGCLOCK invalideaz fereastra astfel:
InvalidateRect (hwnd, NULL, FALSE) ;
Valoarea TRUE folosit pentru ultimul parametru al funciei InvalidateRect determin tergerea
fondului ferestrei nainte de redesenare. Dac acest parametru are valoarea FALSE, Windows
deseneaz peste fondul existent. Am folosit valoarea FALSE n timpul prelucrrii mesajului
WMTIMER pentru reducerea efectului de licrire a imaginii afiate.
La recepionarea unui mesaj WM_TIMER, cea mai mare modificare a lungimii este de dou caractere
- de exemplu, atunci cnd data se schimb de la 12/31 /96 la 1 /1 /97 - aa c irul de caractere
formatat folosit pentru afiare de funcia WndPaint are la fiecare capt dou spaii suplimentare,
acoperitoare pentru aceast modificare n lungime i pentru diferenele datorate folosirii unui font
proporional. Am putea s includem n programul DIGCLOCK i logica de prelucrare a mesajelor WM
TIMECHANGE, care informeaz aplicaiile privind modificarea datei sau a orei sistemului. Deoarece
informaiile deinute de programul DIGCLOCK sunt actualizate la fiecare secund prin mesaje
WM_TIMER, acest lucru nu este necesar. Prelucrarea mesajelor WM_TIMECHANGE ar avea sens pentru
un ceas actualizat la fiecare minut.

76. Utilizarea cronometrului pentru animaii.


ANIMAII
Programul BOUNCE reconstruiete mingea de fiecare dat cnd programul primete un mesaj
WM_SIZE. Pentru aceasta este nevoie de un context de dispozitiv compatibil cu monitorul video:
hdcMem = CreateCompatibleDC (hdc) ;
Diametrul mingii este 1/16 din minimul dintre limea i nlimea zonei client a ferestrei. Totui,
programul construiete o imagine bitmap mai mare dect mingea: pe fiecare dintre cele patru
laturi imaginea bitmap este mai mare dect mingea, cu jumtate din raza acesteia:
hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal) ;
Dup ce este selectat n contextul de dispozitiv din memorie, ntreaga imagine bitmap este
colorat cu alb, pentru obinerea fondului:
Rectangle (hdcMem, -1, -1, xTotal + 1, yTotal + 1) ;
n contextul de dispozitiv din memorie este selectat o pensul cu haur diagonal, apoi este
desenat mingea, n centrul imaginii bitmap:
Ellipse (hdcMem, xMove, yMove, xTotal - xMove, yTotal - yMove) ;

Spaiile libere pstrate n imaginea bitmap n jurul mingii terg imaginea anterioar a mingii atunci
cnd mingea este mutat. Pentru redesenarea mingii ntr-o alt poziie este nevoie doar de apelarea
funciei BitBlt folosind codul ROP2RCCOPY:
BitBlt (hdc, xCenter - xTotal / 2, yCenter - yTotal / 2, xTotai, yTotal, hdcMem, 0,
0, SRCCOPY) ;
Programul BOUNCE ilustreaz cea mai simpl cale de deplasare a unei imagini pe ecran, dar
acest mod de abordare nu este satisfctor n toate situaiile. Dac v intereseaz animaiile, v-ar fi
de folos examinarea celorlalte coduri ROP (cum ar fi SRCINVERT) care efectueaz operaii SAU
EXCLUSIV ntre surs i destinaie. Alte tehnici de animaie implic folosirea paletei Windows (i a
funciei AnimatePalette) precum i a funciei CreateDIBSection.

77. Utilizarea cronometrului. Prima metod.

Prima metod
Prima metod (i cea mai simpl) determin sistemul de operare s trimit mesajele WM_TIMER
ctre procedura de fereastr normal a aplicaiei. Apelul funciei SetTimer arat astfel:
SetTimer (hwnd, 1, iMsecInterval, NULL);
Primul parametru este o variabil handle pentru fereastra a crei procedur de fereastr va
primi mesajele WM_TIMER. Al doilea parametru este identificatorul cronometrului, care trebuie s
fie o valoare diferit de zero i care n acest exemplu este n mod arbitrar 1. Al treilea parametru
este o valoare ntreag fr semn pe 32 de bii, care specific intervalul de timp n milisecunde.
Dac acest parametru are valoarea 60000, programul va primi un mesaj WM_TIMER la fiecare minut.
Putei s oprii generarea mesajelor WM_TIMER n orice moment, chiar i n timpul prelucrrii unui
mesaj WM_TIMER, apelnd funcia:
KillTimer (hwnd, 1);
Al doilea parametru al funciei KillTimer este acelai identificator cu cel folosit la apelarea funciei
SetTimer. naintea terminrii programului, ca rspuns la mesajul WM_DESTROY, este recomandat
s distrugei toate cronometrele active din program.
Atunci cnd procedura de fereastr primete un mesaj WM_TIMER, parametrul wParam conine
identificatorul cronometrului (care n acest caz este 1) iar parametrul lParam este 0. Dac avei
nevoie de mai multe cronometre, folosii un identificator unic pentru fiecare. Valoarea parametrului
wParam va diferenia mesajele WM_TIMER trimise ferestrei. Pentru ca programul s fie mai uor de
citit, putei s folosii instruciuni define pentru definirea identificatorilor fiecrui cronometru:

Dac vrei s schimbai intervalul de timp al unui cronometru existent, oprii cronometrul i apelai
din nou funcia SetTimer:
KillTimer (hwnd, 1);
SetTimer (hwnd, 1, iMsecInterval, NULL);

78. Utilizarea cronometrului. Metoda a doua.


A doua metod
A doua metod v permite s folosii un cronometru astfel nct Windows s trimit mesajele
WM_TIMER ctre o alt funcie din program.
Funcia care recepioneaz mesajele de cronometru este numit funcie cu apel invers
(callback). Aceasta este o funcie din program care poate fi apelat direct de sistemul de operare.
Programul comunic sistemului de operare adresa funciei, iar sistemul de operare Windows
apeleaz ulterior funcia.
Ca i procedurile de fereastr, funciile cu apel invers trebuie s fie definite de tipul CALLBACK,
deoarece sunt apelate de Windows din afara spaiului de cod al programului. Parametrii transmii
funciilor cu apel invers i valoarea returnat de acestea depind de scopul funciei. n cazul unei
funcii cu apel invers asociate unui cronometru, parametrii de intrare sunt aceiai cu parametrii de
intrare ai unei proceduri de fereastr. Funciile cu apel invers folosite pentru cronometre nu
returneaz nici o valoare ctre sistemul de operare.
Presupunem c funcia cu apel invers se numete TimerProc. (Putei s dai orice nume dorii.)
Aceast funcie va prelucra numai mesajele WM_TIMER.
VOID CALLBACK TimerProc (HWND hwnd, UINT iMsg, UINT iTimerlD, DWORD dwTime)
[prelucreaz mesajele WM_TIMER]
Parametrul de intrare hwnd reprezint variabila handle a ferestrei specificate la apelarea funciei
SetTimer. Windows va trimite funciei TimerProc numai mesajele WM_TIMER, aa c parametrul
iMsg va avea ntotdeauna valoarea WM_TIMER. Parametrul iTimerlD conine identificatorul
cronometrului, iar parametrul dwTime reprezint timpul sistemului.
Aa cum am menionat anterior, prima metod de pornire a unui cronometru impune
apelarea funciei SetTimer n felul urmtor:
SetTimer (hwnd, iTimerlD, iHsednterval, NULL) ;

Atunci cnd folosii o funcie cu apel invers pentru prelucrarea mesajelor WM_TIMER, al
patrulea parametru al funciei SetTimer trebuie s conin adresa funciei cu apel invers, ca n
exemplul urmtor:
SetTimer (hwnd, iTimerlD, iHsednterval, (TIMERPROC) TimerProc) ;

79. Utilizarea cronometrului. Metoda a treia.


A treia metod
A treia metod este asemntoare cu cea de-a doua, cu diferena c parametrul hwnd din apelul
funciei SetTimer are valoare NULL, iar al doilea parametru (care ar fi trebuit sa fie identificatorul
cronometrului) este ignorat. Rezultatul este faptul c funcia SetTimer returneaz un identificator
al cronometrului:
iTimerID = SetTimer (NULL, 0, iMsecInterval, (TIMERPROC) TimerProc) ;
Variabila iTimerID returnat de funcia SetTimer va avea valoarea NULL dac nu este disponibil nici
un cronometru.
Primul parametru al funciei KillTimer (de obicei folosit pentru transmiterea variabilei handle a
ferestrei) trebuie s aib valoarea NULL. Al doilea parametru (identificatorul cronometrului) trebuie
s fie valoarea returnat de funcia SetTimer:
KillTimer (NULL, iTimerlD) ;
Parametrul hwnd transmis funciei TimerProc trebuie s aib tot valoarea NULL.
Aceast metod de pornire a cronometrelor este rareori folosit. Se poate dovedi totui util
dac folosii n program mai multe cronometre n diferite puncte, i nu vrei s inei socoteala
identificatorilor pe care deja i-ai folosit.
Acum tii s folosii cronometrele din Windows, aa c este timpul s vedei cteva programe utile.

80. Variabilele handle. Notaia ungar. Punctul de intrare n program.


nregistrarea clasei de fereastr. Crearea ferestrei. Afiarea ferestrei.
Muli programatori Windows folosesc notaia ungar", o convenie de denumire a variabilelor.
Convenia este foarte simpl - fiecare nume de variabil ncepe cu una sau mai multe litere mici care
specific tipul de date al variabilei. De exemplu, prefixul sz al variabilei szCmdLine semnific ir de
caractere terminat cu zero". Prefixul h al variabilelor hInstance i hPrevInstance nseamn variabil
handle"; prefixul i al variabilei iCmdShow nseamn ntreg". De exemplu, n funcia WinMain din
programul HELLOWIN.C, variabila msg este o structur de tip MSG iar wndclass este o variabil de tip
WNDCLASSEX. n funcia WndProc, ps este o structur de tip PAINTSTRUCT iar rect este o structur de
tip RECT.
Prefix Tip de date
c
char
by
BYTE (unsigned char)
i
int
x, y
int (folosit pentru coordonate)
cx, cy
int (folosit pentru dimensiuni pe axele x si y, c vine de la contor")
b sau f BOOL (int); f vine de la flag" (indicator)
w
WORD (unsigned short)
l
LONG (long)
fn
funcie
s
ir de caractere
sz
sir de caractere terminat cu zero
h
variabil handle
p
pointer
n sfrit, n program sunt folosii trei identificatori cu majuscule pentru diferite tipuri de variabile
handle:
Identificator Semnificaie
HINSTANCE
Variabil handle a unei instane" - programul nsui
HWND
Variabil handle a unei ferestre
HDC
Variabil handle a unui context de dispozitiv

O variabil handle este pur i simplu un numr (de obicei pe 32 de bii) care face trimitere la un
obiect. Un program obine aproape ntotdeauna o variabil apelnd o funcie Windows. Programul
folosete apoi variabila handle obinut pentru trimiterea la obiect n alte funcii. Valoarea real a
variabilei handle nu este important pentru program, dar modulul Windows care o furnizeaz
programului tie cum s l manipuleze pentru trimiterea la obiect.
Punctul de intrare ntr-un program Windows este o funcie numit WinMain. Funcia WinMain este
ntotdeauna definit astfel:
int WINAPI WinMain (HINSTANCE hinstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int
iCmdShow)
Aceast funcie folosete secvena de apelare WINAPI i la terminare returneaz sistemului de
operare o valoare ntreag. Numele funciei trebuie s fie WinMain. Aceast funcie are patru
parametri:
Parametrul hlnstance este numit variabil handle a instanei" (instance handle"). Acesta este un
numr care identific n mod unic toate programele rulate n Windows. Utilizatorul poate rula simultan
mai multe copii ale aceluiai program. Aceste copii se numesc instane" i fiecare are o valoare
diferit pentru parametrul hlnstance.
hPrevInstance (previous instance" - instana anterioar) este un parametru nvechit. n versiunile
Windows anterioare acest parametru coninea variabila handle a celei mai recente instane nc activ
a aceluiai program. Dac nu erau ncrcate alte instane ale programului, hPrevInstance avea
valoarea 0 sau NULL.
Parametrul szCmdLine este un pointer la un ir de caractere terminat cu zero care conine
eventualii parametri transmii programului n linia de comand.
Parametrul iCmdShow este un numr care indic modul iniial de afiare a ferestrei n Windows. n
majoritatea cazurilor, iCmdShow are valoarea 1 sau 7. Mai sugestivi sunt identificatorii
SW_SHOWNORMAL (definit n Windows ca 1) i SW_SHOWMINNOACTIVE (definit cu valoarea 7).
Prefixul SW vine de la show window" (afiare fereastr). Acest parametru specific dac fereastra
programului este afiat normal sau dac este afiat iniial doar ca o pictogram.
nregistrarea clasei de fereastr
O fereastr este ntotdeauna creat pe baza unei clase de fereastr. Aceasta identific procedura
de fereastr care prelucreaz toate mesajele trimise ctre fereastr.
Pe baza aceleiai clase pot fi create mai multe ferestre. De exemplu, toate butoanele din Windows
sunt create pe baza unei singure clase de fereastr. Aceasta definete procedura de fereastr i alte
caracteristici ale ferestrei create pe baza clasei respective. Atunci cnd creai o fereastr, definii i
atributele suplimentare ale acesteia, care sunt unice pentru fereastra respectiv.
nainte de a crea fereastra programului trebuie s nregistrai o clas de fereastr, apelnd funcia
RegisterClassEx.
Funcia RegisterClassEx accept un singur parametru: un pointer la o structur de tipul
WNDCLASSEX. Structura WNDCLASSEX este definit n fiierele antet din Windows astfel:
typedef
struct tagWNDCLASSEX
{
UINT
cbSize ;
UINT
style ;
WNDPROC
lpfnWndProc ;
int
cbClsExtra ;
int
cbWnExtra ;
HINSTANCE hinstance ;
HICON
hicon ;
HCURSOR
hCursor ;
HBRUSH
hbrBackground ;
LPCSTR
lpszMenuName ;
LPCSTR
lpszClassName ;
HICON
hIconSm ;
}
WNDCLASSEX ;
n funcia WinMain trebuie s definii o structur de tipul WNDCLASSEX, cum ar fi:
WNDCLASSEX wndclass ;
Apoi definii cele 12 cmpuri ale structurii i apelai funcia RegisterClassEx:

RegisterClassEx (&wndclass) ;
Cele mai importante cmpuri ale structurii sunt al treilea i penultimul. Penultimul cmp conine
numele clasei de fereastr. Al treilea cmp (lpfnWndProc) este adresa procedurii de fereastr folosit
pentru toate ferestrele create pe baza acestei clase. Celelalte cmpuri descriu caracteristicile tuturor
ferestrelor create pe baza acestei clase.
cbSize reprezint dimensiunea structurii.
wndclass.style = CS_HREDRAW | CS_VREDRAW ; combin doi identificatori pentru stilul de clas".
Acestea sunt constante pe 32 de bii n care un singur bit are valoarea 1. Cei doi
identificatori pentru stilul clasei indic faptul c toate ferestrele create pe baza
acestei clase sunt redesenate complet, ori de cte ori se modific dimensiunea pe
orizontal (CS_HREDRAW) sau cea pe vertical (CS_VREDRAW) a ferestrei
wndclass.lpfnWndProc = WndProc ; Aceast instruciune stabilete ca procedur de fereastr
funcia WndProc. Aceast procedur va prelucra toate mesajele trimise ctre
toate ferestrele create pe baza acestei clase de fereastr. Aa cum am artat
mai sus, prefixul lpfn nseamn, n notaia ungar, pointer de tip long la o
funcie".
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ; rezerv un spaiu suplimentar n structura clasei i n structura
ferestrei, pstrat n interiorul
sistemului de Windows. Un program
poate s utilizeze spaiul suplimentar n scopuri proprii.
wndclass.hInstance = hinstance ; variabila handle a instanei
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; definesc o pictogram pentru ferestrele
create pe baza acestei clase. Pictograma este o mic imagine de tip bitmap care apare n bara de
taskuri a sistemului de operare i n bara de titlu a ferestrei. Pentru obinerea unei variabile handle a
unei pictograme predefinite apelai funcia LoadIcon cu primul parametru avnd valoarea NULL. Nu ne
intereseaz valoarea real a acestei variabile, ci doar o stocm n cmpurile hIcon i hIconSm.
wndclass.hCursor = LoadCursor (NULL, IDC_ ARROW) ; Funcia LoadCursor ncarc un cursor
predefinit pentru mouse, numit IDC_ARROW, i returneaz o variabil handle a acestui cursor. Atunci
cnd este deplasat deasupra zonei client a ferestrei create pe baza acestei clase, indicatorul mouseului este afiat sub forma unei sgei.
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); precizeaz culoarea
fondului zonei client a ferestrelor create pe baza acestei clase. Prefixul hbr al numelui hbrBackground
vine de la handle to a brush".
Funcia GetStockObject returneaz o variabil handle a unei pensule albe.
wndclass.lpszMenuName = NULL ; meniul ferestrei
wndclass.IpszClassName = szAppName ;
Se nregistreaz clasa de ferestre prin apelarea funciei RegisterClassEx. Singurul parametru al
funciei este un pointer ctre structura WNDCLASSEX:
RegisterClassEx (&wndclass) ;
Crearea ferestrei
Clasa de fereastr definete caracteristicile generale ale unei ferestre, permind astfel folosirea
aceleiai clase pentru crearea mai multor ferestre.
hwnd =CreateWindow (szAppName,
"The Hello Program",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USE DEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hlnstance,
NULL) ;

//
//
//
//
//
//
//
//
//
//
//

numele clasei de fereastra


titlul ferestrei
stilul ferestrei
poziia iniiala pe axa x
poziia iniiala pe axa y
dimensiunea iniiala pe axa x
dimensiunea iniiala pe axa y
variabila handle a ferestrei printe
variabila handle a meniului
variabila handle a instanei programului
parametri de creare

Fereastra creat de acest program este o fereastr normal suprapus, cu o bar de titlu; n partea
stng a barei de titlu se afl caseta cu meniul sistem; n partea dreapt se afl butoanele de mrire,
de micorare i de nchidere; fereastra are un chenar ngroat, care permite redimensionarea. Acesta
este stilul standard al ferestre lor, numit WS_OVERLAPPEDWINDOW; n funcia CreateWindow i
corespunde comentariul stilul ferestrei". Titlul ferestrei" este textul afiat n bara de titlu.
Parametrii notai cu poziia iniial pe axa x" i poziia iniial pe axa y" specific poziia iniial a
colului din stnga-sus al ferestrei, relativ la colul din stnga-sus al ecranului. Prin folosirea
identificatorului CW_USEDEFAULT pentru aceti para metri indicm sistemului de operare s

foloseasc valorile prestabilite pentru o fereastr suprapus. Parametrii dimensiunea iniial pe axa
x" i dimensiunea iniial pe axa y" specific dimensiunile iniiale ale ferestrei. Identificatorul
CW_USEDEFAULT indic sistemului de operare s foloseasc valorile prestabilite.
Parametrul indicat ca variabil handle a ferestrei printe" are valoarea NULL, deoarece aceast
fereastr nu are nici o fereastr printe. Atunci cnd ntre dou ferestre exist o relaie printedescendent, fereastra descendent este afiat ntotdeauna pe suprafaa ferestrei printe. Parametrul
indicat ca variabil handle a meniului" are tot valoarea NULL, deoarece fereastra nu are meniu.
Parametrul indicat ca variabil handle a instanei programului" are ca valoare variabila handle
transmis programului ca parametru la apelarea funciei WinMain. n sfrit, parametrul de creare"
are valoarea NULL.
Funcia Create Window returneaz o variabil handle a ferestrei create. Aceasta este salvat n
variabila hwnd, definit ca fiind de tipul HWND (variabil handle a unei ferestre). Orice fereastr din
Windows are o variabil handle. Programul folosete variabila handle pentru indicarea ferestrei. Dac
un program creeaz mai multe ferestre, fiecare are o variabil handle diferit.
AFIAREA FERESTREI
Dup executarea funciei CreateWindow, fereastra a fost creat de Windows, dar nc nu este
afiat pe ecran. Pentru aceasta mai sunt necesare nc dou apeluri de funcii. Primul este:
ShowWindow (hwnd, iCmdShow) ;
Primul parametru este o variabil handle a ferestrei create de funcia CreateWindow. Al doilea
parametru este variabila iCmdShow, transmis funciei WinMain. Dac iCmdShow este
SW_SHOWNORMAL (egal cu 1), fereastra este afiat normal. Dac iCmdShow este
SW_SHOWMINNOACTIVE (egal cu 7), atunci fereastra nu este afiat, dar numele i pictograma
acesteia apar pe bara de taskuri.
Apelul:
UpdateWindow (hwnd) ;
determin redesenarea zonei client. Acest lucru se face prin trimiterea ctre procedura de
fereastr a unui mesaj WM_PAINT.

81. CONSTRUIREA INTERFEEI UTILIZATOR. Ferestre. Controale


Ferestre
Spaiul Forms ne ofer clase specializate pentru: creare de ferestre sau formulare
(System.Windows.Forms.Form),
elemente
specifice
(controale)
cum
ar
fi
butoane
(System.Windows.Forms.Button), casete de text (System.Windows.Forms.TextBox) etc.
Proiectarea unei ferestre are la baz un cod complex, generat automat pe msur ce noi desemnm
componentele i comportamentul acesteia. n fapt, acest cod realizeaz: derivarea unei clase proprii
din System.Windows.Forms.Form, clas care este nzestrat cu o colecie de controale (iniial
vid). Constructorul ferestrei realizeaz instanieri ale claselor Button, MenuStrip,
Timer etc. (orice plasm noi n fereastr) i adaug referinele acestor obiecte la colecia de controale
ale ferestrei. Dac modelul de fereastr reprezint ferestra principal a aplicaiei, atunci ea este
instaniat automat n programul principal (metoda Main). Dac nu, trebuie s scriem noi codul care
realizeaz instanierea. Clasele derivate din Form motenesc o serie de proprieti care determin
atributele vizuale ale ferestrei (stilul marginilor, culoare de fundal, etc.), metode care implementeaz
anumite comportamente (Show, Hide, Focus etc.) i o serie de metode specifice (handlere) de tratare
a evenimentelor (Load, Click etc.). O fereastr poate fi activat cu form.Show() sau cu
form.ShowDialog(), metoda a doua permind ca revenirea n fereastra din care a fost activat noul
formular s se fac numai dup ce noul formular a fost nchis (spunem c formularul nou este deschis
modal). Un propietar este o fereastr care contribuie la comportarea formularului deinut. Activarea
propietarului unui formular deschis modal va determina activarea formularului deschis modal. Cnd un
nou formular este activat folosind form.Show() nu va avea nici un deintor, acesta stabilinduse
direct : Formularul deschis modal va avea un proprietar setat pe null. Deintorul se poate stabili
setnd proprietarul nainte s apelm Form.ShowDialog() sau apelnd From.ShowDialog() cu
proprietarul ca argument.
Vizibilitatea unui formular poate fi setat folosind metodele Hide sau Show. Pentru a ascunde un
formular putem folosi :
this.Hide(); // setarea propietatii Visible indirect sau StartPosition determin poziia ferestrei atunci
cnd aceasta apare prima dat. Poziia poate fi setat Manual, sau poate fi centrat pe desktop
(CenterScreen), stabilit de Windows, formularul avnd dimensiunile i locaia stabilite de
programator (WindowsDefaultLocation) sau Windows-ul va stabili dimensiunea iniial i locaia
pentru formular (WindowsDefaultBounds) sau, centrat pe formularul care l-a afiat
(CenterParent) atunci cnd formularul va fi afiat modal. Location (X,Y) reprezint coordonatele
colului din stnga sus al formularului relativ la colul stnga sus al containerului. (Aceast propietate
e ignorat dac StartPosition = Manual). Micarea formularului ( i implicit schimbarea locaiei) poate
fi tratat n evenimentele Move i LocationChanged . Locaia formularului poate fi stabilit relativ la
desktop astfel: Size (Width i Height) reprezint dimensiunea ferestrei. Cnd se schimb

propietile Width i Height ale unui formular, acesta se va redimensiona automat, aceast
redimensionare fiind tratat n evenimentele Resize sau in SizeChanged. Chiar dac propietatea
Size a formularului indic dimensiunea ferestrei, formularul nu este n totalitate responsabil pentru
desenarea ntregului coninut al su. Partea care este desenat de formular mai este denumit i
Client Area. Marginile, titlul i scrollbar-ul sunt desenate de Windows. MaxinumSize i
MinimumSize sunt utilizate pentru a restriciona dimensiunile unui formular. ControlBox
precizeaz dac fereastra conine sau nu un icon, butonul de nchidere al ferestrei i meniul System
(Restore,Move,Size,Maximize,Minimize,Close). HelpButton-precizeaz dac butonul va aprea sau
nu lng butonul de nchidere al formularului (doar dac MaximizeBox=false, MinimizeBox=false).
Dac utilizatorul apas acest buton i apoi apas oriunde pe formular va aprea evenimentul
HelpRequested (F1). Icon reprezint un obiect de tip *.ico folosit ca icon pentru formular.
MaximizeBox i MinimizeBox precizeaz dac fereastra are sau nu butonul Maximize i respectiv
Minimize Opacity indic procentul de opacitate ShowInTaskbar precizeaz dac fereastra apare in
TaskBar atunci cnd formularul este minimizat. SizeGripStyle specific tipul pentru Size Grip
(Auto, Show, Hide). Size grip (n colul din dreapta jos) indic faptul c aceast fereastr poate fi
redimensionat. TopMost precizeaz dac fereastra este afisat n faa tuturor celorlalte ferestre.
TransparencyKey identific o culoare care va deveni transparent pe form. Definirea unei funcii de
tratare a unui eveniment asociat controlului se realizeaz prin selectarea grupului Events din ferestra
Properties a controlului respectiv i alegerea evenimentului dorit. Dac nu scriem nici un nume pentru
funcia de tratare, ci efectum dublu clic n csua respectiv, se genereaz automat un nume pentru
aceast funcie, innd cont de numele controlului i de numele evenimentului (de exemplu
button1_Click). Dac n Designer efectum dublu clic pe un control, se va genera automat o funcie
de tratare pentru evenimentul implicit asociat controlului (pentru un buton evenimentul implicit este
Clic, pentru TextBox este TextChanged, pentru un formular Load etc.). Printre evenimentele cele mai
des utilizate, se numr :
Load apare cnd formularul este pentru prima data ncrcat n memorie.
FormClosed apare cnd formularul este nchis.
FormClosing apare cnd formularul se va inchide ca rezultat al aciunii utilizatorului asupra
butonului Close (Dac se seteaz CancelEventArgs.Cancel =True atunci se va opri
nchidereaformularului).
Activated apare pentru formularul activ.
Deactivate apare atunci cnd utilizatorul va da clic pe alt formular al aplicatiei.

Controale
Unitatea de baz a unei interfee Windows o reprezint un control. Acesta poate fi gzduit de un
container ce poate fi un formular sau un alt control. Un control este o instan a unei clase derivate
din System.Windows.Forms i este reponsabil cu desenarea unei pri din container. Visual
Studio .NET vine cu o serie de controale standard, disponibile n Toolbox. Aceste controale pot fi
grupate astfel: Controale form. Controlul form este un container. Scopul su este de a gzdui alte
controale. Folosind proprietile, metodele i evenimentele unui formular, putem personaliza
programul nostru. n tabelul de mai jos vei gsi o list cu controalele cel mai des folosite i cu
descrierea lor. Exemple de folosire a acestor controale vor urma dup explicarea proprietilor comune
al controalelor i formularelor.
Button Sunt folosite pentru a executa o secven de instruciuni n momentul activrii lor de ctre
utilizator
calendar MonthCalendar Afieaz implicit un mic calendar al lunii curente. Acesta poate fi derulat i
nainte i napoi la celelalte luni calendaristice.
caset de validare CheckBox Ofer utilizatorului opiunile : da/nu sau include/exclude
etichet Label Sunt folosite pentru afiarea etichetelor de text, i a pentru a eticheta controalele.
caset cu list ListBox Afieaz o list de articole din care utilizatorul poate alege.
imagine PictureBox Este folosit pentru adugarea imaginilor sau a altor resurse de tip bitmap.
pointer Pointer Este utilizat pentru selectarea, mutarea sau redimensionarea unui control.
buton radio RadioButton Este folosit pentru ca utilizatorul s selecteze un singur element dint-un
grup de selecii.
caset de text TextBox Este utilizat pentru afiarea textului generat de o aplicaie sau pentru a primi
datele introduse de la tastatur de ctre utilizator.

82. Proprieti comune ale controalelor i formularelor. Metode i


evenimente.
Proprietatea Text Aceast proprietate poate fi setat n timpul proiectrii din fereastra Properties,
sau programatic, introducnd o declaraie n codul programului.

Proprietile ForeColor i BackColor. Prima proprietate enunat seteaz culoare textului din
formular, iar cea de a doua seteaz culoarea formularului. Toate acestea le putei modifica dup
preferine din fereastra Properties.
Proprietatea AutoSize folosit la controalele Label i Picture, decide dac un control este
redimensionat automat, pentru a-i cuprinde ntreg coninutul.
Proprietatea Enabled determin dac un control este sau nu activat ntr-un formular.
Proprietatea Visible seteaz vizibilitatea controlului.
Proprietatea Width and Height permite setarea nlimii i a limii controlului.
Metode i evenimente
Un eveniment este un mesaj trimis de un obiect atunci cnd are loc o anumit aciune. Aceast
actiune poate fi: interaciunea cu utilizatorul (mouse click) sau interaciunea cu alte entiti de
program. Un eveniment (event) poate fi apsarea unui buton, o selecie de meniu, trecerea unui
anumit interval de timp, pe scurt, orice ce se intampl n sistem i trebuie s primeasc un raspuns
din partea programului. Evenimentele sunt proprieti ale clasei care le public. Cuvantul-cheie event
contoleaz cum sunt accesate aceste proprieti.
Metodele Show() i Close(). Evenimentul Click
Metoda Dispose()
Metodele Clear() i Add()
Metoda ShowDialog()
83.Obiecte grafice. Validarea informaiilor de la utilizator. MessageBox. Interfa definit
de ctre utilizator.
Spaiul System.Drawing conine tipuri care permit realizarea unor desene 2D i au rol deosebit n
proiectarea interfeelor grafice.
Un obiect de tip Point este reprezentat prin coordonatele unui punct ntr-un spaiul bidimensional
Putem construi un obiect de tip Point pentru a redimensiona un alt obiect.
Structura Color conine date, tipuri i metode utile n lucrul cu culori. Fiind un tip valoare (struct) i
nu o clas, aceasta conine date i metode, ns nu permite instaniere, constructori, destructor,
motenire.
nainte ca informaiile de la utilizator s fie preluate i transmise ctre alte clase, este necesar s fie
validate. Acest aspect este important, pentru a preveni posibilele erori. Astfel, dac utilizatorul
introduce o valoare real (float) cnd aplicaia ateapt un ntreg (int), este posibil ca aceasta s se
comporte neprevzut abia cteva secunde mai trziu, i dup multe apeluri de metode, fiind foarte
greu de identificat cauza primar a problemei.
Datele pot fi validate pe msur ce sunt introduse, asociind o prelucrare unuia dintre handlerele
asociate evenimentelor la nivel de control (Leave, Textchanged, MouseUp etc.)
n unele situaii (de exemplu atunci cnd valorile introduse trebuie s se afle ntr-o anumit relaie
ntre ele), validarea se face la sfritul introducerii tuturor datelor la nivelul unui buton final sau la
nchiderea ferestrei de date.
MessageBox este o clas din spaiul de nume System.Windows.Forms, derivat din clasa
Object Show este o metod static din clasa MessageBox n momentul n care se apas butonul
OK, fereastra cu acest mesaj se nchide, metoda Show cednd controlul.
Metoda Show are mai multe forme n clasa MessageBox, fiind supradefinit. Apelul acestei funcii
se va face n funcie de parametri. S considerm acum apelul funciei Show cu doi parametri: al
doilea parametru se va referi la textul care apare pe bara de titlu n fereastr de mesaje:
Sunt multe aplicaii n care, poate, dorim s ne realizm o interfa proprie, ca form, n locul celei
dreptunghiulare propus de Visual C#.
n primul rnd trebuie s ne desenm propria fereastr de viitoare aplicaii. Pentru aceasta vom folosi,
de exemplu, aplicaia Paint.
Desenm o figur geometric care va constitui viitoarea noastr fereastr. Presupunem c dorim ca
fereastra s aib forma de oval. Colorm ovalul cu o culoare dorit, iar pentru fundal alegem orice
culoare, reinnd codul ei RGB Salvm desenul cu extensia gif: oval.gif S trecem acum la Visual C#.
Alegem: File | New Project | Windows Forms Application, iar ca nume InterfataUtilizator Aduc
controlul PictureBox. Din PictureBox Task aleg imaginea care s apar: oval.jpg iar la Size Mode
aleg StretchImage astfel nct imaginea s fie toat n PictureBox Deformez PictureBox-ul astfel
nct ovalul desenat s ocupe o suprafa care s corespund esteticii programatorului

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