pw.14-28,84-86.docx

26

Click here to load reader

Upload: mariana-butucea

Post on 12-Jul-2016

8 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: PW.14-28,84-86.docx

14. Clasa butoanelor. Класс кнопок Clasa butoanelor este o clasă predefinită ce permite crearea controalelor de tip ferestre descendent sub formă de butoane. Existenţa clasei într-unul dintre fişierele Windows permite crearea butoanelor direct prin apelarea funcţiei CreateWindow, nefiind necesară inregistrarea clasei de fereastră.

Clasa butoanelor are o procedură de fereastră (aflată într-una dintre bibliotecile cu legături dinamice ale sistemului de operare) care prelucrează mesajele trimise către ferestrele butoanelor, ceea ce determină ca toate butoanele să reacţioneze într-un mod similar la anumite acţiuni ale utilizatorului(de ex: schimbarea culorii în cazul apasării). Procedura ferestrei buton din Windows execută întreţinerea acestor butoane şi toate operaţiile de redesenare.

Stsitemul de operare este responsabil de interpretarea click-urilor de mouse, redesenarea butonului sau de modul în care butonul se mişcă atunci când este apăsat. Sarcina programatorului este să intercepteze mesajul WM_COMMAND - acesta este modul în care butonul informează procedura ferestrei despre declanşarea unui eveniment.

15.Coduri virtuale de taste. Starea tastelor de modificare. Utilizarea mesajelor de acţionare a tastelor.

Fiecare tastă este identificată de un număr numit cod virtual. Acest cod virtual este conţinut în parametrul wParam al mesajelor WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN. Cel mai des utiizate coduri virtuale sunt definite în fişierele antet din windows, având un nume sepcific precedat de prefixul VK- virtual key. De exemplu: VK_SHIFT, VK_CONTROL şi VK_RETURN sunt codurile virtuale corespunzătoare tastelor Shift, Ctrl şi Enter ale tastaturii.

Starea tastelor de modificare (Shift, Alt, Ctrl) poate fi obţinută cu ajutorul funcţiei GetKeyState. De exemplu: GetKeyState (VK_SHIFT) returnează o valoare negativă (adică un număr în care primul bit are valoarea 1) dacă tasta Shift este apăsată. Valoarea returnată de apelul: GetKeyState (VK_CAPITAL) are un 1 în bitul cel mai puţin semnificativ dacă tasta Caps Lock este activă. Funcţia GetKeyState nu verifică starea tastaturii în timp real, ci starea tastaturii până în momentul mesajului curent. Pentru a obţine starea curentă a unei taste, se foloseşte funcţia GetAsyncKeyState.

Utilizarea mesajelor de acţionare a tastelor: În principiu, este necesar ca în scrierea unui program windows să se ţină cont numai de

mesajele WM_KEYDOWN şi WM_KEYUP, întrucât mesajele WM_SYSKEYUP, WM_SYSKEYDOWN sunt folosite pentru funcţii de sistem (deci nu este necesară interceptarea lor). Mai mult, dacă sunt prelucrate mesajele WM_KEYDOWN, pot fi ignorate mesajele WM_KEYUP.

Programele pentru Windows folosesc mesajele WM_KEYDOWN pentru tastele care nu generează caractere. Folosirea mesajelor pentru acţionări de taste în combinaţie cu informaţiile despre tastele de modificare (furnizate de funcţia GetKeyState) cu scopul de a le transforma în mesaje pentru caractere, poate genera probleme din cauza diferenţelor între tastaturile internaţionale.

Mesajele WM_KEYDOWN sunt utile pentru tastele de deplasare, tastele funcţionale şi tastele speciale, precum Insert, Delete. Uneori tastele Insert, Delete si tastele funcţionale sunt folosite ca acceleratori pentru comenzi de meniu. Deoarece Windows transformă acceleratorii în comenzi de meniu, nu este nevoie să prelucraţi în program mesajele pentru acţionarea tastelor de accelerare. De cele mai multe, mesajele WM_KEYDOWN sunt prelucrate numai pentru tastele de deplasare a cursorului. Unele funcţii Windows folosesc de multe ori tastele de deplasare în combinaţie cu tasta Shift pentru extinderea unei selecţii - de exemplu într-un procesor de texte. Tasta Ctrl este folosită deseori pentru a schimba semnificaţia unei taste de

Page 2: PW.14-28,84-86.docx

deplasare. De exemplu, tasta Ctrl în combinaţie cu săgeata spre dreapta mută cursorul cu un cuvânt la dreapta.

16.Crearea ferestrelor child.

Fereastra descendent prelucrează mesajele primite de la mouse şi de la tastatură şi înştiinţează fereastra părinte atunci când starea proprie se modifică. În acest fel, fereastra descendent devine un dispozitiv de introducere a datelor pentru fereastra părinte. Fereastra descendent încapsulează funcţionalităţi specifice legate de modul de afişare pe ecran, răspunde de datele introduse de utilizator şi metodele de înştiinţare a unei alte ferestre în momentul producerii unui eveniment important. Deşi pot fi create propriile controale de tip fereastră descendent, este mai uşor de a beneficia de avantajele oferite de un set de clase de fereastră (şi proceduri specifice) predefinite, clase pe care programele pot să le folosească pentru crearea unor controale de tip fereastră descendent standard: butoane, casete de validare, casetede editare, casete listă, casete combinate, bare de derulare.

Fiecare fereastră descendent este creată printr-un apel al funcţiei CreateWindow. Poziţia şi dimensiunea pot fi modificate apelând funcţia MoveWindow . Când este folosit unul dintre controalele predefinite, nu este necesară înregistrarea unei clase pentru fereastra descendent. Clasa există deja în Windows şi are unul dintre aceste nume: „button", „static", „scrollbar", „edit", „listbox" sau „combobox". Unul din aceste nume este utilizat ca parametru al funcţiei CreateWindow. Parametrul de stil (style) al funcţiei CreateWindow defineşte mai precis aspectul şi funcţionalitatea controlului de tip fereastră descendent. Sistemul de operare Windows conţine deja procedurile de fereastră pentru prelucrarea mesajelor către fereastra descendent pe baza acestor clase. Procedura ferestrei părinte trimite mesaje către controlul de tip fereastră descendent, iar acesta trimite mesaje către procedura ferestrei părinte.

După apelarea funcţiei CreateWindow nu mai trebuie să facem nimic în legătură cu aceste ferestre descendent. Procedura ferestrei buton din Windows execută întreţinerea acestor butoane şi toate operaţiile de redesenareLa terminarea programului, Windows distruge toate ferestrele descendent odată cu distrugerea ferestrei părinte.

17. Cum poate fi obţinută variabila handle a unui device context? Există mai multe metode de obţinere a variabilei handle de dispozitiv. Prima metodă este legată de tratarea mesajelor WM_PAINT, şi anume, prin apelul funcţiilor BeginPaint şi EndPaint:case WM_PAINT :hdc = BeginPaint (hwnd, &ps) ;[apelarea unor funcţii GDI] EndPaint (hwnd, &ps) ;return 0 ; Aceste funcţii au nevoie de variabila handle a ferestrei (transmisă procedurii de fereastră ca

parametru) şi de adresa unei variabile de tipul PAINTSTRUCT. În timpul prelucrării mesajului WM_PAINT, procedura de fereastră apelează mai întâi funcţia BeginPaint ca să completeze câmpurile structurii ps. Valoarea returnată de funcţia BeginPaint este variabila handle a contextului de dispozitiv. În general, aceasta este salvată într-o variabilă numită hdc de tipul HDC. Tipul de date HDC este definit ca un întreg fără semn, pe 32 de biţi. Apelul funcţiei EndPaint eliberează variabila handle a contextului de dispozitiv.

Page 3: PW.14-28,84-86.docx

O altă metodă de obţinere a variabilei handle a contextului de dispozitiv, utlizată in afara prelucrarii mesajelor WM_PAINT este apelul la funcţia GetDC. Funcţia ReleaseDC eliberează variabila atunci când nu mai este necesară:

hdc = GetDC(hwnd) ;[apelarea unor funcţii GDI] ReleaseDC(hwnd, hdc) ;

La fel ca funcţiile BeginPaint şi EndPaint, şi funcţiile GetDC şi ReleaseDC ar trebui apelate în pereche, în timpul prelucrării aceluiaşi mesaj. Diferenţa dintre cele două metode de obţinere a variabilei hdc este că variabila handle returnată de funcţia GetDC se referă la un dreptunghi cu întreaga zonă client a ferestrei, şi nu doar la un dreptunghi invalid. Spre deosebire de funcţia BeginPaint, GetDC nu validează nici o regiune invalidă.

Un program Windows poate să obţină ş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

Funcţiile BeginPaint, GetDC şi GetWindowDC obţin variabila handle a contextului de dispozitiv asociat unei anumite ferestre de pe ecran. O funcţie mai generală pentru obţinerea variabilei handle a unui context de dispozitiv este CreateDC:

hdc = CreateDC (pszDriver, pszDevice, pszOutput, pData);[alte linii de program] DeleteDC (hdc);

Pentru a obţine o variabila handle a contextului de dispozitiv pentru tot spaţiul de afişare, se utilizează următorul apel:

hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);

18. Curbe Bezier. Funcţia PolyBezierTo. Curbele Bezier îşi datorează numele inginerului Pierre Bezier, angajat al companiei de automobile Renault, care a elaborat un set de formule necesare proiectării la calculator a caroseriilor. De atunci, datorită formei bidimensionale, curba Bezier s-a dovedit a fi cea mai utilă curbă pentru grafica pe calculator. O curbă Bezier este definită prin patru puncte - două capete şi două puncte de control. Capetele curbei sunt ancorate în cele două puncte finale. Punctele de control acţionează ca nişte „magneţi" care deformează linia dreaptă dintre cele două puncte finale.

Funcţiile Bezier sunt considerate utile pentru proiectarea asistată de calculator, datorită câtorva caracteristici:

În primul rând, cu puţină practică, de obicei puteţi să manipulaţi curba până ajunge la o formă apropiată de cea dorită.

În al doilea rând, curbele Bezier sunt foarte uşor de controlat. În unele variante ale funcţiilor spline, curba nu trece prin nici unul din punctele care o definesc. Curbele Bezier, însă, sunt întotdeauna ancorate în cele două puncte finale. (Aceasta este una dintre ipotezele de la care porneşte calculul formulei Bezier.) De asemenea, unele forme ale funcţiilor spline au puncte de singularitate, din care curba se întinde la infinit. În proiectarea asistată de calculator acest lucru

Page 4: PW.14-28,84-86.docx

este de cele mai multe ori evitat. Ca urmare, curbele Bezier sunt întotdeauna limitate de un patrulater (numit „carcasă convexă" - „convex hull") format prin unirea punctelor finale şi a punctelor de control.

În al treilea rând, o altă caracteristică a curbelor Bezier implică relaţiile dintre punctele finale şi punctele de control. Curba este întotdeauna tangentă la linia trasată de la primul punct final la primul punct de control şi are întotdeauna aceeaşi direcţie cu această linie. (Această caracteristică este ilustrată vizual de programul BEZIER.) De asemenea, curba este întotdeauna tangentă la linia trasată de la al doilea punct final la al doilea punct de control şi are întotdeauna aceeaşi direcţie cu această linie. (Acestea sunt alte două ipoteze de la care este derivată formula Bezier.)În al patrulea rând, curbele Bezier sunt satisfăcătoare şi din punct de vedere estetic.

Pentru trasarea mai multor curbe Bezier conexe, se ulizează instrucţiunea:

PolyBezierTo (hdc,pt, iCount) ,

unde pt este o matrice de structuri POINT. Parametrul iCount reprezintă numărul de puncte din matrice, adică unu plus de trei ori numărul curbelor pe care vreţi să le desenaţi.

Funcţia PolyBezierTo foloseşte poziţia curentă ca punct de început pentru prima curbă Bezier. Fiecare curbă desenată are nevoie doar de trei puncte. La returnarea funcţiei, poziţia curentă este punctul final al ultimei curbe desenate.

19. Cursorul de editare (CARET). Funcţii pentru cursorul de editare. Soluţia Unicode pentru Windows.

Atunci când se introduce text într-un program, poziţia în care va apărea următorul caracter este indicată de o liniuţă de subliniere sau de un mic dreptunghi, în Windows pentru acest semn se foloseşte termenul „cursor de editare".

Funcţii pentru cursorul de editare

Există cinci funcţii principale pentru cursorul de editare: CreateCaret - creează un cursor de editare asociat unei ferestre. SetCaretPos - stabileşte poziţia cursorului de editare în fereastră. ShowCaret - afişează cursorul de editare. HideCaret - maschează cursorul de editare. DestroyCaret - distruge cursorul de editare creat.

Mai există şi alte funcţii pentru obţinerea poziţiei cursorului de editare (GetCaretPos) şi pentru stabilirea şi obţinerea intervalelor de licărire a acestuia (SetCaretBlinkTime şi GetCaretBlinkTime).

Cursorul de editare este, de obicei, o linie ori un bloc orizontal de dimensiunea unui caracter, sau o linie verticală. Linia verticală este recomandată în cazul folosirii unui font proportional, cum ar fi fontul sistem prestabilit din Windows. Deoarece caracterele din fonturile proporţionale nu au aceeaşi lăţime, linia sau blocul orizontal nu poate avea lăţimea exactă a unui caracter.

Cursorul de editare nu poate fi creat pur şi simplu în timpul prelucrării mesajului WM_CREATE şi nici distrus în timpul prelucrării mesajului WM_DESTROY. El este ceea ce se numeşte o „resursă de sistem". Aceasta înseamnă că în sistem există un singur cursor de editare. De fapt, atunci când un program trebuie să afişeze un cursor de editare în fereastra proprie, el „împrumută" acest semn de la sistem.

Cursorul de editare este afişat în fereastra care deţine cursorul de intrare (input focus). La un moment dat, o singură fereastră poate deţine cursorul de intrare, aşa că existenţa unui singur cursor de editare este logică.

Page 5: PW.14-28,84-86.docx

Un program poate determina dacă deţine cursorul de intrare prin prelucrarea mesajelor WM_SETFOCUS şi WM_KILLFOCUS. O procedură de fereastră recepţionează un mesaj WM_SETFOCUS atunci când primeşte cursorul de intrare şi un mesaj WM_KILLFOCUS atunci când pierde cursorul de intrare. Aceste mesaje sunt transmise în pereche. O procedură de fereastră primeşte întotdeauna un mesaj WM_SETFOCUS înainte de a primi un mesaj WM_KILLFOCUS şi întotdeauna va primi un număr egal de mesaje WM_SETFOCUS şi WM_KILLFOCUS pană la distrugerea ferestrei.

Principala regulă de folosire a cursorului de editare este simplă. O procedură de fereastră apelează funcţia CreateCaret în timpul prelucrării mesajului WM_SETFOCUS şi funcţia DestroyCaret în timpul prelucrării mesajului WM_KILLFOCUS.

Există şi alte câteva reguli: la creare, cursorul de editare nu este afişat. După apelarea funcţiei CreateCaret, programul trebuie să apeleze funcţia ShowCaret pentru a face vizibil cursorul de editare. În plus, procedura de fereastră trebuie să-l mascheze, apelând funcţia HideCaret, ori de câte ori desenează ceva pe ecran în timpul prelucrării unui alt mesaj decât WM_PAINT. După terminarea operaţiei de desenare, programul apelează funcţia ShowCaret ca să afişeze din nou cursorul de editare. Efectul funcţiei HideCaret este aditiv: dacă s+a apelat funcţia HideCaret de mai multe ori fără a fi apelată funcţia ShowCaret, atunci când se doreşte ca acest cursor de editare să devină din nou vizibil,este necesar apelul funcţiei ShowCaret de tot atâtea ori de cate ori s-a apelat şi funcţia HideCaret.

20. Desenarea suprafeţelor pline. Funcţia Polygon şi modul de umplere a poligoanelor. Funcţia SetPolyFillMode. Umplerea suprafeţelor interioare. Pentru desenarea suprafeţe pline sunt utilizate 7 funcţii windows:

Funcţie Figura

RectangleEllipseRoundRectChord

Dreptunghi cu colţuri drepteElipsăDreptunghi cu colţuri rotunjiteArc pe circumferinţa unei elipse, având capetele unite printr-o coardă

PiePolygon PolyPolygon

Suprafaţă de forma unei felii de plăcintă, reprezentând un segment de elipsă.Figură geometrică având mai multe laturi Mai multe figuri geometrice cu mai multe laturi

Windows desenează conturul figurilor folosind peniţa curentă selectată în contextul de dispozitiv şi umple interiorul lor cu pensula curentă. În mod prestabilit, aceasta este pensula de stoc WHITE_BRUSH, ceea ce înseamnă că interiorul figurilor va fi umplut cu alb. Windows defineşte şase pensule de stoc: WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH şi NULL_BRUSH (sau HOLLOW_BRUSH).

Windows defineşte tipul HBRUSH ca variabilă handle a unei pensule.

Pentru a obţine variabila handle a unei pensulei de stoc se apelează funcţia GetStockObject:.

hBrush = GetStoCkObject (GRAY_BRUSH) ;

Odată selectată in contextual de dispozitiv cu ajutorul funcţiei SelectObject (hdc, hBrush)

pensula respectivă va colora interiorul figurilor în gri. Pentru a desena o figură fără contur se utilizează peniţa NULL_PEN, şi , în mod similar, pentru a desena o figură fără contur se utlizează pensula NULL_BRUSH.

Page 6: PW.14-28,84-86.docx

Funcţia Polygon este utlizată pentru a desena diverse poligoane pe baza unui sistem de puncte. Ea are drept parametric variabila handle a contextului de dispozitiv, un pointer la o matrice de structure POINT, şi numărul de puncte din matrice: Polygon (hdc, pt, iCount) .

Suprafaţa închisă de poligon este colorată folosind pensula curentă în două moduri: ALTERNATE sau WINDING . Modul prestabilit de umplere a poligoanelor este ALTERNATE, ceea ce înseamnă că Windows colorează numai suprafeţele închise la care se poate ajunge din exteriorul poligonului prin traversarea unui număr impar de laturi (1, 3, 5 şi aşa mai departe). Celelalte suprafeţe interioare nu sunt umplute.

Modul WINDING de umplere, presupune colorarea tuturor suprafeţelor închise de polygon. Modul de umplere poate fi setat cu ajutorul funcţiei SetPolyFillMode:

SetPolyFillMode (hdc, iMode) .

Umplerea suprafeţelor interioare

Interiorul figurilor Rectangle, RoundRect, Ellipse, Chord, Pie, Polygon şi PollyPolygon este umplut cu pensula - numită uneori şi „model" („pattern") - selectată în contextul de dispozitiv. O pensulă este de fapt o imagine bitmap 8x8 repetată pe verticală şi pe orizontală, pentru umplerea unei suprafeţe.

Windows conţine patru funcţii pentru crearea pensulelor logice:

hBrush = CreateSolidBrush (rgbColor ) ; hBrush = CreateHatchBrush (iHatchSt yle, rgbColor) – crearea unei pensule “haşurată" cu

linii orizontale, verticale sau oblice. Parametrul iHatchStyle precizează aspectul haşurii şi poate avea una dintre următoarele valori: HS_HORIZONTAL, HS_VERTICAL, HS_FDIAGONAL, HS_BDIAGONAL, HS_CROSS şi HS_DIAGCROSS.

hBrush = CreatePatternBrush (hBitmap) – crearea unei pensule proprii, bazată pe o imagine bitmap.

hBrush = CreateBrushIndirect (&logbrush) - funcţie care poate înlocui toate celelalte trei funcţii de creare a pensulelor. Variabila logbrush este o structură de tip LOGBRUSH („logical brush") cu 3 câmpuri: lbStyle (UINT),lbColor (COLORREF),lbHatch (LONG).

Pentru a selecta pensula în contextul de dispozitiv se foloseşte funcţia SelectObject:SelectObject (hdc, hBrush) ;

O pensulă creată poate fi ştearsă cu ajutorul funcţiei DeleteObject:DeleteObject (hBrush) ;

Pentru a obţine informaţii despre o pensulă, se apelează funcţia GetObject:GetObject (hBrush, sizeof (LOGBRUSH), (LPVOID) &logbrush) ;

unde variabila logbrush este o structură de tip LOGBRUSH („logical brush").

21. Dimensiunea unui caracter. Funcţia GetTextMetrics. Tipul TEXTMETRIC. Dimensiunile textului.

Dimensiunea unui caracter este necesară în cazul utilizării funcţiei TextOut pentru afişarea mai multor linii. Spaţiul dintre liniile succesive de text poate fi stabilit pe baza înălţimii unui caracter iar spaţiul dintre coloane pe baza lăţimii medii a caracterelor din font.

Dimensiunile caracterelor sunt obţinute prin apelarea funcţiei GetTextMetrics. Funcţia GetTextMetrics are ca parametru o variabilă handle a contextului de dispozitiv, deoarece returnează informaţii despre fontul selectat în contextul de dispozitiv. Windows copiază valorile referitoare la dimensiunile caracterelor într-o structură de tip TEXTMETRIC. Valorile sunt

Page 7: PW.14-28,84-86.docx

exprimate în unităţi de măsură care depind de modul de mapare selectat în contextul de dispozitiv. În contextul prestabilit de dispozitiv, modul de mapare este MM_TEXT, aşa că dimensiunile sunt date în pixeli.

Pentru folosirea funcţiei GetTextMetrics se defineşte mai întâi o variabilă de tipul TEXTMETRIC (numită, de obicei, tm):

TEXTMETRIC tm;În continuare se obţine o variabilă handle a contextului de dispozitiv şi se apelează funcţia

GetTextMetrics:hdc = GetDC(hwnd);GetTextMetrics(hdc, &tm) ;ReleaseDC(hwnd, hdc);

Astfel se obţine o structura cu infomţii despre dimensiunile textului, care pot fi salvate pentru utilizarea în viitor.

Dimensiunile textului:

tmInternalLeading - spaţiul păstrat deasupra unui caracter pentru semnele de accentuare. tmExternalLeading - spaţiul recomandat pentru a fi lăsat între rândurile de text. tmAveCharWidth -lăţimea medie a literelor mici. tmMaxCharWidth -lăţimea celui mai mare caracter al fontului.

Lăţimea medie a majusculelor poate fi obţinută calculând 150% din valoarea tmAveCharWidth.

22. DIMENSIUNEA ZONEI CLIENT. Macroinstrucţiunile LOWORD şi HIWORD (LOWORD (lParam), HIWORD (lParam)). Barele de derulare. Domeniul şi poziţia unei bare de derulare.

Dimensiunea ferestrelor poate să varieze foarte mult: de la o valoare maximă în care zona client ocupă întregul ecran, cu excepţia barei de titlu a programului până la o valoare minimă în care zona client este de fapt eliminată. Dimensiunile totale ale ferestrei mărite pot fi obţinute prin apelarea funcţiei GetSystemMetrics cu parametrii SM_CXFULLSCREEN şi SM_CYFULLSCREEN. Pentru un monitor VGA valorile returnate sunt 640 şi 461 de pixeli.

O metodă obişnuită de determinare a dimensiunilor zonei client a unei ferestre este prelucrarea mesajului WM_SIZE în procedura de fereastră. Windows trimite un mesaj WM_SIZE către procedura de fereastră, de fiecare dată când se modifică dimensiunile ferestrei. Parametrul lParam transmis procedurii de fereastră conţine lăţimea zonei client în cuvântul mai puţin semnificativ (LOWORD) şi înălţimea zonei client în cuvântul mai semnificativ (HIWORD). Codul pentru prelucrarea acestui mesaj arată astfel: static int cxClient, cyClient ; [alte linii de program] case WM_SIZE :

cxClient = LOWORD (lParam) ;cyClient = HIWORD (lParam) ;return 0 ;

Page 8: PW.14-28,84-86.docx

Despachetarea parametrului lParam pentru obţinerea dimensiunilor zonei client se face cu ajutorul macroinstrucţiunilor LOWORD şi HIWORD, care sunt definite în fişierele antet din Windows.

Barele de derulare se numără printre cele mai reuşite componente ale unei interfeţe grafice pentru mouse având funcţia de a permite vizualizarea informaţiei pentru care este nevoie de mai mult spaţiu decât este disponibil în zona client a ferestrei.

Ele sunt poziţionate vertical (pentru deplasări în sus şi în jos) sau orizontal (pentru deplasări la stânga şi la dreapta). Bara de derulare este parcursă longitudinal de o „casetă de derulare" care indică poziţia aproximativă a părţii afişate pe ecran faţă de întregul document.

Pentru a include în fereastra aplicaţiei o bară de derulare orizontală sau vertical este necesar de a include identificatorul WS_VSCROLL (derulare verticală) şi/sau WS_HSCROLL (derulare orizontală) în stilul de fereastră din apelul funcţiei CreateWindow. Barele de derulare sunt plasate întotdeauna la marginea de jos sau la cea din dreapta a ferestrei şi se întind pe toată lăţimea, respectiv înălţimea zonei client. Zona client nu include spaţiul ocupat de barele de derulare. Lăţimea unei bare de derulare verticale şi înălţimea uneia orizontale sunt constante pentru un driver de afişare dat..

Windows se ocupă de modul de utilizare a mouse-ului pentru barele de derulare, dar barele de derulare ale ferestrelor nu au o interfaţă automatizată cu tastatura.

Domeniul şi poziţia unei bare de derulareFiecare bară de derulare are asociate un „domeniu" (definit printr-o pereche de numere

întregi care reprezintă valorile maximă şi minimă) şi o „poziţie" (punctul în care se află caseta de derulare în domeniul asociat barei de derulare). Atunci când caseta de derulare se află la capătul de sus (sau la capătul din partea stângă) al barei de derulare, poziţia corespunde valorii minime. Capătul de jos (sau capătul din partea dreaptă) al barei de derulare reprezintă valoarea maximă.

În mod prestabilit, domeniul unei bare de derulare este de la 0 (sus sau în stânga) la 100 (jos sau în dreapta) dar poate fi uşor modificat astfel încât să aibă o formă mai convenabilă pentru program:

SetScrollRange (hwnd, iBar, iMin, iMax, bRedraw) ;Parametrul iBar poate avea una dintre valorile SB_VERT şi SB_HORZ, iar iMin şi iMax sunt

poziţiile minimă şi maximă din domeniu, în timp ce bRedraw trebuie să aibă valoarea TRUE pentru ca Windows să redeseneze bara de derulare pe baza noului domeniu stabilit.

Poziţia casetei de derulare este reprezentată întotdeauna printr-o valoare întreagă. De exemplu, o bară de derulare cu domeniul cuprins între 0 şi 4 are cinci poziţii ale casetei de derulare.

Pentru a stabili o nouă poziţie a casetei de derulare pe bara de derulare se utilizează funcţia SetScrollPos :

SetScrollPos (hwnd, iBar, iPos, bRedraw) ;Parametrul iPos reprezintă noua poziţie, care trebuie să fie cuprinsă în domeniul delimitat de

iMin şi iMax. Windows conţine funcţii asemănătoare (GetScrollRange şi GefScrollPos) pentru obţinerea domeniului şi a poziţiei unei bare de derulare.

23. Elemente de bază despre mouse. Funcţia GetSystemMetrics (SM_MOUSEPRESENT); cButtons = GetSystemMetrics (SM_CMOUSEBUTTONS). Parametrul SM_SWAPBUTTON. Zona senzitivă a indicatorului.

Windows 95 permite folosirea mouse-ului cu un buton, cu două butoane sau cu trei butoane, precum şi folosirea unui joystick sau a unui creion optic, pentru simularea unui mouse cu un buton. Totuşi, cel mai utlizat este mouse-ul cu trei butoane, devenit un standard de facto. Al doilea buton al mouse-ului este recomandat pentru apelarea „meniurilor de context" - meniuri care apar în fereastră în afara barei de meniu - sau pentru operaţii speciale de tragere.

Page 9: PW.14-28,84-86.docx

Pentru a determina dacă mouse-ul este prezent se foloseşte funcţia GetSystemMetrics având drept parametru identificatorul SM_MOUSEPRESENT:

fMouse = GetSystemMetrics (SM_MOUSEPRESENT) ;

Variabila fMouse va avea valoarea TRUE (diferită de zero) dacă mouse-ul este instalat. Pentru determinarea numărului de butoane ale mouse-ului instalat, folosiţi tot funcţia GetSystemMetrics:

cButtons = GetSystemMetrics (SM_CMOUSEBUTTONS) ;

Această funcţie returnează valoarea 0 dacă mouse-ul nu este instalat.

Utilizatorii care folosesc mâna stângă pot să inverseze butoanele mouse-ului folosind Panoul de control din Windows. O aplicaţie poate să determine dacă butoanele mouse-ului au fost inversate apelând funcţia GetSystemMetrics cu parametrul SM_SWAPBUTTON.

Zona senzitivă a indicatorului. Atunci când utilizatorul deplasează mouse-ul, Windows deplasează pe ecran o mică imagine bitmap numită „indicator". Indicatorul are o „zonă senzitivă" cu dimensiunea de un pixel, care indică o poziţie precisă pe ecran.

Driverul de afişare conţine câteva indicatoare de mouse predefinite, care pot fi folosite de programe. Indicatorul cel mai obişnuit este săgeata oblică definită în fişierele antet din Windows cu numele IDC_ARROW. Zona senzitivă a acestui indicator este vârful săgeţii. Indicatorul IDC_CROSS are zona senzitivă situată la celor două linii.

24. Ferestre child de control şi culoare. Ades, utilizarea unor aspecte implicite pentru crearea butoanelor duce la un design neclar sau mai putin atragător- Pentru a îmbunătăţi aspectul acestor butoane trebuie ori să schimbăm culoarea zonei client, aşa încât aceasta să se asorteze cu fondul butoanelor, ori să schimbăm culoarea folosită pentru fondul butoanelor.

Culorile de sistem pentru butoane:COLOR_BTNFACE este folosită pentru culoarea suprafeţei principale a butoanelor de apăsare şi pentru

fondul celorlalte butoane. (De asemenea, aceasta este culoarea de sistem folosită pentru casete de dialog şi casete de mesaje.)

COLOR_BTNSHADOW este folosită pentru sugerarea unei umbre la marginile din dreapta şi de jos ale butoanelor de apăsare, precum şi în interiorul pătratelor din casetele de validare şi a cercurilor din butoanele radio.

COLOR_BTNTEXT- culoarea textului în cazul butoanelor de apăsareCOLOR_WINDOWTEXT - culoarea textului pentru pentru celelalte butoane.

În cazul afişării butoanelor pe suprafaţa zonei client, una dintre metodele de evitare a conflictelor între culori este folosirea culorilor de sistem. Pentru început, se foloseşte COLOR_BTNFACE la definirea clasei de fereastră pentru fondul zonei client:

wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ;

Atunci când variabila hbrBackground din structura WNDCLASSEX are o valoare, Windows înţelege că aceasta se referă la culoarea de sistem, nu la o variabilă handle. Atunci când sunt specificate în câmpul hbrBackground al structurii WNDCLASSEX, la aceste valori trebuie adăugat 1, pentru a se evita folosirea valorii NULL. Dacă în timpul rulării programului culoarea de sistem se schimbă, suprafaţa zonei client va fi invalidată şi Windows va folosi noua valoare pentru COLOR_BTNFACE.

Pentru a rezolva problema cauzată de necorespondenţa dintre culoarea de sistem şi fondul din spatele textului în cazul funcţiei TextOut se vor utiliza funcţiile SetTextColor şi SetBkColor. Astfel, culorile pentru fond şi pentru text vor fi identice culorile de sistem.

SetBkColor (hdc, GetSysColor (COLORBTNFACE)) ; SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ;

Page 10: PW.14-28,84-86.docx

Acum, fondul zonei client, al textului şi culoarea textului se potrivesc cu culorile butoanelor.

Mesajul WM_CTLCOLORBTNModificarea culorilor butoanelor nu este o idee plauzibilă din punct de vedere practic. Apelul

funcţiei SetSysColors cu scopul modificării aspectului butoanelor, va afecta toate programele care rulează în momentul respectiv sub Windows - o mişcare pe care utilizatorii nu o vor aprecia prea mult. O abordare mai potrivită (teoretic) este prelucrarea mesajului WM_CTLCOLORBTN. Acesta este un mesaj pe care controalele de tip buton îl trimit către procedura ferestrei părinte atunci când fereastra descendent este pe cale de a executa o redesenare. Fereastra părinte poate să folosească această ocazie ca să modifice culorile pe care procedura ferestrei descendent urmează să le folosească pentru desenare.

Atunci când procedura părinte recepţionează mesajul WM_CTLCOLORBTN, parametrul wParam conţine variabila handle a contextului de dispozitiv al butonului, iar IParam este variabila handle a ferestrei butonului. Atunci când fereastra părinte primeşte acest mesaj, controlul de tip buton a obţinut deja contextul de dispozitiv. În timpul prelucrării mesajului WM_CTLCOLORBTN:

■ Se stabileşte (opţional) o culoare de text cu ajutorul funcţiei SetTextColor.

■ Se stabileşte (opţional) o culoare de fond cu ajutorul funcţiei SetBkColor.

■ Se returnează către fereastra descendent o variabilă de manipulare a pensuleicu care se va desena.

Teoretic, fereastra descendent foloseşte pensula respectivă pentru colorarea fonduluiTotuşi, în legătură cu mesajul WM_CTLCOLORBTN este o problemă: acesta nu este trimis decât

de butoanele de apăsare şi de butoanele desenate de proprietar; de asemenea, numai butoanele desenate de proprietar răspund la prelucrarea făcută mesajului de către fereastra părinte, folosind pensula trimisă pentru colorarea fondului. Oricum, acest lucru este inutil, deoarece fereastra părinte este răspunzătoare de desenarea acestor butoane.

25. Ferestre child. Butoane definite de programator. S_OWNERDRAW

Crearea unui buton cu stilul BS_OWNERDRAW oferă controlul complet asupra aspectului vizual al butonului. Majoritatea programelor care folosesc stilul BS_OWNERDRAW pentru desenarea butoanelor de proprietar folosesc mici imagini (bitmap) pentru identificarea acestor butoane.

Un buton creat cu stilul BS_OWNERDRAW trimite ferestrei părinte un mesaj WM_DRAWITEM de fiecare dată când butonul trebuie să fie redesenat. Aceasta se întâmplă la crearea butonului, de fiecare dată când este apăsat sau eliberat, când obţine sau pierde cursorul de intrare şi în orice altă situaţie când trebuie să fie redesenat.

în mesajul WM_DRAWITEM, parametrul IParam este un pointer către o structură de tip DRAWITEMSTRUCT. Această structură conţine informaţiile necesare programului pentru redesenarea butonului. Câmpurile din structură importante pentru lucrul cu butoane sunt hDC (contextul de dispozitiv al butonului), rcltem (o structură RECT în care este stocată dimensiunea butonului), CtllD (identificatorul ferestrei controlului) şi UemState (care indică dacă butonul este apăsat sau dacă deţine cursorul de intrare).

Dacă butonul este apăsat, unul dintre biţii câmpului UemState din structura DRAWITEMSTRUCT are valoarea 1. Acest bit poate fi testat folosind constanta ODS_SELECTED. Dacă butonul deţine cursorul de intrare, atunci bitul ODS_FOCUS din câmpul UemState are valoarea 1.

Page 11: PW.14-28,84-86.docx

În cazul folosirii buroanelor desneate de proprietar, Windows obţine contextul de dispozitiv şi îl include în structura DRAWITEMSTRUCT. Este necesar ca la sfârşit contextul de dispozitiv să fie în aceeaşi stare ca la început, deci orice obiect GDI selectat în contextul de dispozitiv trebuie să fie deselectat.

26. Ferestre child. Butoane şi input focus.

Butoanele de apăsare, butoanele radio şi butoanele desenate de proprietar primesc cursorul de intrare atunci când se execută clic pe acestea. Controlul indică faptul că deţine cursorul de intrare printr-o linie punctată care înconjoară textul. Atunci când o fereastră descendent primeşte cursorul de intrare, fereastra părinte îl pierde; toate intrările de la tastatură sunt direcţionate către control, nu către fereastra părinte. Totuşi, controalele de tip fereastră descendent răspund numai la apăsarea barei de spaţiu, care funcţionează în acest caz ca şi butonul mouse-ului. Cu alte cuvinte, programul a pierdut controlul asupra tastaturii.

Atunci când sistemul de operare Windows mută cursorul de intrare de la o fereastră (cum ar fi fereastra părinte) la o altă fereastră (cum ar fi controlul de tip fereastră descendent), trimite mai întâi un mesaj WM_KILLFOCUS către fereastra care pierde cursorul de intrare. Parametrul wParam al mesajului este variabila handle a ferestrei care primeşte cursorul de intrare. Windows trimite apoi un mesaj WM_SETFOCUS către fereastra care primeşte cursorul de intrare. Parametrul wParam al mesajului este variabila de manipulare a ferestrei care pierde cursorul de intrare. (În ambele cazuri, wParam poate avea valoarea NULL, ceea ce arată că nici o fereastră nu primeşte sau nu pierde cursorul de intrare.)

O fereastră părinte poate împiedica un control de tip fereastră descendent să primească cursorul de intrare prelucrând mesajul WM_KILLFOCUS. Să presupunem că matricea hwndCmd conţine variabilele handle ale tuturor ferestrelor descendent. (Aceste variabile au fost salvate în matrice în timpul apelării funcţiei CreateWindow pentru crearea ferestrelor descendent.) NUM este numărul ferestrelor descendent.

case WM_KILLFOCUS :for (i = 0 ; i < NUM ; 1++)

if (hwndChild[i] == (HWND) wParamSetFocus (hwnd) ; break ;

return 0 ;

În această secvenţă de cod, atunci când fereastra părinte este avertizată că urmează să piardă cursorul de intrare în favoarea uneia dintre ferestrele descendent, apelează funcţia SetFocus ca să recâştige cursorul de intrare.

Însă această prelucrare împiedică butoanele să răspundă la apăsarea barei de spaţiu, deoarece butoanele nu obţin niciodată cursorul de intrare. O soluţie mai bună ar fi permiterea butoanelor să obţină cursorul de intrare, şi, în acelaşi timp, permiterea utilizatorului să treacă de la un buton la altul cu ajutorul tastei Tab.

27. Ferestre child. Butoane visibile şi accesibile.

Pentru recepţionarea intrărilor de la mouse şi de la tastatură, o fereastră descendent trebuie să fie vizibilă (afişată), dar şi activată. Atunci când o fereastră este vizibilă, dar nu este activată, textul acesteia este afişat cu gri, în loc de negru.

Dacă parametrul WS_VISIBLE nu este inclus în clasa ferestrei la crearea ferestrei descendent, aceasta nu va fi afişată până când nu este apelată funcţia ShowWindow:

Page 12: PW.14-28,84-86.docx

ShowWindow (hwndChild, SW_SHOWNORMAL) ;Dacă parametrul WS_VISIBLE este inclus în clasa ferestrei, nu este necesar apelul funcţia ShowWindow. Totuşi, prin apelarea funcţiei ShowWindow poate fi mascată o fereastră descendent afişată:

ShowWindow (hwndChild, SW_HIDE) ;

Pentru a determina dacă o fereastră descendent este afişată se utilizază apelul:

IsWindowVisible (hwndChild) ;În mod prestabilit, ferestrele descendent sunt activate. Pentru a le dezactiva se utilizează

funcţia:

EnableWindow (hwndChild, FALSE) ;

Pentru controalele de tip buton, această acţiune are ca efect afişarea cu gri a textului din buton. Butonul nu mai răspunde la intrările de la mouse sau de la tastatură. Aceasta este cea mai bună metodă de a indica faptul că opţiunea reprezentată de un anumit buton nu este disponibilă.

Pentru a reactiva o fereastră descendent se utilizează aceeaşi funcţie, dar având drept al doliea parametru valoarea TRUE:

EnableWindow (hwndChild, TRUE) ;Pentru a determina dacă o fereastră descendent este activă sau nu se utilizează funcţia :

IsWindowEnabled (hwndChild) ;

28. Ferestre child. Check box.

Casetele de validare sunt dreptunghiuri etichetate cu un text; de obicei, textul apare în partea dreaptă a casetei de validare. (Dacă la crearea butonului este folosit stilul BS_LEFTTEXT, textul apare în stânga casetei de validare.) De obicei, casetele de validare sunt incluse în aplicaţii pentru a permite utilizatorilor să selecteze diferite opţiuni. Casetele de validare funcţionează ca un comutator: executarea unui clic într-o casetă de validare determină apariţia unui marcaj de validare; un al doilea clic face ca marcajul de validare să dispară.

Cele mai cunoscute stiluri de casete de validare sunt BS_CHECKBOX şi BS_AUTOCHECKBOX. În cazul stilului BS_CHECKBOX, sarcina de aplicare a marcajului de validare revine programatorului, prin trimiterea unui mesaj BS_SETCHECK. Parametrul wParam trebuie să aibă valoarea 1 pentru afişarea marcajului de validare şi valoarea 0 pentru ştergerea acestuia. Pentru inversarea marcajului de validare la prelucrarea mesajului WM_COMMAND primit de la control poate fi utilizată instrucţiunea:

SendMessage ((HWND) lParam, BM_SETCHECK, (WPARAM) SendMessage ((HWND) lParam, BM_GETCHECK, 0, 0), 0) ;

Valoarea lParam este variabila handle a ferestrei descendent, transmisă către procedura ferestrei prin mesajul WM_COMMAND.

Pentru a iniţializa o casetă de validare de tip BS_CHECKBOX cu un X, se utilizează aceeaşi funcţie cu parametrul BM_SETCHECK:

SendMessage (hwndButton, BM_SETCHECK, 1, 0) ;În cazul folosirii stilului BS_AUTOCHECKBOX, controlul este cel care actualizează afişarea

marcajului de validare. Procedura ferestrei părinte poate să ignore mesajele

Page 13: PW.14-28,84-86.docx

WM_COMMAND. Pentru a dtermina starea butonului, se transmite către acesta mesajul BM_GETCHECK:

iCheck = (int) SendMessage (hwndButton, BM_GETCHECK, 0, 0) ;iCheck are valoarea TRUE (sau o valoare diferită de 0) dacă butonul este validat şi valoarea FALSE (sau 0) în caz contrar.

Celelalte două stiluri de casete de validare sunt BS_3STATE şi BS_AUTO3STATE. Aşa cum indică şi numele lor, aceste stiluri permit afişarea unei stări terţe - culoarea gri din caseta de validare - în cazul în care se trimite către control un mesaj WM_SETCHECK cu parametrul wParam egal cu 2. Culoarea gri indică utilizatorului că opţiunea respectivă este nedeterminată sau irelevantă. În acest caz, caseta nu poate fi validată - cu alte cuvinte, este dezactivată. Totuşi, caseta de validare continuă să trimită mesaje către fereastra părinte atunci când se execută clic.

Caseta de validare este aliniată la partea stângă a dreptunghiului şi este centrată între marginile de sus şi de jos ale acestuia, conform dimensiunilor specificate la apelarea funcţiei CreateWindow. Executarea unui clic oriunde în cadrul dreptunghiului determină trimiterea unui mesaj WM_COMMAND către fereastra părinte, înălţimea minimă a casetei de validare este egală cu înălţimea unui caracter. Lăţimea minimă este egală cu numărul de caractere din text, plus două.

84.C#: Expresii şi operatori. Instrucţiunile try-catch-finally şi throw.     Un operator este un simbol care indica o actiune. Operandul este valoarea asupra careia se executa operatia. Operatorii alaturi de operanzi formeaza o expresie.Clasificarea operatorilorOperatorii sunt impartiti 3 categorii.

Operatori unari – actioneaza asupra unui singur operand.

Operatori binari – actioneaza intre doi operanzi.

Operatori ternari – actioneaza asupra a trei operanzi. Exista doar unul de acest tip, operatorul conditional.

Operatorii aritmetici In C#, exista urmatorii operatori aritmetici : + , - ,* , / , % , ++ , -- .

Operatorii relationali Operatorii relationali se refera la relatiile de ordine care pot exista intre doua valori: =, !=, < , > , <= , >= . Deoarece acesti operatori produc rezultate de tip adevarat sau fals, sunt folositi des cu operatorii logici.

Operatorii logici Pentru operatorii logici, operanzii trebuie sa fie de tipul bool, rezultatul fiind tot de acest tip.

Operator Semnificatie

! negatie logica

&& SI logic

|| SAU logic

Operatorul de atribuire

Page 14: PW.14-28,84-86.docx

Operatorul de atribuire “=” se foloseste intr-o constructie de forma variabila = expresie. Dupa evaluarea expresiei, rezultatul va fi atribuit variabilei. Pentru atribuire se mai folosesc si operatorii +=, –=, *=, /=, %=.Operatorul conditional Este de forma : expresie1? expresie2: expresie3 .Daca expresie1 este adevarata, atunci va fi returnata valoarea lui expresie2. Dacaexpresie1 este falsa, atunci va fi returnata valoarea lui expresie3.

Cuvintele cheie in C# rezervate pentru tratarea exceptiilor sunt try, catch, finally, throw. Acestea reprezinta un sistem unitar, utilizarea unuia dintre ele implicand si utilizarea altuia.Intr-un bloc try vom scrie instructiunile care trebuie verificate pentru aparitia erorilor. Daca pe parcursul executiei acestor intructiuni apare o exceptie, aceasta este “aruncata”, lansata (thrown).Cu ajutorul lui catch programul poate intercepta exceptia si o poate trata in functie de logica programului. Instructiunile din catch se executa doar daca se lanseaza o exceptie.Instructiunile din finally se vor executa intotdeauna.O imagine de ansamblu a codului folosit pentru tratarea exceptiilor:

try{ //in this block exception may get thrown }

catch{ //handle exception }

finally{ //cleanup code, optionally }Cuvantul cheie try nu poate aparea fara a fi completat de cuvantul cheie catch sau de finally si nici invers. Finally este optional.Pot exista mai multe instructiuni catch asociate unui try. Instructiunea care se va executa se va stabili in functie de tipul exceptiei, celelalte sunt ignorate.ThrowPentru a lansa manual o exceptie se foloseste throw.if (numbers == null)

throw new ArgumentNullException("Array is null"); Tipul obiectului trebuie sa fie o clasa derivata din Exception.

Page 15: PW.14-28,84-86.docx

85.Evoluţia tehnicilor de programare. Tipuri de date obiectuale. Încapsulare.Supraîncărcare.

1.1. Evoluţia tehnicilor de programare Programarea nestructurată(un program simplu, ce utilizează numai variabile globale);complicaţiile apar când prelucrarea devine mai amplă, iar datele se multiplică şi se diversifică. Programarea procedurală(program principal deservit de subprograme cu parametric formali, variabile locale şi apeluri cu parametri efectivi); se obţin avantaje privind depanarea şi reutilizarea codului şi se aplică noi tehnici privind transferul parametrilor şi vizibilitateavariabilelor; complicaţiile apar atunci când la program sunt asignaţi doi sau mai mulţiprogramatori care nu pot lucra simultan pe un acelaşi fişier ce conţine codul sursă. Programarea modulară(gruparea subprogramelor cu funcţionalităţi similare în module, implementate şi depanateseparat); se obţin avantaje privind independenţa şi încapsularea (prin separarea zonei de implementare, păstrând vizibilitatea numai asupra zonei de interfaţă amodulului) şi se aplică tehnici de asociere a procedurilor cu datele pe care le manevrează, stabilind şi diferite reguli de acces la date şi la subprograme.Se observă că modulele sunt ”centrate” pe proceduri,acestea gestionând şi setul de date pe care le prelucrează. Programarea orientată obiect(programe cu noi tipuri ce integrează atât datele, cât şi metodele asociate creării,prelucrării şi distrugerii acestor date); se obţin avantaje prin abstractizareaprogramării (programul nu mai este o succesiune de prelucrări, ci un ansamblu de obiecte care prind viaţă, au diverse proprietăţi, sunt capabile de acţiuni specifice şi care interacţionează în cadrul programului); intervin tehnici noi privind instanţierea, derivarea şi polimorfismul tipurilor obiectuale.

Tipuri de date obiectuale. ÎncapsulareUn tip de date abstract (ADT) este o entitate caracterizată printr-o structură de date şi un ansamblu de operaţii aplicabile acestor date. Considerând, în rezolvarea unei problemede gestiune a accesului utilizatorilor la un anumit site, tipul abstract USER , vom obseva că sunt multe date ce caracterizează un utilizator Internet. Totuşi se va ţine cont doar de datele semnificative pentru problema dată. Astfel, ”culoarea ochilor” este irelevantă în acest caz, întimp ce ”data naşterii” poate fi importantă. În aceeaşi idee, operaţii specifice ca ”se înregistrează”, ’comandă on-line” pot fi relevante, în timp ce operaţia ”manâncă” nu este, în cazul nostru. Evident, nici nu se pun în discuţie date sau operaţii nespecifice (”numărul delaturi” sau acţiunea ”zboară”).Operaţiile care sunt accesibile din afara entităţii formează interfaţaacesteia. Astfel,operaţii interne cum ar fi conversia datei de naştere la un număr standard calculat de la01.01.1900 nu fac parte din interfaţa tipului de date abstract, în timp ce operaţia ”plasează ocomandă on-line” face parte, deoarece permite interacţiunea cu alte obiecte (SITE, STOC etc.) O instanţă a unui tip de date abstract este o ”concretizare” a tipului respectiv, formatădin valori efective ale datelor.Un tip de date obiectual este un tip de date care implementează un tip de date abstract.Vom numi operaţiile implementate în cadrul tipului de date abstract metode . Spunem că datele şi metodele sunt membrii unui tip de date obiectual. Folosirea unui astfel de tip presupune: existenţa definiţiei acestuia, apelul metodelor şi accesul la date. Un exemplu de-acum clasic de tip de date abstract este STIVA. Ea poate avea ca date: numerele naturale din stivă, capacitatea stivei, vârful etc. Iar operaţiile specifice pot fi:I ntroducerea în stivă

Page 16: PW.14-28,84-86.docx

( push) şi extragerea din stivă ( pop). La implementarea tipului STIVA, vom defini o structura de date care să reţină valorile memorate în stivă şi câmpuri de datesimple pentru: capacitate, număr de elemente etc. Vom mai defini metode (subprograme)capabile să creeze o stivă vidă, care să introducă o valoare în stivă, să extragă valoarea dinvârful stivei, să testeze dacă stiva este vidă sau dacă stiva este plină etc. Crearea unei instanţe noi a unui tip obiectual, presupune operaţii specifice de”construire” a noului obiect, metoda corespunzătoare purtând numele de constructor. Analog, la desfiinţarea unei instanţe şi eliberarea spaţiului de memorie aferent datelor sale, se aplică o metodă specifică numită destructor.O aplicaţie ce utilizează tipul obiectual STIVA, va putea construi două sau mai multe stive (de cărţi de joc, de exemplu), le va umple cu valori distincte, va muta valori dintr-o stivă în alta după o anumită regulă desfiinţând orice stivă golită, până ce rămâne o singură stivă.De observat că toate aceste prelucrări recurg la datele, constructorul, destructorul şi la metodele din interfaţa tipului STIVA descris mai sus. Principalul tip obiectual întâlnit în majoritatea mediilor de dezvoltare (Viisual Basic,Delphi, C++, Java, C#) poartă numele de clasă (class). Există şi alte tipuri obiectuale (struct,object). O instanţă a unui tip obiectual poartă numele de obiect..La implementare, datele şi metodele asociate trebuie să fie complet şi corect definite,astfel încât utilizatorul să nu fie nevoit să ţină cont de detalii ale acestei implementări. El vaaccesa datele, prin intermediul proprietăţilor şi va efectua operaţiile, prin intermediulmetodelor puse la dispoziţie de tipul obiectual definit. Spunem că tipurile de date obiectualerespectă principiulÎncapsulării. Permiţând extensia tipurilor de date abstracte, clasele pot avea la implementare:•date şi metode caracterisitice fiecărui obiect din clasă (membri de tip instanţă),•date şi metode specifice clasei (membri de tip clasă). Astfel, clasa STIVA poate beneficia, în plus, şi de date ale clasei cum ar fi: numărul de stive generate, numărul maxim sau numărul minim de componente ale stivelor existente etc.Modificatorul static plasat la definirea unui membru al clasei face ca acela să fie un membru de clasă, nu unul de tip instanţă. Dacă în cazul membrilor nestatici, există câte unexemplar al membrului respectiv pentru fiecare instanţă a clasei, membrii statici sunt unici,fiind accesaţi în comun de toate instanţele clasei. Mai mult, membrii statici pot fi referiţi fără acrea vreo instanţă a clasei respective.1.3. SupraîncărcareDeşi nu este o tehnică specifică programării orientată obiect, ea creează un anumit context pentru metodele ce formează o clasă şi modul în care acestea pot fi (ca orice subprogram) apelate.Prin supraîncarcare se înţelege posibilitatea de a defini în acelaşi domeniu devizibilitatemai multe funcţii cu acelaşi nume, dar cu parametri diferiti ca tip şi/sau ca număr.Astfel ansamblul format din numele funcţiei şi lista sa de parametri reprezintă o modalitateunică de identificare numită semnătură sau amprentă. Supraîncărcarea permite obţinereaunor efecte diferite ale apelului în contexte diferite.Apelul unei funcţii care beneficiază, prin supraîncărcare, de două sau mai multesemnături se realizează prin selecţia funcţiei a cărei semnătură se potriveşte cel mai bine culista de parametri efectivi (de la apel).Astfel, poate fi definită metoda ”comandă on-line” cu trei semnături diferite:1)comanda_online(cod_prod)cu un parametru întreg (desemnând comanda unui singur produs identificat prin cod_prod.2)comanda_online(cod_prod,cantitate)cu primul parametru întreg şi celalalt real3)comanda_online(cod_prod,calitate)cu primul parametru întreg şi al-II-ilea caracter.

86.Moştenire. Polimorfism. Metode virtuale. Principiile programării orientate pe obiecte.

Page 17: PW.14-28,84-86.docx

Pentru tipurile de date obiectuale class este posibilă o operaţie de extindere sau specializare a comportamentului unei clase existente prin definirea unei clase noi cemoşteneşte datele şi metodele clasei de bază, cu această ocazie putând fi redefiniţi unii membri existenţi sau dăugaţi unii membri noi. Operaţia mai poartă numele de derivare.Clasa din care se moşteneştea se mai numeşte clasă de bază sau superclasă. Clasacare moşteneşte se numeşte subclasă , clasă derivată sau clasă descendentă. O subclasă poate moşteni de la o singură superclasă, adică avem de-a face cu moştenire simplă; aceeaşi superclasă însă poate fi derivată în mai multe subclase distincte. O subclasă, la randul ei, poate fi superclasă pentru o altă clasă derivată.O clasă de bază impreună cu toate clasele descendente (direct sau indirect) formeaza oierarhie de clase. În C#, toate clasele moştenesc de la clasa de bază Object. În contextul mecanismelor de moştenire trebuie amintiţi modificatoriiAbstract şi sealed aplicaţi unei clase, modificatori ce obligă la şi respectiv se opun procesului de derivare. Astfel, oclasă abstractă trebuie obligatoriu derivată, deoarece direct din ea nu se pot obţine obiecteprin operaţia de instanţiere, în timp ce o clasă sigilată (sealed) nu mai poate fi derivată (e unfel de terminal în ierarhia claselor). O metodă abstractă este o metodă pentru care nu este definită o implementare, aceasta urmând a fi realizată în clasele derivate din clasa curentă.O metodă sigilată nu mai poate fi redefinită în clasele derivate din clasa curentă.1.5. Polimorfism. Metode virtuale

Folosind o extensie a sensului etimologic, un obiect polimorfic este cel capabil să ia diferite forme, să se afle în diferite stări, să aibă comportamente diferite. Polimorfismul obiectual se manifestă în lucrul cu obiecte din clase aparţinând unei ierarhii de clase, unde,prin redefinirea unor date sau metode, se obţin membri diferiţi având însă acelaşi nume.Astfel, în cazul unei referiri obiectuale, se pune problema stabilirii datei sau metodei referite. Comportamentul polimorfic este un element de flexibilitate care permite stabilirea contextuală, în mod dinamic, a membrului referit.

De exemplu, dacă este definită clasa numită PIESA (de şah), cu metoda nestatică muta(pozitie_initiala,pozitie_finala),atunci subclasele TURN şi PION trebuie să aibă metoda muta definită în mod diferit (pentru a implementa maniera specifică a pionului de a captura o piesă ”en passant”). Atunci, pentru un obiect T, aparţinând claselor derivate din PIESA, referirea la metoda muta pare nedefinită.

Totuşi mecanismele POOpermit stabilirea, în momentul apelului, a clasei proxime căreia îi aparţine obiectul T şiapelarea metodei corespunzătore (mutare de pion sau turn sau altă piesă).Pentru a permite acest mecanism, metodele care necesită o decizie contextuală (în momentul apelului), se decalră ca metode virtuale (cu modificatorul virtual). În mod curent, în C# modificatorului virtual al funcţiei din clasa de bază, îi corespunde un specificator override al funcţiei din clasa derivată ce redefineşte funcţia din clasa de bază.O metodă ne-virtuală nu este polimorfică şi, indiferent de clasa căreia îi aparţine obiectul, va fi invocată metoda din clasa de bază.

Principiile POO: Abstractizarea – Este posibilitatea ca un program să ignore unele aspecte ale informaţiei pe care o

manipulează, adică posibilitatea de a se concentra asupra esenţialului. Fiecare obiect în sistem are rolul unui “actor” abstract, care poate executa acţiuni, îşi poate modifica şi comunica starea şi poate comunica cu alte obiecte din sistem fără a dezvălui cum au fost implementate acele facilitaţi. Procesele, funcţiile sau metodele pot fi de asemenea abstracte, şi în acest caz sunt necesare o varietate de tehnici pentru a extinde abstractizarea:

Încapsularea – numită şi ascunderea de informații: Asigură faptul că obiectele nu pot schimba starea internă a altor obiecte în mod direct (ci doar prin metode puse la dispoziţie de obiectul

Page 18: PW.14-28,84-86.docx

respectiv); doar metodele proprii ale obiectului pot accesa starea acestuia. Fiecare tip de obiect expune o interfaţă pentru celelalte obiecte care specifică modul cum acele obiecte pot interacţiona cu el.

Polimorfismul – Este abilitatea de a procesa obiectele în mod diferit, în funcţie de tipul sau de clasa lor. Mai exact, este abilitatea de a redefini metode pentru clasele derivate. De exemplu pentru o clasă Figura putem defini o metodă arie. Dacă Cerc, Dreptunghi, etc. ce vor extinde clasa Figura, acestea pot redefini metoda arie.

Moștenirea – Organizează şi facilitează polimorfismul şi încapsularea, permiţând definirea şi crearea unor clase specializate plecând de la clase (generale) deja definite - acestea pot împărtăşi (şi extinde) comportamentul lor, fără a fi nevoie de a-l redefini. Aceasta se face de obicei prin gruparea obiectelor în clase şi prin definirea de clase ca extinderi ale unor clase existente. Conceptul de moştenire permite construirea unor clase noi, care păstrează caracteristicile şi comportarea, deci datele şi funcţiile membru, de la una sau mai multe clase definite anterior, numite clase de bază, fiind posibilă redefinirea sau adăugarea unor date şi funcţii noi. Se utilizează ideea: ”Anumite obiecte sunt similare, dar în acelaşi timp diferite”. O clasă moştenitoare a uneia sau mai multor clase de bază se numeşte clasă derivată. Esenţa moştenirii constă în posibilitatea refolosirii lucrurilor care funcţionează.