GDI dispozitive rastru dispozitive vectoriale

Similar documents
VISUAL FOX PRO VIDEOFORMATE ŞI RAPOARTE. Se deschide proiectul Documents->Forms->Form Wizard->One-to-many Form Wizard

GRAFURI NEORIENTATE. 1. Notiunea de graf neorientat

Pasul 2. Desaturaţi imaginea. image>adjustments>desaturate sau Ctrl+Shift+I

Ghid de instalare pentru program NPD RO

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Split Screen Specifications

Modalităţi de redare a conţinutului 3D prin intermediul unui proiector BenQ:

Parcurgerea arborilor binari şi aplicaţii

PREZENTARE INTERFAŢĂ MICROSOFT EXCEL 2007

Split Screen Specifications

Exerciţii Capitolul 4

Sistemul de operare Windows (95, 98) Componenta My Computer

1. Noţiuni elementare de WinApi

4 Caracteristici numerice ale variabilelor aleatoare: media şi dispersia

Circuite Basculante Bistabile

9. MENIURI si OBIECTE MULTIMEDIA

SUBIECTE CONCURS ADMITERE TEST GRILĂ DE VERIFICARE A CUNOŞTINŢELOR FILIERA DIRECTĂ VARIANTA 1

Curs 3 Word 2007 Cuprins

Operaţiile de sistem de bază

Mail Moldtelecom. Microsoft Outlook Google Android Thunderbird Microsoft Outlook

Geographical data management in GIS systems

Reprezentări grafice

Anexa 2. Instrumente informatice pentru statistică

MODULUL 2 UTILIZAREA SISTEMULUI DE OPERARE WINDOWS XP CURSUL UTILIZAREA CALCULATORULUI PERSONAL; APLICAREA TIC ÎN ŞCOALĂ ŞI AFACERI


Click pe More options sub simbolul telefon (în centru spre stânga) dacă sistemul nu a fost deja configurat.

Teoreme de Analiză Matematică - II (teorema Borel - Lebesgue) 1

ELEMENTE DE INTERFATA ALE UNUI SISTEM DE OPERARE

riptografie şi Securitate

Aplicatii ale programarii grafice in experimentele de FIZICĂ

10 Estimarea parametrilor: intervale de încredere

Algoritmică şi programare Laborator 3

22METS. 2. In the pattern below, which number belongs in the box? 0,5,4,9,8,13,12,17,16, A 15 B 19 C 20 D 21

Realizarea prezentărilor electronice folosind Microsoft Power Point 2010

TTX260 investiţie cu cost redus, performanţă bună

Capitolul V MODELAREA SISTEMELOR CU VENSIM

6. MPEG2. Prezentare. Cerinţe principale:

EPI INFO. - Cross-tabulation şi testul 2 -

MODULUL 2 UTILIZAREA SISTEMULUI DE OPERARE WINDOWS VISTA CURSUL UTILIZAREA CALCULATORULUI PERSONAL; APLICAREA TIC ÎN ŞCOALĂ ŞI AFACERI

Rigla şi compasul. Gabriel POPA 1

Programare Windows I Visual C++ Curs 9

Windows Programming with MFC. Computer Graphics Hardware. Computer Graphics. Binghamton University. EngiNet. Thomas J. Watson

LESSON FOURTEEN

9.1. Structura unităţii de I/E. În Figura 9.1 se prezintă structura unui sistem de calcul împreună cu unitatea

Tehnologia Informaţiei şi a Comunicaţiilor

Defuzzificarea într-un sistem cu logică fuzzy. Aplicaţie: maşina de spălat cu reguli fuzzy. A. Obiective. B. Concepte teoretice ilustrate

Ghid de utilizare a platformei e-learning

ARHITECTURA CALCULATOARELOR 2003/2004 CURSUL 10

GREUTATE INALTIME IMC TAS TAD GLICEMIE

Un tip de data este caracterizat de: o O mulţime de date (valori є domeniului) o O mulţime de operaţii o Un identificator.

1. Funcţii speciale. 1.1 Introducere

Biostatistică Medicină Generală. Lucrarea de laborator Nr Intervale de încredere. Scop: la sfârşitul laboratorului veţi şti:

ARHITECTURA SISTEMELOR DE CALCUL ŞI SISTEME DE OPERARE. LUCRĂRILE DE LABORATOR Nr. 12, 13 şi 14

Laboratorul 1. Primii paşi în Visual Basic.NET

directorul ATESTAT de pe desktop.

Structura sistemelor de operare Windows şi Linux

Press review. Monitorizare presa. Programul de responsabilitate sociala. Lumea ta? Curata! TIMISOARA Page1

CUPRINS CAP. 1. PREZENTARE GENERALĂ

O abordare orientată pe componente generice pentru crearea dinamică a interfeţelor cu utilizatorul

Ghidul administratorului de sistem

Hama Telecomanda Universala l in l

Pagini Web prin Microsoft Frontpage. Crearea de pagini web. Introducere

1. Ecuaţii diferenţiale de ordinul întâi

2. PORŢI LOGICE ( )

Mediul XWindow. Dr. Sabin-Corneliu. Facultatea de Informatică Universitatea A.I.Cuza Iaşi, România ://

Paradoxuri matematice 1

GHIDUL UTILIZATORULUI DE REŢEA

Application form for the 2015/2016 auditions for THE EUROPEAN UNION YOUTH ORCHESTRA (EUYO)

Project Title. SPANA Development of Multimedia Tool for Learning Speech. Analysis. Supervisor: Dr. M.W. Mak

MANUAL DE UTILIZARE. 2. Nomenclator Curs Produse Clienti Introducere Facturi

Universitatea din Bucureşti. Facultatea de Matematică şi Informatică. Şcoala Doctorală de Matematică. Teză de Doctorat

Biraportul în geometria triunghiului 1

DIRECTIVA HABITATE Prezentare generală. Directiva 92/43 a CE din 21 Mai 1992

CURSUL 4 STOCARE ŞI VIRTUALIZAREA STOCĂRII ÎN SISTEME INFORMATICE

declarare var <identif>:array[<tip1>,<tip2>,...] of <tip_e>; var a: array[1..20] of integer; (vector cu 20 elemente)

PROBLEME DE TEORIA NUMERELOR LA CONCURSURI ŞI OLIMPIADE

TIPURI DE DISPOZITIVE DE INTRARE, DE IESIRE, DE INTRARE IESIRE, DE STOCARE A DATELOR

Poo Laboratoare 1. Laborator Programare cu JTable & JTree JTable JTree... 2

Laboratorul 1. MS Word

Ghid de Instalare Windows Vista

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Conferinţa Naţională de Învăţământ Virtual, ediţia a IV-a, Graph Magics. Dumitru Ciubatîi Universitatea din Bucureşti,

O VARIANTĂ DISCRETĂ A TEOREMEI VALORII INTERMEDIARE

Construirea interfeţei utilizator

Manualul utilizatorului

CAPITOLUL 2. FACILITATILE SI ARHITECTURA SISTEMULUI ORACLE

Obiectivele acestui modul sunt:

BAZE DE DATE SI PRELUCRARI STATISTICE

CURS Nivele de management al SAN Nivelul de stocare *I LTO Tape Library Specialist

Sistemul de semnalizare SS7. Petre Ogruţan, ianuarie 2015

Maria plays basketball. We live in Australia.

TUTORIAL: EVALUAREA SUSCEPTIBILITĂŢII LA EROZIUNE PRIN ANALIZĂ BIVARIATĂ

Start with some basics: display devices

E-MANUAL. Model Număr de serie

INTRODUCERE DEMONSTRATIVĂ LECŢIE OPERATOR CALCULATOR

OLIMPIADA INTERNAŢIONALĂ DE MATEMATICĂ FORMULA OF UNITY / THE THIRD MILLENIUM 2014/2015 RUNDA A DOUA

ANALIZA STATICĂ A UNEI STRUCTURI DE TIP PANOU

3. CPU 3.1. Setul de regiştri. Copyright Paul GASNER

Programarea calculatoarelor CURS 1

Sisteme de operare şi programe specifice. Material de predare partea a I-a. Material de învăţare

Transcription:

GDI Biblioteca GDI32.DLL GDI = permite manipularea elementelor grafice independente de dispozitiv, este un sistem de afisare static, ce permite numai animatii simple; Dipozitive grafice de iesire: 1. dispozitive rastru = reprezentare imagine prin matrice de puncte (placi video, imprimante matriciale, laser); 2. dispozitive vectoriale = deseneaza imaginile prin linii = plottere; Sistem de coordonate virtual, sistem de coordonate al dispozitivului; W95 foloseste coordonate in numere intregi pe 16 biti, W_NT foloseste coordonate pe 32 biti; Din pdv al programatorului, interfata GDI este formata din citeva sute de rutine si unele tipuri de date, macroinstructiuni si structuri de date; Tipuri de apeluri de functii Functii care obtin (sau creaza) si elibereaza (sau distrug) un context de dispozitiv; (in API: BeginPaint... EndPaint, GetDc, ReleaseDC; in MFC (clase): CDC, CPaintDC, CClientDC, CMetaFileDC, CWindowDC) Functii care obtin informatii despre contextul de dispozitiv - structura TEXTMETRICS, GetTextMetrics; Functii care deseneaza ceva (TextOut, DrawText, desenarea liniilor, a zonelor colorate si a imaginilor bitmap...); Functii care stabiliesc sau obtin atribute ale contextului de dispozitiv - Un atribut al DC specifica modul de lucru al functiilor de desenare; SetTextColor,... Toate atributele DC au valori prestabilite care devin active la obtinerea DC. Pentru fiecare functie de tip Set exista si o functie de tip Get, folosita pt. obtinerea valorilor curente ale atributelor DC. Functii care lucreaza cu obiecte GDI; Primitive GDI Linii si curbe: linii drepte, dreptunghiuri, elipse, arce. Liniile sint desenate folosind penita (HPEN, clasa CPen) curenta selectata in DC Suprafete pline: Suprafata poate fi umpluta folosind pensula GDI curenta (HBRUSH, clasa CBrush) Imagini bitmap: matrici dreptunghiulare de biti, care corespund pixelilor unui dispozitiv de afisare - pt. sisteme grafice de tip rastru. Imagini bitmap - dependente de dispozitiv si imagini bitmap independente de dispozitiv (DIB = Device Independent Bitmap) care pot fi stocate in fisiere. Text: afisarea textului este legata de fonturi (HFONT, clasa CFont). Alte aspecte ale GDI: Moduri de mapare si transformari: sitem de coordonate in pixeli, inci, mm Metafisiere (metafiles): o colectie de comenzi GDI stocate intr-o forma binara; sint folosite pentru transferarea reprezentarilor unor elemente grafice vectoriale prin intermediul memoriei temporare (clipboard). 1

Cai (paths): colectie de linii drepte si curbe stocate intern de GDI; pot fi folosite pt. desenare, umplere sau decupare. Decupare (clipping): desenarea poate fi limitata la o anumita sectiune a zonei client, numita zona de decupare - definita in general de o cale sau de o regiune. Tiparire (printing): Contextul de dispozitiv (DC): Modalitati de obtinere a variabilei handle a DC: Varainata 1(putem desena numai in regiunea invalida a ferestrei): la tratarea mesajului WM_PAINT: PAINTSTRUCT ps; hdc = BeginPaint (hwnd, &ps);... EndPaint(hwnd, &ps); structura PAINTSTRUCT contine o structura de tip RECT rcpaint; care defineste dreptunghiul ce cuprinde regiunea invalida a zonei client a ferestrei; se valideaza regiunea invalida. Varianta 2 (putem desena in toata zona client a ferestrei; nu se valideaza regiunea invalida ale zonei client): hdc = GetDC(hwnd);... ReleaseDC(hwnd, hdc); Varianta 3: (DC cuprinde in plus bara de titlu a ferestrei, barele de derulare si chenarul) hdc = GetWindowDC(hwnd);... ReleaseDC(hwnd, hdc); Pentru folosirea acestei functii trebuie interceptat mesajul WM_NCPAINT ( non client paint). Varianta 4: CreateDC hdc = CreateDC(pszDriver, pszdevice, pszoutput, pdata);... DeleteDC(hdc); Pentru a obtine o variabila handle a DC pt. spatiul de afisare: hdc = CreateDC( DISPLAY, NULL, NULL, NULL); 2

Varianta 5: Obtinere informatii despre DC - CreateIC care are aceeasi parametri ca si CreateDC hdc = CreateIC(pszDriver, pszdevice, pszoutput, pdata);... DeleteDC(hdc); Varianta 6: context de dispozitiv in memorie - necesar la lucrul cu imagini bitmap: hdcmem = CreateCompatibleDC (hdc)... DeleteDC(hdcMem); Crearea unui metafisier: hdcmeta = CreateMetaFile(pszFileName);... hmf = CloseMetaFile(hdcMeta); Obtinere informatii despre contextul de dispozitiv: dimensiuni ecran (pixeli, fizice) posibilitati de folosire a culorilor, etc. cu functia GetDeviceCaps (get device capabilities); ivalue = GetDeviceCaps(hdc, iindex); Atributele Contextului de Dispozitiv Cele mai uzuale atribute ale DC sunt date in urmatorul tabel: Attribute Default Set with Get with Text color Black CDC::SetTextColor CDC::GetTextColor Background color White CDC::SetBkColor CDC::GetBkColor Background mode OPAQUE CDC::SetBkMode CDC::GetBkMode Mapping mode MM_TEXT CDC::SetMapMode CDC::GetMapMode Drawing mode R2_COPYPEN CDC::SetROP2 CDC::GetROP2 Current position (0,0) CDC::MoveTo CDC::GetCurrentPosition Current pen BLACK_PEN CDC::SelectObject CDC::SelectObject Current brush WHITE_BRUSH CDC::SelectObject CDC::SelectObject Current font SYSTEM_FONT CDC::SelectObject CDC::SelectObject GDI Moduri de desenare functia SetROP2 Mod de desenare R2_NOP R2_NOT Operatii executate dest = dest dest = NOT dest 3

R2_BLACK R2_WHITE R2_COPYPEN R2_NOTCOPYPEN R2_MERGEPENNOT R2_MASKPENNOT R2_MERGENOTPEN R2_MASKNOTPEN R2_MERGEPEN R2_NOTMERGEPEN R2_MASKPEN R2_NOTMASKPEN R2_XORPEN R2_NOTXORPEN dest = BLACK dest = WHITE dest = src dest = NOT src dest = (NOT dest) OR src dest = (NOT dest) AND src dest = (NOT src) OR dest dest = (NOT src) AND dest dest = dest OR src dest = NOT (dest OR src) dest = dest AND src dest = NOT (dest AND src) dest = src XOR dest dest = NOT (src XOR dest) Moduri de mapare functia SetMapMode Mod de mapare Distanta ce corespunde la o Axa x Axa y unitate logica MM_TEXT Pixel spre dreapta in jos MM_LOMETRIC 0,1 mm spre dreapta in sus MM_HIMETRIC 0,01 mm spre dreapta in sus MM_LOENGLISH 0.01 inci spre dreapta in sus MM_HIENGLISH 0.001 inci spre dreapta in sus MM_TWIPS 1/1440 inci spre dreapta in sus MM_ISOTROPIC arbitrar (x = y) Selectabil selectabil MM_ANISOTROPIC Arbitrar (x!=y) Selectabil Selectabil Vizorul si fereastra SetWindowExt seteaza extensia ferestrei marimea dorita a ferestrei in unitati logice. SetViewportExt seteaza extensia vizorului marimea in pixeli a ferestrei in care desenam.. Marimea fereastrei este masurata in unitati logice. Marimea viewport-ului este masurata in unitati de dispozitiv, sau pixeli. In modul MM_ISOTROPIC ordinea de apel este SetWindowExt si apoi SetViewportExt. Exemple de cod CRect rect; GetClientRect (&rect); dc.setmapmode (MM_ANISOTROPIC); dc.setwindowext (500, 500); 4

dc.setviewportext (rect.width (), rect.height ()); dc.ellipse (0, 0, 500, 500); Originea este in coltul din stanga sus. CRect rect; GetClientRect (&rect); dc.setmapmode (MM_ANISOTROPIC); dc.setwindowext (500, -500); dc.setviewportext (rect.width (), rect.height ()); dc.ellipse (0, 0, 500, -500); Modul MM_ISOTROPIC CRect rect; GetClientRect (&rect); dc.setmapmode (MM_ISOTROPIC); dc.setwindowext (500, 500); dc.setviewportext (rect.width (), rect.height ()); dc.ellipse (0, 0, 500, 500); Pentru vizor se folosesc coordonatele de dispozitiv (pixeli). Pentru toate modurile de mapare, Windows transforma coordonatele ferestrei (coordonate logice) in coordonate ale vizorului (coordonate de dispozitiv) folosind doua formule: xviewport = (xwindow - xwinorg) * (xviewext / xwinext) + xvieworg yviewport = (ywindow - ywinorg) * (yviewext / ywinext) + yvieworg unde (xwindow, ywindow) este punct in coordonate logice care trebuie translatat; (xviewport, yviewport) este punct in coordonate de dispozitiv; (xwinorg, ywinorg) = originea ferestrei in coordonate logice; (xvieworg, yvieworg) = originea vizorului in coordonate dispozitiv. Formulele de mai sus implica faptul ca punctul (xwinorg, ywinorg) este intotdeauna mapat la punctul (xvieworg, yvieworg). (xwinext, ywinext) = extensia ferestrei in coordonate logice; (xviewext, yviewext) = extensia vizorului in coordonate de dispozitiv; In majoritatea modurilor de mapare aceste extensii sint prestabilite si nu pot fi modificate. Raportul intre extensia vizorului si extensia ferestrei reprezinta un factor de scalare folosit pentru convertirea unitatilor logice in unitati de dispozitiv. Extensiile pot avea valori negative: aceasta inseamna ca nu este obligatoriu ca valorile pe axa x sa creasca spre dreapta si valorile pe axa y sa creasca in jos. 5

Functiile folosite pentru a realiza conversia intre puncte reprezentate in coordonate de dispozitiv in puncte reprezentate in coordonate logice si invers sunt: DPtoLP(hdc, ppoints, inumber); LPtoDP(hdc, ppoints, inumber); ppoints = matrice de structuri POINT inumber = numarul de puncte care urmeaza a fi convertite. Daca dorim sa stim unde este punctul din centru in unitati MM_LOENGLISH, trebuie sa folosim DPtoLP : CRect rect; GetClientRect (&rect); CPoint point (rect.width () / 2, rect.height () / 2); CClientDC dc (this); dc.setmapmode (MM_LOENGLISH); dc.dptolp (&point); DPtoLP va returna coordonatele punctului central in coordonate logice. Daca dorim sa stim coordonatele in pixeli al punctului de coordonate logice (100,100) in modul de mapare MM_LOENGLISH vom folosi LPtoDP: CPoint point (100, 100); CClientDC dc (this); dc.setmapmode (MM_LOENGLISH); dc.lptodp (&point); Modul MM_TEXT Functiile SetViewportOrgEx si SetWindowOrgEx modifica originea vizorului si a ferestrei. Aceste functii au ca efect deplasarea axelor astfel incit punctul de coordonate (0,0) nu se mai refera la coltul din stanga sus al ecranului. In general se foloseste doar una din cele doua functii. Explicati asupra lucrului cu aceste functii: daca schimbam originea vizorului la (xvieworg, yvieworg) atunci punctul logic de coordonate (0,0) va fi mapat la punctul de coordonate de dispozitiv (xvieworg, yvieworg). daca schimbam originea ferestrei la (xwinorg, ywinorg) atunci acest punct logic va fi mapat la punctul de coordonate de dispozitiv (0,0) care este intotdeauna coltul din stinga sus al zonei client. Exemplu Mutare origine 6

Sa presupunem ca zona client are latimea cxclient si inaltimea cyclient. Daca dorim ca punctul de coordonate logice (0,0) sa se afle in centrul zonei client, atunci: SetViewportOrgEx(hdc, cxclient/2, cyclient/2, NULL); Valorile logice ale axei x sint cuprinse in intervalul [-cxclient/2, cxclient/2], iar cele ale axei y in intervalul [-cyclient/2, cyclient/2]. Afisarea de text incepind cu coltul din stanga sus, care are coordonatele de dispozitiv (0,0) inseamna folosirea urmatoarelor coordonate logice: TextOut(hdc, -cxclient/2, -cyclient/2,...,...); Acelasi rezultat poate fi obtinut si cu functia SetWindowOrgEx in locul functiei SetViewportOrgEx: SetWindowOrgEx(hdc, -cxclient/2, -cyclient/2, NULL); Setarea extent-ului O aplicatie poate modifica in mod direct extentul ferestrei sau al vizorului numai daca modul de mapare este MM_ISOTROPIC sau MM_ANISOTROPIC. Modficarea extentului ferestrei se face cu ajutorul functiei SetWindowExt, iar extentul vizorului se modifica cu functia SetViewportExt. Valorile se dau totdeauna in unitati absolute, nu in unitati logice si nu sunt afectate de modul curent de mapare. Setarea unui extent la valoarea zero nu este permisa. Din cauza ca perechea de extent-uri stabileste un factor de scalare ce va fi folosit in conversii, marimea extentului ar trebui sa fie cat mai mica posibila pentru a simplifica calculele, de exemplu folosirea de extent-uri de 400 si 300 este echivalent cu exetent-uri de 4 si 3. Pentru a schimba orientarea unei axe (fata de orientarea implicita data de Windows), factorul de scalare trebuie sa fie negativ. Urmatorul cod are ca efect schimbarea orientarii axei y, y pozitiv va fi in sus. SetMapMode(hDC, MM_ANISOTROPIC); SetViewportExt(hDC, 1, -1); SetWindowExt(hDC, 1, 1); 7

Setarea originilor Functiile folosite sunt: SetWindowOrg, OffsetWindowOrg, SetViewportOrg si OffsetViewportOrg. Originile sunt independente de extent. Originile sunt specificate in unitati absolute ce nu sunt afectate de modul curent de mapare. Exemple Setam un mod de mapare in care la o unitate logica ii corespund trei unitati de dispozitiv: SetMapMode(hDC, MM_ANISOTROPIC); SetWindowOrg(hDC, 0, 0); SetWindowExt(hDC, 1, 1); SetViewportOrg(hDC, 0, 0); SetViewportExt(hDC, 3, 3); Urmatorul cod deseneaza un dreptunghi de 1 pe 2 mm. SetMapMode(hDC, MM_HIMETRIC); SetViewportOrg(hDC, 0, 100); // Ce...? SetWindowOrg(hDC, 0, 0); Rectangle(hDC, 0, 0, 100, 200); Unitatile de dispozitiv sunt mapate la rezolutia dispozitivului fizic: SetMapMode(hDC, MM_ANISOTROPIC); SetWindowOrg(hDC, 0, 0); SetWindowExt(hDC, 600, 600); // logical window is 600 dpi SetViewportOrg(hDC, 0, 0); // Device viewport is dpi of actual output device. SetViewportExt(hDC, GetDeviceCaps(hDC, LOGPIXELSX), GetDeviceCaps(hDC, LOGPIXELSY)); 8

Obtinerea informatiilor despre un periferic Functia CDC::GetDeviceCaps Urmatorul cod obtine rezolutia ecranului, in pixeli: CClientDC dc (this); int cx = dc.getdevicecaps (HORZRES); int cy = dc.getdevicecaps (VERTRES); Functia GetDeviceCaps va returna totdeauna valori fizice corecte pentru imprimanta sau orice alt periferic hardcopy (de exemplu LOGPIXELSX si LOGPIXELSY). Pentru o imprimanta laser cu 600 dpi, LOGPIXELSX si LOGPIXELSY vor avea valoarea 600. Useful GetDeviceCaps Parameters Parameter Returns HORZRES Width of the display surface in pixels VERTRES Height of the display surface in pixels HORZSIZE Width of the display surface in millimeters VERTSIZE Height of the display surface in millimeters LOGPIXELSX Number of pixels per logical inch horizontally LOGPIXELSY Number of pixels per logical inch vertically NUMCOLORS For a display device, the number of static colors; for a printer or plotter, the number of colors supported BITSPIXEL Number of bits per pixel PLANES Number of bit planes RASTERCAPS Bit flags detailing certain characteristics of the device, such as whether it is palettized and whether it can display bitmapped images TECHNOLOGY Bit flags identifying the device type screen, printer, plotter, and so on 9

Desenarea pe ecran (Exemple de cod) Windows este un SO independent de dispozitiv. Pentru că nu ştim niciodată dinainte ce tipuri de periferice pot fi conectate la sistemul utilizatorului, nu putem face presupuneri despre posibilităţile de afişare ale acestora. Funcţiile care desenează pe ecran, trebuie să facă acest lucru indirect prin intermediul aşa numitelor contexte de dispozitiv (DC). Windows manipulează perifericele cu ajutorul driver-elor instalate de utilizator pe sistem. Aceste drivere interceptează datele pe care aplicaţiile doresc să le afişeze şi apoi translatează aceste date pentru perifericul respectiv pentru a fi reprezentate cât mai corect. Driverele de dispozitiv trebuie să ia cerinţele de afişare să le ajusteze (fine tuning) funcţie de perifericul (dispozitivul) pe care vor apărea. Există o structură de date, cunoscută sub numele de context de dispozitiv, care leagă aplicaţia de driverul dispozitivului. Un context de dispozitiv este mai mult decât o structură de date în memorie care păstrează atributele suprafeţei de desenare a ferestrei. Aceste atribute includ: peniţa, pensula, fontul, etc. Un DC conţine la un moment dat o singură peniţă (de exemplu). Pentru a folosi diverse peniţe, trebuie să le creăm şi apoi selectăm în cadrul DC. Zona client este suprafaţa în care un program poate desena orice. Afişarea în zona client se face cu ajutorul funcţiilor din GDI. Construirea unei aplicatii pentru exemplificarea folosirii penitelor, pensulelor si fonturilor Vom construi o aplicaţie cu arhitectura Document/View şi de tip SDI, în care vom exemplifica folosirea peniţelor, fonturilor şi a pensoanelor. Vom afişa text cu diverse fonturi, vom desena linii de diferite grosimi (cu peniţe diferite), vom desena dreptunghiuri sau zone închise umplute cu pensule diferite. WM_PAINT Un mesaj important pe care fiecare program Windows, cu o fereastră, trebuie să-l trateze este WM_PAINT. Windows trimite mesajul WM_PAINT ferestrei aplicaţiei când fereastra trebuie să se redeseneze. Mai multe evenimente fac ca Windows să trimită acest mesaj: Când utilizatorul lansează programul în execuţie pentru prima dată, fereastra aplicaţiei primeşte acest mesaj imediat după începerea execuţiei, pentru a afişa informaţiile necesare pentru început. 10

Cănd fereastra a fost redimensionată sau a fost descoperită (total sau parţial) de o altă fereastră. Partea din fereastră care a fost acoperită trebuie acum redesenată şi actualizată. Când un program îşi trimite indirect mesajul WM_PAINT prin invalidarea zonei client. Această funcţionalitate asigură faptul că o aplicaţie poate schimba conţinutul ferestrei aproape în orice moment doreşte. De exemplu, un procesor de texte poate invalida fereastra sa după ce utilizatorul a copiat tet din Clipboard. Macroul din harta de mesaje pentru WM_PAINT este ON_WM_PAINT(), iar funcţia ce corespunde tratării acestui mesaj este OnPaint(). Posibil cod în OnPaint(): void CView::OnPaint() // rutina standard de desenare CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc); CPaintDC este o clasă specială pentru gestionarea DC-ului folosit numai când se răspunde la mesajul WM_PAINT. Un obiect al clasei CPaintDC în afară de faptul că crează DC apelează şi funcţia BeginPaint() în constructorul clasei şi apelează funcţia EndPaint() în destructor. Constructorul CPaintDC ia un singur argument, care este un pointer la fereastra pentru care am creat DC. Pointer-ul this punctează la vederea curentă, deci putem să-l pasăm în constructor pentru a crea un DC pentru vederea curentă. OnPrepareDC() este o funcţie din CView care pregăteşte DC-ul pentru a fi folosit. OnDraw() afişează documentul în zona client. Schimbarea afisarii Logica aplicaţiei este următoarea: la apăsarea butonului stâng al mouse-ului se va afişa fie text cu un anumit font, fie o linie cu o anumită peniţă, fie un dreptunghi umplut cu o anumita pensula. Comutarea afişării se face cu ajutorul unei variabile m_display definită în clasa derivată din CView. Valoarea implicită a acestei variabile este Fonts şi se actualizează circular pe mesajul WM_LBUTTONDOWN, cu valorile Pens şi apoi Brushes, samd. În definiţia clasei: protected: enum Fonts, Pens, Brushes m_display; 11

În constructor: m_display = Fonts; iar desenarea in void CXView::OnDraw(CDC* pdc) CPaint1Doc* pdoc = GetDocument(); ASSERT_VALID(pDoc); switch (m_display) case Fonts: ShowFonts(pDC); break; case Pens: ShowPens(pDC); break; case Brushes: ShowBrushes(pDC); break; Vom scrie funcţiile ShowFonts(), ShowPens() şi ShowBrushes(). Vom adăuga funcţiile în definiţia clasei şi apoi vom scrie codul în implementarea clasei. void CXView::OnLButtonDown(UINT nflags, CPoint point) if (m_display == Fonts) m_display = Pens; else if (m_display == Pens) m_display = Brushes; else m_display = Fonts Invalidate(); // generează mesajul WM_PAINT CView::OnLButtonDown(nFlags, point); Folosirea fonturilor Trebuiesc cercetate fonturile care sunt instalate în sistem. Un font Windows este descris într-o structură LOGFONT. 12

LOGFONT Fields and Their Descriptions Field lfheight lfwidth lfescapement lforientation lfweight lfitalic lfunderline lfstrikeout lfcharset lfoutprecision lfclipprecision lfquality lfpitchandfamily lffacename Description Font height in logical units Font width in logical units Angle at which to draw the text Character tilt in tenths of a degree Font weight A nonzero value indicates italics A nonzero value indicates an underlined font A nonzero value indicates a strikethrough font Font character set How to match requested font to actual font How to clip characters that run over clip area Print quality of the font Pitch and font family Typeface name Unitatea logică (logical units) depinde de modul de mapare folosit. Modul de mapare implicit este MM_TEXT care înseamnă că o unitate logică este egală cu un pixel. Moduri de mapare Mode MM_HIENGLISH MM_HIMETRIC MM_ISOTROPIC MM_LOENGLISH MM_LOMETRIC MM_TEXT MM_TWIPS Unit 0.001 inch 0.01 millimeter Arbitrary 0.01 inch 0.1 millimeter Device pixel 1/1440 inch Escapement se referă la a scrie text de-a lungul unei linii ce face cu orizontala un anumit unghi. Orientation se referă la a scrie text de-a lungul unei linii (flat line). Ponderea (weight) fontului se referă la (thickness) subţirimea literelor. Au fost definite un număr de constante pentru a fi utilizate cu acest câmp: FW_DONTCARE, FW_THIN, FW_EXTRALIGHT, FW_ULTRALIGHT, FW_LIGHT, FW_NORMAL, FW_REGULAR, FW_MEDIUM, FW_SEMIBOLD, FW_DEMIBOLD, FW_BOLD, FW_EXTRABOLD, FW_ULTRABOLD, FW_BLACK, şi FW_HEAVY. Nu toate fonturile sunt disponibile în toate ponderile. Sunt disponibile patru mulţimi de caractere (ANSI_CHARSET, OEM_CHARSET, SYMBOL_CHARSET, şi UNICODE_CHARSET), dar pentru a scrie text în engleză vom folosi totdeauna ANSI_CHARSET. 13

Ultimul câmp din structură reprezintă numele fontului (de ex. Helvetica, Times New Roman, etc.) void CXView::ShowFonts(CDC * pdc) // Initializare structura LOGFONT pentru fonturi LOGFONT logfont; logfont.lfheight = 8; logfont.lfwidth = 0; logfont.lfescapement = 0; logfont.lforientation = 0; logfont.lfweight = FW_NORMAL; logfont.lfitalic = 0; logfont.lfunderline = 0; logfont.lfstrikeout = 0; logfont.lfcharset = ANSI_CHARSET; logfont.lfoutprecision = OUT_DEFAULT_PRECIS; logfont.lfclipprecision = CLIP_DEFAULT_PRECIS; logfont.lfquality = PROOF_QUALITY; logfont.lfpitchandfamily = VARIABLE_PITCH FF_ROMAN; strcpy(logfont.lffacename, "Times New Roman"); // Initializare pozitie text in fereastra. UINT position = 0; // Creaza si afiseaza 8 exemple de fonturi. for (UINT x=0; x<8; ++x) // Setam inaltimea noului font. logfont.lfheight = 16 + (x * 8); // Cream un nou font si-l selectam intr-un // context de dispozitiv. CFont font; font.createfontindirect(&logfont); CFont* oldfont = pdc->selectobject(&font); // Tiparim textul cu noul font. position += logfont.lfheight; pdc->textout(20, position, "Exemplu de font."); // Restauram vechiul font in DC. pdc->selectobject(oldfont); 14

Explicaţii la acest cod. Se va rula aplicaţia în acest moment. Se va constata că nu pot fi afişate toate informaţiile în zona client. Marire si pozitionare fereastra Informaţiile nu pot fi afişate în zona client la o rezolutie a ecranului de 800*600. Acest lucru se corectează prin mărirea ferestrei, care se face în funcţia PreCreateWindow() din CMainFrame. Această funcţie este apelată înainte ca fereastra să fie creată. PreCreateWindow() are un singur parametru, o referinţă la o structură CREATESTRUCT. Această structură conţine informaţii despre fereastra care va fi creată. CREATESTRUCT Structure typedef struct tagcreatestruct LPVOID lpcreateparams; HANDLE hinstance; HMENU hmenu; HWND hwndparent; int cy; int cx; int y; int x; LONG style; LPCSTR lpszname; LPCSTR lpszclass; DWORD dwexstyle; CREATESTRUCT; cx şi cy menţin lăţimea şi înălţimea ferestrei, iar x şi y poziţia acesteia. Se inhibă redimensionarea ferestrei (style). BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) cs.cx = 440; cs.cy = 480; cs.style &= ~WS_SIZEBOX; if(!cframewnd::precreatewindow(cs) ) return FALSE; return TRUE; Majoritatea funcţiilor rescrise şi apelate de cadrul de lucru trebuie să apeleze în final versiunea din clasa de bază. 15

Folosirea penitelor Vezi clasa CPen. void CXView::ShowPens(CDC * pdc) // Initializam pozitia liniei UINT position = 10; // Desenam 16 linii in fereastra for (UINT x=0; x<16; ++x) // Cream o noua penita si o // selctam in contextul de dispozitiv CPen pen(ps_solid, x*2+1, RGB(0, 0, 255)); CPen* oldpen = pdc->selectobject(&pen); // Desenam o linie cu noua penita position += x * 2 + 10; pdc->moveto(20, position); pdc->lineto(400, position); // Repunem vechea penita in DC pdc->selectobject(oldpen); Explicaţii la acest cod. Stiluri penita Style PS_DASH PS_DASHDOT PS_DASHDOTDOT PS_DOT PS_INSIDEFRAME PS_NULL PS_SOLID Description A pen that draws dashed lines A pen that draws dash-dot patterned lines A pen that draws dash-dot-dot patterned lines A pen that draws dotted lines A pen that's used with shapes, in which the line's thickness must not extend outside the shape's frame A pen that draws invisible lines A pen that draws solid lines Folosirea pensulelor Cu ajutorul unei pensule desenam interiorul unei figuri de pe ecra. Putem crea pensule solide, pensule cu un anumit şablon şi chiar pensule din bitmap-uri. 16

void CXView::ShowBrushes(CDC * pdc) // Initializam dreptunghiul de pozitionare UINT position = 0; // Selectam penita ce va fi folosita pentru // a desena conturul dreptunghiului CPen pen(ps_solid, 5, RGB(255, 0, 0)); CPen* oldpen = pdc->selectobject(&pen); // Desenam 7 dreptunghiuri. for (UINT x=0; x<7; ++x) CBrush* brush; // Cream o pensula if (x == 6) brush = new CBrush(RGB(0,255,0)); else brush = new CBrush(x, RGB(0,160,0)); // Selectam noua pensula in DC CBrush* oldbrush = pdc->selectobject(brush); // Desenam dreptunghiul position += 50; pdc->rectangle(20, position, 400, position + 40); noua // Restauram vechea pensula si o stergem pe cea pdc->selectobject(oldbrush); delete brush; // Restauram vechea penita pdc->selectobject(oldpen); Stiluri pentru pensoane: HS_HORIZONTAL--Horizontal HS_VERTICAL--Vertical HS_CROSS--Horizontal and vertical HS_FDIAGONAL--Forward diagonal HS_BDIAGONAL--Backward diagonal 17

HS_DIAGCROSS--Diagonal in both directions Observaţie: Trebuie să apelăm Invalidate() în OnLButtonDown(). Invalidate() are un singur argument (Boolean) cu valoarea implicită TRUE. Acest argument are ca efect ştergerea sau nu a background-ului. Dacă valoarea este FALSE, backgroundul nu va fi şters. Ferestre cu bare de navigare (scrolling Windows ferestre cu derulare) Ferestrele ne permit de a partiţiona ecranul între diverse aplicaţii şi documente. Dacă folosim MFC şi derivăm clasa de vizualizare din CScrollView, atunci fereastra are posibilităţi de derulare. Indicatii de construire a unei aplicatii cu ferestre cu derulare Vom construi o aplicaţie pentru a exemplifica posibilităţile de derulare. În cadrul aplicaţiei iniţial se vor afişa 5 linii de text, iar pe mesajul WM_LBUTTONDOWN vom adăuga de fiecare dată încă 5 linii te text, astfel că la un moment dat textul nu va mai încăpea în fereastră. Numărul liniilor de text care sunt afişate în zona client le vom gestiona cu ajutorul unei variabile din clasa derivata din CDocument public: int m_numlines; pe care o iniţializăm în constructorul clasei: m_numlines = 5; Această variabilă o putem serializa: void CScrollDoc::Serialize(CArchive& ar) if (ar.isstoring()) ar << m_numlines; else ar >> m_numlines; 18

În vizualizare: void CMyScrollView::OnDraw(CDC* pdc) CScrollDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // obtinem numarul de linii din document int numlines = pdoc->m_numlines; // Initializam o structura LOGFONT pentru fonturi. LOGFONT logfont; logfont.lfheight = 24; logfont.lfwidth = 0; logfont.lfescapement = 0; logfont.lforientation = 0; logfont.lfweight = FW_NORMAL; logfont.lfitalic = 0; logfont.lfunderline = 0; logfont.lfstrikeout = 0; logfont.lfcharset = ANSI_CHARSET; logfont.lfoutprecision = OUT_DEFAULT_PRECIS; logfont.lfclipprecision = CLIP_DEFAULT_PRECIS; logfont.lfquality = PROOF_QUALITY; logfont.lfpitchandfamily = VARIABLE_PITCH FF_ROMAN; strcpy(logfont.lffacename, "Times New Roman"); // Cream un nou font si il selectam in DC CFont* font = new CFont(); font->createfontindirect(&logfont); CFont* oldfont = pdc->selectobject(font); // Initializam pozitia textului in fereastra UINT position = 0; // Cream si afisam 8 linii de text for (int x=0; x<numlines; ++x) // Cream sirul de caractere ce va fi afisat char s[25]; wsprintf(s, "Linia numarul: #%d", x+1); // Tiparim textul cu noul font pdc->textout(20, position, s); // Trecem pe linia urmatoare position += logfont.lfheight; // Restauram vechiul font in DC si stergem fontul creat de program pdc->selectobject(oldfont); delete font; 19

Explicaţie cod. Se va rula aplicaţia. Modificarea codului pentru a creste numarul de linii afisate pe ecran Pe mesajul WM_LBUTTONDOWN void CMyScrollView::OnLButtonDown(UINT nflags, CPoint point) CScrollDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // Marim numarul liniilor de afisat //(cu 5 la fiecare clic stanga mouse) pdoc->m_numlines += 5; // Redesenam fereastra Invalidate(); CScrollView::OnLButtonDown(nFlags, point); Micsorarea numarului de linii void CMyScrollView::OnRButtonDown(UINT nflags, CPoint point) CScrollDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // Micsoram numarul liniilor de afisat // (cu 5 la fiecare clic dreapa mouse) pdoc->m_numlines -= 5; if (pdoc->m_numlines < 0) pdoc->m_numlines = 0; // Redesenam fereastra. Invalidate(); CScrollView::OnRButtonDown(nFlags, point); Dacă rulăm aplicaţia vom observa că barele de derulare nu apar. Trebuie modificată funcţia OnDraw(). Linii de cod ce se vor adauga la OnDraw() // Calculam marimea documentului CSize docsize(100, numlines*logfont.lfheight); // Calculam marimea paginii CRect rect; GetClientRect(&rect); CSize pagesize(rect.right, rect.bottom); 20

// Calculam marimea liniei CSize linesize(0, logfont.lfheight); // Ajustam barele de navigare SetScrollSizes(MM_TEXT, docsize, pagesize, linesize); 21