Sunteți pe pagina 1din 10

9

LABORATOR Nr. 5-6

WinAPI
Generai aplicaia Lab3 de tip Hello World, selectnd ca i tip de proiect Win32 Application.
(n fereastra n care se impune tipul aplicaiei selectai A typical Hello World Application).
Executai aplicaia.
1. Adugai aplicaiei clasele definite n laboratorul precedent (punct, segment, cerc i
element).
SOLUIE
Copiai n directorul curent (\Lab3\) fiierele punct.h, punct.cpp, segment.h, segment.cpp,
cerc.h, cerc.cpp, element.h i element.cpp. Adugai apoi proiectului fiierele copiate folosind
opiunea Project / Add to Project / Files

10
tergei n clasele punct, segment, cerc i element funciile afisez()

Adugai claselor punct, segment i cerc funciile desenez() definite ca mai jos :
void punct::desenez(HDC hdc)
{
HPEN hPen;
hPen=CreatePen(PS_SOLID, 1, col);
SelectObject(hdc, hPen);
MoveToEx(hdc, x-4, y, NULL);
LineTo(hdc, x+4, y);
MoveToEx(hdc, x, y-4, NULL);
LineTo(hdc, x, y+4);
DeleteObject(hPen);
}
void segment::desenez(HDC hdc)
{
HPEN hPen;
hPen=CreatePen(PS_SOLID, 1, col);
SelectObject(hdc, hPen);
MoveToEx(hdc, x, y, NULL);
LineTo(hdc, x+dx, y+dy);
DeleteObject(hPen);
}
void cerc::desenez(HDC hdc)
{
HPEN hPen;
hPen=CreatePen(PS_SOLID, 1, col);
SelectObject(hdc, hPen);
Ellipse(hdc, x-r, y-r, x+r, y+r);
DeleteObject(hPen);
}

11
Pentru a putea desena elementele grafice incluse ntr-o list, funcia punct : :desenez() va fi
declarat ca virtual.
Deschidei fiierul Lab3.cpp i adugai fiierele antet necesare utilizrii claselor aplicaiei :
#include "stdafx.h"
#include "resource.h"
#include "segment.h"
#include "cerc.h"
#include "element.h"
Cutai n Lab3.cpp funcia WndProc i modificai-o astfel:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
static punct a;
static punct b;
static segment s;
static cerc c;
switch (message)
{
case WM_CREATE:
// Generez doua puncte, un segment si un cerc
a = punct(10,10, RGB(255, 0, 0));
b = punct(100,100, RGB(255, 0, 0));
s = segment(10, 10, RGB(0, 255, 0), 90, 90);
c = cerc(55, 55, RGB(0, 0, 255), 15);
break;
case WM_COMMAND:
. . . . (rmne neschimbat) . . . . .
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
// Desenez elementele
a. desenez(hdc);
b. desenez(hdc);

12
s. desenez(hdc);
c.desenez(hdc);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Rezultat:

2.
Generai i reprezentai grafic o list de 100 segmente de dreapt, coordonatele
extremitilor fiind obinute folosind funcia de generare a numerelor aleatoare, rand(). Pentru
declanarea generatorului de numere aleatoare se folosete funcia srand() apelat astfel:
srand((unsigned) time (NULL));
Funcia time() returneaz numrul de secunde care au trecut de la ora 0, 1 ianuarie 1970.
Pentru utilizarea funciei time() va trebui inclus la nceputul fiierului Lab3.cpp fiierul antet
time.h.
Numrul generat va fi cuprins ntre 0 i RAND_MAX. Prototipurile funciilor rand() i
srand() precum i declaraia constantei RAND_MAX sunt n <stdlib.h>.
Pentru a desena un element din lista de segmente adugai clasei element funcia
desenez() definit astfel :
void element::desenez(HDC hdc)
{
p->desenez(hdc);
}

13

SOLUIE
Adugai aplicaiei fiierul antet <stdlib.h> i apoi modificai funcia WndProc ca mai jos:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
// Declar STATIC toate variabilele care trebuie sa se regaseasca la o noa apelare
static element *baza;
static element *e;
static long culoare;
punct *s;
int x, y, dx, dy;
switch (message)
{
case WM_CREATE:
culoare = RGB(0, 0, 255); // Desenez cu albastru
// Generez lista de segmente
// Pornesc generatorul de numere aleatoare:
srand( 2000 );
// Generez primul element din lista
// Primul punct
x = 20+rand()*500/RAND_MAX; // Pentru a avea valori intre 0 si 500
y = 20+rand()*500/RAND_MAX;
// Al doilea punct
dx = 20+rand()*500/RAND_MAX - x;
dy = 20+rand()*500/RAND_MAX - y;
// generez segmentul corespunzator
s = new segment(x, y, culoare, dx, dy);
e = new element(s, 1);
baza = e;
// Reiau de 30 ori
int i;
for(i=1; i<30; i++) {

14
// Primul punct
x = 20+rand()*500/RAND_MAX;
y = 20+rand()*500/RAND_MAX;
// Al doilea punct
dx = 20+rand()*500/RAND_MAX - x;
dy = 20+rand()*500/RAND_MAX - y;
// generez segmentul corespunzator
s = new segment(x, y, culoare, dx, dy);
e->urm = new element(s, 1);
e = e->urm; // Avansez pe noul element
}
break;
case WM_COMMAND:
. . . . . . . ( rmne neschimbat )
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
// desenez un chenar albastru:
HPEN hPen;
hPen=CreatePen(PS_SOLID, 1, RGB(0,0,255));
SelectObject(hdc, hPen);
MoveToEx(hdc, 20, 20, NULL);
LineTo(hdc, 20, 520);
LineTo(hdc, 520, 520);
LineTo(hdc, 520, 20);
LineTo(hdc, 20, 20);
DeleteObject(hPen);
// Desenez lista de segmente
e = baza;
while (e != NULL) {
e->desenez(hdc);
e = e->urm;
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}

15
return 0;
}
3. Modificai aplicaia astfel nct s deseneze o linie poligonal format din segmente ale
cror extremiti sunt indicate cu mouse-ul.
SOLUIE
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
// Declar STATIC toate variabilele care trebuie sa se regaseasca la o noa apelare
static element *baza=NULL;
static element *e;
static long culoare;
static int e_pct_2;
int dx, dy;
static POINT coord1;
punct *s;
POINT coord;
switch (message)
{
case WM_CREATE:
culoare = RGB(0, 0, 255); // Desenez cu albastru
e_pct_2 = 0;
break;
case WM_LBUTTONDOWN:
// Preiau coordonatele absolute ale cursorului
GetCursorPos(&coord);
// Preiau coord. cursorului f. de coltul zonei client
ScreenToClient(hWnd, (LPPOINT) &coord);
if(e_pct_2) {
// Generez segmentul de dreapta. In coord1 am primul capat.
dx = coord.x-coord1.x;
dy = coord.y-coord1.y;
s = new segment(coord1.x, coord1.y, culoare, dx,dy);

16

if (baza == NULL) { // e primul segment


e = new element(s, 1);
baza = e;
}
else {
// Merg pe ultimul segment din lista
e = baza;
while (e->urm != NULL) {
e = e->urm;
}
e->urm = new element(s, 1);
e = e->urm; // Avansez pe noul element
}
// Desenez segmentul curent
hdc = GetDC(hWnd);
e->desenez(hdc);
ReleaseDC(hWnd, hdc);
// Mut coordonatele pct. 2 in pct. 1.
coord1 = coord;
}
else { // Nu se poate trasa inca
coord1 = coord;
e_pct_2=1;
}
break;
..........
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
// Desenez lista de segmente
e = baza;
while (e != NULL) {
e->desenez(hdc);
e = e->urm;
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:

17
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
4. Modificai funcia WndProc() astfel nct la apasarea tastei END s se nceap
generarea unei noi linii poligonale iar la apsarea uneia dintre tastele 'r', 'g', sau 'b' s
modifice culoarea de desenare n rou, verde respectiv albastru..
SOLUIE
Adugai n WndProc() o secven de tratare a evenimentului WM_KEYDOWN, produs la
apsarea unei taste :
case WM_KEYDOWN:
switch (wParam)
{
case VK_END:
e_pct_2 = 0;
break;
case 'r': case 'R':
culoare = RGB(255, 0, 0); // Desenez cu rosu
break;
case 'g': case 'G':
culoare = RGB(0, 255, 0); // Desenez cu verde
break;
case 'b': case 'B':
culoare = RGB(0, 0, 255); // Desenez cu albastru
break;
}
break;
5. Modificai funcia WndProc() astfel nct la apsarea tastei 's' s deseneze segmente iar
la apsarea tastei 'c' s deseneze cercuri.
SOLUIE
.....
// Declar STATIC toate variabilele care trebuie sa se regaseasca la o noa apelare
static element *e, *baza=NULL;
static long culoare;
static int e_pct_2, tip
static POINT coord1;
punct *s;
POINT coord;

18
int dx, dy, raza;
. . . . . . . . . . . . .( neschimbat) . . . . . . . . .
case WM_LBUTTONDOWN:
// Preiau coordonatele cursorului
GetCursorPos(&coord);
// Preiau coord. cursorului f. de coltul zonei client
ScreenToClient(hWnd, (LPPOINT) &coord);
if(e_pct_2) {
dx = coord.x-coord1.x;
dy = coord.y-coord1.y;
if (tip == 1) {
// Generez segmentul de dreapta. In coord1 am primul capat.
s = new segment(coord1.x, coord1.y, culoare, dx, dy);
e_pct_2 = 0;
}
else {
raza = int(sqrt(dx*dx+dy*dy)); // includei <math.h>!
s = new cerc(coord1.x, coord1.y, culoare, raza);
e_pct_2 = 0;
}
if (baza == NULL) { // e primul segment
e = new element(s, 1);
baza = e;
}
else {
. . . . . . . .(neschimbat) . . . . . . .
case WM_KEYDOWN:
switch (wParam)
{
case VK_END:
e_pct_2 = 0;
break;
case 's': case 'S':
tip = 1; // Desenez segmente
e_pct_2 = 0;
break;
case 'c': case 'C':
tip = 2; // Desenez cercuri
e_pct_2 = 0;
break;
case 'r': case 'R':
culoare = RGB(255, 0, 0); // Desenez cu rosu
break;
. . . . . . . .(neschimbat) . . . . . . .

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