Sunteți pe pagina 1din 4

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 6.
Visual C++6.0 MFC Desenarea i afiarea imaginilor folosind contexte de dispozitiv

Un context dispozitiv reprezint suprafaa pe care se deseneaz toate punctele, liniile, ptratele, fonturile, culorile. Cuvntul dispozitiv din context dispozitiv nseamn c se poate desena pe ecran, la imprimant, pe un plotter fr a cunoate prea multe detalii despre ce dispozitiv se folosete sau ce marc sau model este acesta. Exist un context dispozitiv standard brut, i exist contexte dispozitiv pentru situaii speciale i operaii particulare. MFC ofer ncapsulri ale contextelor dispozitiv care simplific interaciunea cu obiectele GDI aflate dedesubt. Clasa care ncapsuleaz contextul dispozitiv standard brut este CDC. Aceast clas conine un numr mare de funcii de desenare, de mapare de coordonate i de decupare pentru implementarea reprezentrilor grafice. Toate celelalte clase de context dispozitiv, mai specializate, sunt bazate pe aceast clas i o extind. Capacitatea clasei CDC de a se ataa i a desena ntr-un context dispozitiv poate fi ilustrat printr-un program simplu. Fiecare fereastr are asociat un context dispozitiv care acoper ntreaga fereastr; nu face excepie nici fereastra suprafeei de lucru, care se ntinde pe ntregul ecran. Aplicaia urmtoare acapareaz un context dispozitiv i l folosete pentru desenare. Exerciiu 1. Creai o aplicaie de tip SDI. Adugai un buton cu numele Trasare (ID DrawIt) resursei Edit de meniu din cadrul proiectului. Cu ajutorul ClassWizard tratai mesajul generat de apsarea butonului, ntr-o funcie OnDrawIt() situat n clasa CSDIView. Completai corpul funciei cu urmtorul cod:
void CSDIView::OnDrawIt() { //Obtinerea unui pointer la fereastra suprafatei de lucru CWnd* pDeskTop=GetDesktopWindow(); //Obtinerea unui pointer la contextul dispozitiv al //acesteia CDC* pDC=pDeskTop->GetWindowDC(); for(int i=0;i<300;i++) for(int j=0;j<300;j++) //Desenarea fiecarui pixel cu o alta culoare pDC->SetPixel(i,j,i*j); //Eliberarea contextului dispozitiv pDeskTop->ReleaseDC(pDC);

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Utilizarea contextelor dispozitiv client - CClientDC Pentru a desena n contextul dispozitiv al ferestrei aplicaiei i nu n fereastra suprafeei de lucru se folosete un pointer pDC de tip CClientDC. Se va folosi proiectul creat la punctul anterior, modificndu-se corpul funciei OnDrawIt():
void CSDIView::OnDrawIt(){ // Construim un DC pentru fereastra client CClientDC pDC(this); for(int x=0;x<300;x++) for(int y=0;y<300;y++) pDC.SetPixel(x,y,x*y); }

Utilizarea contextelor dispozitiv de redesenare - CPaintDC Clasa CPaintDC este o ncapsulare special de context dispozitiv care ajut la tratarea mesajului WM_PAINT transmis de Windows. Mesajul WM_PAINT este transmis unei ferestre atunci cnd suprafaa acesteia a fost descoperit parial sau total de o alt fereastr. n loc s se redeseneze ntreaga fereastr de fiecare dat cnd este descoperit o mic poriune, Windows transmite coordonatele unui dreptunghi care ncadreaz zona descoperit. Aceste informaii se pot folosi pentru a desena exclusiv poriunea afectat, fr a mai irosi timp pentru a desena zone de ecran pe care utilizatorul oricum nu le poate vedea. Pentru a experimenta redesenarea se creeaz un nou proiect SDI i cu ajutorul AppWizard-ului se trateaz mesajul WM_PAINT n funcia OnPaint()Pentru aceasta se parcurg urmtoarele etape: Se selecteaz View, apoi ClasWizaed sau direct CTRL W; Se va selecta clasa CSDIView i Messages WM_PAINT; Se va aduga functia OnPaint() cu Add Function; Se va selecta Edit Code. Se va rescrie corpul funciei:
void CSDIView::OnPaint(){ //Crearea unui context dispozitiv pentru desenare CPaintDC paintDC(this); //Crearea uni pointer spre dreptunghiul de redesenare RECT* pRect=&paintDC.m_ps.rcPaint; for(int x=pRect->left;x<pRect->right;x++) for(int y=pRect->top;y<pRect->bottom;y++) paintDC.SetPixel(x,y,x*y); }

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Compilai i rulai aplicaia. La prima afiare a ferestrei este transmis un mesaj WM_PAINT pentru redesenarea ntregii suprafee. Pentru a vedea efectul mesajului de redesenare, acoperii fereastra aplicaiei cu o alt fereastr. Deplasai apoi aceast fereastr pn cnd nu se va mai suprapune peste fereastra aplicaiei. Se va observa c redesenarea se va face mai repede deoarece regiunea acoperit devine din ce n ce mai mic, fiind astfel necesare mai puine apeluri SetPixel.

Contexte dispozitiv de memorie - CDC Un context dispozitiv de memorie este un context dispozitiv care nu are asociat nici un dispozitiv. Aceste contexte dispozitiv se folosesc de regul mpreun cu un context dispozitiv obinuit pentru copierea i lipirea unor zone de ecran. Este posibil crearea unui context dispozitiv de memorie compatibil cu un dispozitiv de afiare. Apoi se pot copia n memorie imaginile care nu mai sunt afiate, aducndu-le napoi n contextul dispozitiv de afiare atunci cnd este nevoie. Exerciiu 2. Creai o aplicaie de tip SDI. Adugai un buton cu numele DrawIt resursei de meniu din cadrul proiectului. Cu ajutorul ClassWizard tratai mesajul generat de apsarea butonului ntr-o funcie Draw() situat n clasa CSDIView. Completai corpul funciei cu urmtorul cod:
void CSDIView::OnDrawIt() { //Construim un DC client pentru fereastra dialog CClientDC clientDC(this); //Creem un context dispozitiv de memorie care s fie //compatibil cu un context dispozitiv de pe ecran CDC memDC; memDC.CreateCompatibleDC(&clientDC); //Determinam zona client CRect rcClient; GetClientRect(&rcClient); //Creem un bitmap compatibil cu atributele contextului //dispozitiv de pe ecran CBitmap memBitmap; memBitmap.CreateCompatibleBitmap(&clientDC,rcClient.Width(), rcClient.Height()); //l selectm n cadrul contextului dispozitiv de memorie memDC.SelectObject(&memBitmap);

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

//Parcurgem dreptunghiul de desenare pe orizontal for(int x=0; x<rcClient.Width(); x++) { // Parcurgem dreptunghiul de desenare pe vertical for(int y=0; y<rcClient.Height(); y++) { //Desenm fiecare pixel cu alt culoare; //desenarea are loc n memorie, n acest moment //nu se vede nimic memDC.SetPixel(x,y,x*y); } } //Copiem imaginea din memorie napoi n contextul //dispozitiv client; ntreaga imagine este copiat acum pe //ecran, devenind vizibil utilizatorului clientDC.BitBlt(0,0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY); }

Compilai i executai .