Sunteți pe pagina 1din 4

PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator 

Lucrarea de laborator 6.
Visual C++6.0 – MFC

Desenarea şi afişarea imaginilor folosind contexte de dispozitiv

Un context dispozitiv reprezintă suprafaţa pe care se desenează toate punctele, liniile, pătratele,
fonturile, culorile. Cuvântul “dispozitiv” din context dispozitiv înseamnă că se poate desena pe ecran, la
imprimantă, pe un plotter fără a cunoaşte prea multe detalii despre ce dispozitiv se foloseşte sau ce
marcă sau model este acesta.
Există un context dispozitiv standard brut, şi există contexte dispozitiv pentru situaţii speciale şi
operaţii particulare. MFC oferă încapsulări ale contextelor dispozitiv care simplifică interacţiunea cu
obiectele GDI aflate dedesubt. Clasa care încapsulează contextul dispozitiv standard brut este CDC.
Această clasă conţine un număr mare de funcţii de desenare, de mapare de coordonate şi de decupare
pentru implementarea reprezentărilor grafice. Toate celelalte clase de context dispozitiv, mai
specializate, sunt bazate pe această clasă şi o extind.
Capacitatea clasei CDC de a se ataşa ş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 excepţie nici fereastra suprafeţei de lucru, care se întinde pe întregul ecran.
Aplicaţia următoare acaparează un context dispozitiv şi îl foloseşte pentru desenare.
Exerciţiu 1. Creaţi o aplicaţie de tip SDI. Adăugaţi un buton cu numele Trasare (ID DrawIt)
resursei Edit de meniu din cadrul proiectului. Cu ajutorul ClassWizard trataţi mesajul generat de
apăsarea butonului, într-o funcţie OnDrawIt() situată în clasa CSDIView. Completaţi corpul
funcţiei cu următorul 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 aplicaţiei şi nu în fereastra suprafeţei de lucru


se foloseşte un pointer pDC de tip CClientDC. Se va folosi proiectul creat la punctul anterior,
modificându-se corpul funcţiei 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
când suprafaţa acesteia a fost descoperită parţial sau total de o altă fereastră.
În loc să se redeseneze întreaga fereastră de fiecare dată când este descoperită o mică porţiune,
Windows transmite coordonatele unui dreptunghi care încadrează zona descoperită. Aceste informaţii
se pot folosi pentru a desena exclusiv porţiunea afectată, fără 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 funcţia OnPaint()Pentru aceasta se parcurg următoarele etape:
Se selectează View, apoi ClasWizaed – sau direct CTRL –W;
Se va selecta clasa CSDIView şi Messages WM_PAINT;
Se va adăuga functia OnPaint() cu Add Function;
Se va selecta Edit Code.

Se va rescrie corpul funcţiei:


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 

Compilaţi şi rulaţi aplicaţia.


La prima afişare a ferestrei este transmis un mesaj WM_PAINT pentru redesenarea întregii
suprafeţe. Pentru a vedea efectul mesajului de redesenare, acoperiţi fereastra aplicaţiei cu o altă
fereastră. Deplasaţi apoi această fereastră până când nu se va mai suprapune peste fereastra aplicaţiei.
Se va observa că redesenarea se va face mai repede deoarece regiunea acoperită devine din ce în ce mai
mică, fiind astfel necesare mai puţine 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 obişnuit
pentru copierea şi lipirea unor zone de ecran. Este posibilă crearea unui context dispozitiv de memorie
compatibil cu un dispozitiv de afişare. Apoi se pot copia în memorie imaginile care nu mai sunt afişate,
aducându-le înapoi în contextul dispozitiv de afişare atunci când este nevoie.

Exerciţiu 2. Creaţi o aplicaţie de tip SDI. Adăugaţi un buton cu numele DrawIt resursei de
meniu din cadrul proiectului. Cu ajutorul ClassWizard trataţi mesajul generat de apăsarea butonului
într-o funcţie Draw() situată în clasa CSDIView. Completaţi corpul funcţiei cu următorul 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 selectăm î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++)
{
//Desenăm 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);
}

Compilaţi şi executaţi .

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