1234 Asdf [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

Ministerul Educaţiei al Republicii Moldova Universitatea Tehnică a Moldovei Facultatea Calculatoare Informatica si Microelectronica

RAPORT Lucrarea de laborator nr.3,4,5 Programarea in Windows

A efectuat: A verificat: lect., univ.

Lisnic Inga

Chisinau 2017 Tema: Curbe Bezier. Principiile de lucru cu tastatura. Principiile de lucru cu mouse-ul

Scopul lucrarii: 1.

De a studia primitivele grafice ce permit afişarea curbelor Bezier şi afişarea acestor curbe cu ajutorul formulelor.

2.

De a studia metodele şi principiile de lucru cu tastatura. Însuşirea modului de prelucrare a mesajelor parvenite de la tastatură

3.

De studiat metodele şi principiile de lucru cu mouse-ul; de însuşit modul de prelucrare a mesajelor parvenite de la mouse

Sarcina de lucru: 1.

Scrieţi un program care afişază curba Bezier, utilizând funcţiile GDI standarde şi o curbă Bezier, afişată după calcule prin formule.

2.

De scris un program care în zona clienbt afişează un desen, care poate fi mişcat cu ajutorul tastelor ← (la stânga), ↑(în sus), →(la dreapta), ↓(în jos). De asemenea, trebuie să fie prevăzute taste pentru rotirea figurii

3.

1. De modificat programul din lucrarea de laborator nr. 3 astfel ca punctele de control al curbei Bezier să poată fi deplasate, schimbînd forma curbei în timp real. 2. De modificat programul din lucrarea nr. 4 astfel ca desenul să poată fi mişcat cu ajutorul mouse-lui. Notiuni teoretice

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 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

1

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. Ştiu că acesta

este un criteriu subiectiv, dar nu este numai părerea mea. Arhitectura bazată pe mesaje a sistemului de operare Windows este ideală pentru lucrul cu tastatură. Programul „află" despre apăsarea unor taste prin intermediul mesajelor care ajung la procedura de fereastră. De fapt, lucrurile sunt puţin mai complicate: atunci când utilizatorul apasă şi eliberează tastele, driverul de tastatură transmite sistemului de operare informaţiile legate de acţiunile asupra tastelor. Windows salvează aceste acţiuni (sub formă de mesaje) în coada de aşteptare a sistemului. Mesajele de la tastatură sunt apoi transferate, unul câte unul, în coada de mesaje a programului căruia îi aparţine fereastra ce deţine „cursorul de intrare" (despre care vom discuta imediat). Programul distribuie mesajele procedurii de fereastră corespunzătoare. Tastatura trebuie să fie partajată de toate aplicaţiile rulate simultan sub Windows. Unele aplicaţii pot avea mai multe ferestre, iar tastatura trebuie să fie partajată de toate ferestrele din cadrul aceleiaşi aplicaţii. Atunci când este apăsată o tastă, o singură fereastră trebuie să primească mesajul privind apăsarea tastei respective. Fereastra care primeşte acest mesaj este fereastra care deţine „cursorul de intrare" („input focus"). Raspunsuri la intrebari: 1.

Ce se subînţelege sub noţiunea de “cursor de intrare”? Care sunt funcţiile lui? Sub noţiunea “cursor de intrare” se subînţelege fereastra a carei este activă pentru primirea acţiunilor din partea mousului, tastaturii sau a altui dispozitiv periferic. Funcţiile lui este de a indica dacă o fereastră anumită primeşte sau pierde cursorul de intrare. În aşa mod dacă o fereastră deţine “cursorul de intrare”, toate acţiunile îndeplinite de pe tastatură vor fi scrise în coada de aşteptare a ferestrei date.

2.

Ce valori conţin parametrii lParam şi wParam în timpul prelucrării mesajelor parvenite de la tastatură? În timpul prelucrării mesajelor parvenite de la tastatură, parametrul lParam(pe 32 de biţi), transmisă procedurii de fereastră este împărţită în şase cîmpuri: contorul de repetare, codul de scanare OEM, indicatorul flag pentru taste extinse, codul de context, starea anterioară a tastei şi starea de tranziţie. Parametrul wParam conţine codul virtual care identifică tasta apăsată sau eliberată.

3.

Ce reprezintă codul de scanare OEM? Codul de scanare OEM (OEM Scan Code) este codul de scanare al tastaturii, generat de componentele hardware. În general, aplicaţiile Windows ignorează acest cod, deoarece există metode mai bune de decodificare a informaţiilor de la tastatură.

4.

Cum se obţine starea unei taste? 2

Pentru a obţine starea oarecărei taste, folosim funcţia GetKeyState, această funcţie este folosită, de obicei, pentru obţinerea stării tastelor de modificare (Shift, Alt şi Ctrl) şi a tastelor de comutare (Caps Lock, Num Lock¸ şi Scroll Lock). 5.

Cum se verifică dacă mouse-ul este instalat şi câte butoane are? Putem să determinăm dacă mouse-ul este prezent folosind funcţia GetSystemMetrics: 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 mouseului instalat, folosiţi funcţia GetSystemMetrics: cButtons = GetSystemMetrics(SM_CMOUSEBUTTONS); Această funcţie returnează valoarea 0 dacă mouse-ul nu este instalat.

6.

Unde se specifică indicatorul predefinit al mouse-lui? Indicatorul predefinit al unei ferestre este specificat la definirea structurii clasei de ferestre. De exemplu: wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

7.

Ce valori conţin parametrii lParam şi wParam în timpul prelucrării mesajelor parvenite de la mouse-ul? Pentru toate mesajele, parametrul lParam conţine poziţia mouse-ului. Cuvîntul mai puţin semnificativ conţine coordonata pe axa z, relative la colţul din stînga-sus al zonei client a ferestrei. Puteţi să extrageţi coordonatele pe axele x şi z din parametrul lParam folosind macroinstrucţiunile LOWORD şi HIWORD, definite în fişierele antet din Windows. Valoarea parametrului wParam indică starea butoanelor mouse-ului şi starea tastelor Shift şi Ctrl.

8.

În ce cazuri procedura de fereastră prelucrează mesajele generate de dublu-clic, efectuat pe butonul mouse-ului? Dacă vrem ca procedura de fereastră să primească mesajele generate de dublu-clic, trebuie să includeţi identificatorul CS_DBLCLKS în stilul ferestrei, atunci cînd definiţi structura clasei de ferestre, înaintea apelării funcţiei RegisterClassEx: Wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBCLKS Dacă în stilul ferestrei nu este inclus identificatorul CS_DBCLKS şi utilizatorul execută d două ori clic pe butonul din stînga al mouse-ului într-o succesiune rapidă, procedura de fereastră va recepţiona următoarele mesaje: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDOWN şi WM_LBUTTONUP.

Listingul programului 3

#include #include #include #include #include #include #pragma comment (lib, "Gdiplus.lib") using namespace Gdiplus; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); struct { int x, y; } pos = { 900,100 }; struct{float x, y;} stretch = { 1 }; struct{int x;} rotate = { 0 }; int x, y, z = 0; POINT pt[4]; HPEN hNewPen; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("Window"); HWND hwnd; MSG msg; WNDCLASSEX wndclass; GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // #Inregistrarea clasei ferestrei wndclass.cbSize = sizeof(wndclass); //cbSize reprezinta dimensiunea structurii wndclass.style = CS_HREDRAW | CS_VREDRAW;//se restabileste de fiecare data cand fereastra este redimensionata, fie pe orizontala sau pe verticala wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_INFORMATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //GetStockObject obtine un obiect grafic (in acest caz o pensula folosita pentru desenarea fondului ferestrei) wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon(NULL, IDI_INFORMATION); if (!RegisterClassEx(&wndclass)) { //inregistreaza o clasa de fereastra pentru fereastra programului MessageBox(NULL, TEXT("Inregistrarea ferestrei a esuat!"), TEXT("Eroare!"), MB_ICONEXCLAMATION | MB_OK); return 0; } // #Crearea ferestrei hwnd = CreateWindow(szAppName, // numele clasei de fereastra (creaza o fereastra pe baza unei clase de fereastra ) TEXT("Laborator"), // titlul ferestrei WS_TILEDWINDOW, // stilul ferestrei CW_USEDEFAULT, // pozitia initiala pe axa x CW_USEDEFAULT, // pozitia initiala pe axa y 1366, // dimensiunea initiala pe axa x 760, // dimensiunea initiala pe axa y NULL, // variabila handle a ferestrei parinte NULL, // variabila handle a meniului hInstance, // variabila handle a instantei programului NULL); // parametri de creare ShowWindow(hwnd, SW_MAXIMIZE); UpdateWindow(hwnd); // #Bucla de mesaje while (GetMessage(&msg, NULL, 0, 0)) {

4

TranslateMessage(&msg); DispatchMessage(&msg); } GdiplusShutdown(gdiplusToken); return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc, hCompatibleDC; PAINTSTRUCT ps; RECT rect; HANDLE hOldBitmap; HANDLE hBitmap; BITMAP Bitmap; HBRUSH hBrush; static POINT apt[4]; switch (iMsg) { case WM_SIZE: apt[0].x = 90; apt[0].y = 90; apt[1].x = 180; apt[1].y = 200; apt[2].x = 250; apt[2].y = 50; apt[3].x = 490; apt[3].y = 150; pt[0].x = 90; pt[0].y = 375; pt[1].x = 180; pt[1].y = 475; pt[2].x = 250; pt[2].y = 325; pt[3].x = 490; pt[3].y = 435; return 0; case WM_PAINT: { pos.x = pos.x > 1220 ? 1220 : pos.x; pos.y = pos.y > 560 ? 560 : pos.y; pos.x = pos.x < 862 ? 862 : pos.x; pos.y = pos.y < 145? 145 : pos.y; hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); TextOut(hdc, 0, 0, TEXT("Tastele de control: Bezier-mouse left click; Imagine-mouse right click"), 71); TextOut(hdc, 0, 15, TEXT("Miscare imagineUp(sus),Right(dreapta),Down(jos),Left(stinga)"), 61); TextOut(hdc, 0, 30, TEXT("Rotire imagine-PgUP,PgDown"), 26); MoveToEx(hdc, 715, 0, NULL);// punctul initial (x,y) LineTo(hdc, 715, 760); // punctul final (x,y) MoveToEx(hdc, 0, 370, NULL); LineTo(hdc, 715, 370); PolyBezier(hdc, apt, 4); SelectObject(hdc, hNewPen); MoveToEx(hdc, pt[0].x, pt[0].y + 190, NULL); for (float t = 0; t < 1; t += 0.01) { x = pow((1 - t), 3)*pt[0].x + 3 * t*pow((1 - t), 2)*pt[1].x + 3 * t*t*(1 - t)*pt[2].x + t*t*t*pt[3].x; y = pow((1 - t), 3)*pt[0].y + 3 * t*pow((1 - t), 2)*pt[1].y + 3 * t*t*(1 - t)*pt[2].y + t*t*t*pt[3].y - 130; LineTo(hdc, x, y + 320); } hBitmap = (HBITMAP)LoadImage(NULL, TEXT("image.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); Graphics graphics(hdc); ImageAttributes IAttr; RectF destination(25, 80, rect.right, rect.bottom); Image image(L"image.bmp");

5

graphics.TranslateTransform(pos.x , pos.y); graphics.RotateTransform(rotate.x); graphics.TranslateTransform(-150, -150); graphics.ScaleTransform(stretch.x, stretch.y); graphics.DrawImage(&image, destination, 0, 0, 1400, 700, UnitPixel, &IAttr); EndPaint(hwnd, &ps); break; } case WM_KEYDOWN: switch (wParam){ case VK_RIGHT: if (pos.x < 1220) { pos.x+=5; InvalidateRect(hwnd, NULL, TRUE); } break; case VK_LEFT: if (pos.x > 862) { pos.x-=5; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } break; case VK_UP: if (pos.y > 145) { pos.y-=5; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } break; case VK_DOWN: if (pos.y < 560) { pos.y+=5; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } break; case 0x21: rotate.x--; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; case 0x22: rotate.x++; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; } break; case WM_MOUSEMOVE: /*z++; if (z != 0 && z % 10 != 0) { break; }*/ if (wParam & MK_LBUTTON || wParam & MK_RBUTTON) { hdc = GetDC(hwnd); SelectObject(hdc, GetStockObject(BLACK_PEN)); PolyBezier(hdc, apt, 4); if (wParam & MK_LBUTTON) { apt[1].x = LOWORD(lParam); apt[1].y = HIWORD(lParam); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } if (wParam & MK_RBUTTON) { pos.x = LOWORD(lParam);

6

pos.y = HIWORD(lParam); InvalidateRect(hwnd, NULL,TRUE); UpdateWindow(hwnd); } SelectObject(hdc, GetStockObject(BLACK_PEN)); PolyBezier(hdc, apt, 4); } break; return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, iMsg, wParam, lParam); }

Rezultatele obtinute

Concluzii În urma executării acestei lucrări de laborator am studiat primitivele ce permit afișarea curbelor Bezier cît cu ajutorul formulei predefinite atît și cu utilizarea formulelor matematice. Pentru realizarea sarcinii propuse am creat un program ce generează două curbe Bezier și le afișează pe ecran. Am studiat metodele și principiile de lucru cu tastatura și am însușit modul de prelucrare a mesajelor provenite de la tastatură pentru a realiza sarcina propusă am creat un program simplu care afișează o figură geometrică ce poate fi mișcată sau rotită cu ajutorul tastelor. Si am sușit modul de prelucrare a mesajelor provenite de la mouse. Pentru a realiza sarcina propusă am creat un program interactiv ce generează o fereastră cu un desen ce poate fi mișcat cît cu tastele atît și cu ajutorul mișcării mouse-ului.

7