Sunteți pe pagina 1din 54

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 1.
SISTEMUL DE INTRARI/IESIRI DE BAZA DIN C++ n C++ ntre intrrile i ieirile fizice se interpun zone tampon organizate sub forma unor clase ierarhizate, aceste zone tampon se numesc streamuri. Spre deosebire de zonele tampon din C care erau doar nite locaii de memorie asupra crora acionau o serie de funcii n mod explicit sau implicit (printf, scanf) n C++ acestea au devenit clase, avnd asociate i doi operatori unul de inserie (<<) i altul de extracie (>>) care pot fi suprancrcai. n principiu sunt definite 4 streamuri standard: cin - pentru intrri standard de la Tastatur; cout pentru ieiri standard spre display (sau fereastr); cerr pentru ieiri standard de eroare spre display; clog ieirile de eroare sunt pstrate trec printr-o memorie tampon nainte de ajunge la display; n continuare se vor expune funcionarea streamurilor cin i cout. Biblioteca n care sunt descrise arhetipurile acestor streamuri i care trebuie ncarcat cu #include este <iostream.h>. Avantajul utilizrii streamurilor este folosirea direct fr specificri sau configurri speciale lundu-se n acest caz setrile implicite sau setri fcute anterior. Dei atunci cnd se va dori o anumit formatare se va apela la funcii i constante suplimentare spre deosebire de printf i scanf aceste formatari se vor pstra, astfel dac se dorete ca afirile de la un punct la alt punct al programului s se fac cu aceeai formatare se va specifica formatarea o singura data, apoi aceasta pstrndu-se. Pentru a afia nite variabile,constante, iruri de caractere pe ecran vom scrie: cout<<v1<<v2<<k1<<abcdefg<<a<<*; Se vor afia una dup alta fr spaii ntre ele valoare lui v1, a lui v2 a constantei k1, irul de caractere dintre ghilimele, caracterul a i *. Pentru a citi o variabil sau un ir de caractere vom scrie: int a; char s[100]; cin>>a; cin>>s; sau cin>>a>>s; Se observ c sgeile indic ntotdeauna sensul de deplasare a informaiei la cout toate informaiile se deplaseaz dinspre variabile spre stream, pe cnd la cin dinspre stream spre variabile.

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Exerciiu 1: Citii trei valori float, calculai media lor i afiai-o. Formatarea streamurilor Formatarea afirilor i intrrilor se poate face cu o serie de indicatori de format i o serie de funcii prin care se activeaz aceti indicatori. Indicatorii de format sunt efectiv valori ntregi pe 16 bii. Aceste valori n format binar au doar un singur bit setat, permind astfel implementarea a 16 indicatori maxim pe acest principiu. Ca tip de date aceti indicatori sunt definii ca enumerare. Acetia sunt definii astfel: Enum{ skipws=0x0001, left=0x0002, right=0x0004, internal=0x0008, dec=0x0010, oct=0x0020, hex=0x0040,showbase=0x0080, showpoint=0x0100, uppercase=0x0200, showpos=0x0400, scientific=0x800,fixed=0x1000,unitbuf=0x2000 }; Pentru setarea acestor indicatori se folosete funcia membru setf(indicator), Pentru resetarea lor se folosete funcia unsetf(indicator). Pentru a seta indicatorul hex scriem: stream.setf (ios::hex); unde stream poate fi cin sau cout. Pentru a seta mai muli indicatori vom folosi urmtoare secven de cod: stream.setf(ios::ind1| ios::ind2 | ios::ind3 | . ios ::indn) ; Pentru a reseta indicatorii de format ai unui stream folosim aceleai expresii dar n loc de setf vom scrie unsetf. Semnificaiile indicatorilor de format: - skipws la citirea unui ir de caractere nu ia n considerare spaiile goale (spaii i tabulatori); Exemplu: char s[100]; cin.setf(ios::skipws); cin>>s; cout<<s; left alineaz afiarea pe ecran la stnga; ( abc______) right alineaz afiarea pe ecran la dreapta;(______abc) internal alineaz semnul valorii la stnga;(-_____123) dec specific c streamul va lucra cu valori n baza 10; oct specific c streamul va lucra cu valori n baza 8; hex specific c streamul va lucra cu valori n baza 16; showbase specific c se va afia baza de numeraie n care se lucreaz ( 0__ pentru octal, 0x__ pentru hexazecimal, fr nici o specificaie pentru zecimal);

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

showpoint arat punctul zecimal pentru valori reale chiar i atunci cnd nu au zecimale diferite de zero (1234.0000) uppercase arat notaia bazelor cu liter mare i pentru baza 16 toate cifrele literare (a,b,c,d,e,f) vor fi scrise cu liter mare;(FFB9) showpos dispune n faa valorilor pozitive semnul +. ( +1234); scientific valorile reale vor fi afiate n notaie tiinific (1.234e+03); fixed valorile reale vor fi afiate n notaie cu virgul, opiune ce este implicit; unitbuf se golese memoria tampon asociat streamurilor dup fiecare operaie de ieire;

Exerciiu 2. S se citeasc un numr ntreg n baza 16 i s se afieze valoare citit n baza 8. S se active afiarea simbolizrii bazei. Exerciiu 3. S se citeasc o valoare float i s se afieze fr punctul zecimal.(dac valoarea nu are zecimale), altdat s se afieze n notaie tiinific, i mai apoi n notaie fix. Alte funcii membre ale streamurilor: flags(), width(), precision(), fill() Pentru a citi sau a scrie valorile tuturor indicatorilor de formatare se va folosi funcia flags(). Exemplu: long a; a=flags(); // am citit toate valorile flags(a); // am suprascris toate valorile Pentru a specifica lungimea minima a spaiului(cmpului) de afiare a unei variabile, ir de caractere sau constante se folosete funcia width() avnd prototipul: int width(int dimensiune_camp); Pentru a specifica precizia(numrul de zecimale) cu care va fi afiat un numr real se fa folosi funcia membru precision() avnd prototipul: int precision(int nr_de_zecimal); Pentru a specifica caracterul cu care se umple spaiile libere ale unui cmp cnd informaia efectiv afiat ocup mai puin dect lrgimea cmpului se folosete fill() avnd prototipul: char fill(char noul_caracter_de_umplere); // funcia va returna caracterul de umplere anterior Exemplu: #include <iostream.h> #include <iomanip.h> void main() { cout.width(10); //latimea cmpului de 10 cout <<"salut" << "\n"; cout.width(10); cout.fill('_'); cout << "salut" << "\n";

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

// utilizare manipulatori cout<<setw(15)<<setfill('*')<<"Salut"<<hex<<" "<<24<<endl; cout.setf(ios :: left); cout.width(10); cout << "salut" << "\n"; cout <<123.234567 << "\n"; cout.width (10); cout.precision(8); cout << 123.234567 << "\n"; } Exerciiu 4. S se afieze pe cte un rnd valoare radicalului primelor 15 numere ncepnd cu 2. Valoarea va fi afiat cu 7 zecimale. Pe prima coloan se va afia numrul, pe cea de-a doua radicalul su. Fiecare cmp va avea o lrgime de 20 de caractere iar valorile vor fi alineate la dreapta.(Ca n figura de mai jos.)(pentru radical se va include biblioteca math.h i din aceast bibliotec se va folosi funcia sqrt(), pentru linie nou se va folosi caracterul `\n`) Este setarea fcut cu funcia width() permanent?

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 2.
SISTEMUL DE INTRARI/IESIRI DE BAZA DIN C++ Utilizare manipulatori Utilizarea manipulatorilor pentru formatarea ieirilor Manipulatorii sunt o serie funcii speciale declarate n biblioteca IOMANIP.H. Acetia sunt : - dec, oct, hex pentru a specifica baza de numeraie a intrrilor i ieirilor; (I/O) - setbase(int baza) stabilete baza valorilor numerice ce intr sau ies din stream; (O) - endl pentru un caracter de linie nou care se terge (echivalentul unui Enter din tastatur); (O) - ends scrie n stream un caracter null (0x00 sau `\0`);(O) - ws pentru streamuri de intrare emite spaiile libere introduse nainte de valoarea efectiv; (I) - flush golete un stream; (O) - resetiosflags(long f) dezactiveaz indicatorii specificai n f; (I/O) - setiosflags(long f) activeaz indicatorii specificai f; (I/O) - setprecision(int precizie) stabilete numrul de zecimale al valorilor cu virgul ; (O) - setfill(int ch) stabilete caracterul de umplere; (O) - setw(int w) stabilete lrgimea cmpului n care se va afia o valoare sau ir de caractere; (O) Pentru a folosi un manipulator vom folosi expresia: cout<<manip1<<v1<<<<manip2<<manip3<<vk; cin>>manip1>>v1>>manip2>>; Exemplu n cazul stabilirii cmpului de afiare de 10 avnd caracterul de umplere * putem scrie: cout.width(10) ; cout. fill( *) ; cout<<Exemplu<<endl; sau cout<<setw(10)<<setfill(*)<<Exemplu<<endl; cu condiia includerii bibliotecii iomanip.h. Exerciiul 1. S se afieze pe cte un rnd,n cmpuri de 20 de caractere, alineate la dreapta, valoarea lui radical din 2, mai nti cu o zecimal i apoi crescnd cu unu numrul de zecimale. Vor fi afiate astfel zece rnduri. Se va da prioritate folosirii manipulatorilor mai sus prezentai.

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Rezultatul programului va fi cel din figura de mai jos.

Definirea propriilor manipulatori Se pot crea manipulatori proprii care sa acioneze asupra unor streamuri. Pentru a crea un manipulator se poate utiliza aceast structur general valabil: Pentru manipulatori folosii mpreun cu cout: ostream& nume_manipulator_out (ostream& cout) { // se fac operatii cu streamul cout<<<<; cout.setf() ; cout.precision() ; cout<<endl<<ends; // aceste operatii sunt date ca exemplu putandu-se alege oricare // combinatie ce este utila return cout ; //aceasta comanda este absolut necesara // este ultima comanda din corpul functiei de definire } Pentru manipulatori folosii mpreun cu cin: istream& nume_manipulator_in (istream& cin) { // se fac operatii cu streamul cin>>>>; cin.setf() ; cin.precision() ; cin>>ws; // aceste operatii sunt date ca exemplu putandu-se alege oricare // combinatie ce este utila return cin ; //aceasta comanda este absolut necesara // este ultima comanda din corpul functiei de definire

} Pentru a folosi aceti manipulatori se va folosi secvena: cout<<<<nume_manipulator_out<<; cin<<<<nume_manipulator_in<<;

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Exerciiu 2 Creai un manipulator de ieire cu numele rnd_nou, care ataat unui stream cout sa fac acelai lucru ca manipulatorul endl. Sau un manipulator numit da_un_bip care ataat lui cout s scoat un sunet scurt de avertizare. (Se va folosi caracterul special \a). Exerciiu 3 Creai un manipulator de intrare cu numele cere_parola, care ataat unui stream cin s cear introducerea unui ir de caractere ce semnific parola. Dac parola este greit se va emite un sunet de avertizare folosindu-se manipulatorul da_un_bip creat mai nainte i se va repeta secvena de solicitare a parolei. Altfel se va confirma c parola este corect i se va ncheia programul. (Pentru compararea irului introdus cu parola dorit se va folosi funcia strcmp(sir1,sir2) din biblioteca string.h).

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 3.
Crearea claselor i lucrul cu obiecte n C++ Organizarea programelor sub forma unor nlnuiri de clase reprezint urmtorul pas dup ce s-a deprins lucrul cu funciile i construcia structurilor de date. Pentru cine este obinuit cu acestea, definirea i lucrul cu clase li se va prea ca i cum ar avea o structur de date (struct) creia i s-au asociat o serie de funcii. Dar asemnrile din pcate se opresc aici, dei imaginea simplificatoare este n mare parte valabil. Odat cu avantajele utilizrii claselor apar i unele restricii. Funciile definite n clas (care poart numele de funcii membre ale clasei) au acces preferenial asupra datelor definite n interiorul clasei i uneori pot fi chiar singurele funcii ce au acces la aceste date. Pe de alt parte datele din clas sunt de cele mai multe ori inaccesibile din afar, doar funciile membre le pot citi i modifica. Important de reinut sunt avantajele pe care le aduce folosirea claselor : ncapsularea, Polimorfismul i Motenirea. ncapsularea nseamn c datele clasei nu sunt accesibile din afar ci mai ntotdeauna sunt accesate prin medierea funciilor membre (nu nseamn c nu se pot accesa datele ci doar c clasele au fost concepute s funcioneze astfel). Polimorfismul nseamn c putem defini o funcie de mai multe ori, astfel nct s accepte diferite combinaii de parametri i s realizeze aceeai sarcin folosind parametri diferii dar specificai (funcia va avea acelai nume dar va diferi numrul i tipul parametrilor la fiecare declarare). Motenirea presupune c caracteristicile unei clase datele i funciile sunt puse la dispoziia sau mai degrab devin baza pe care se construiete alt clas. Astfel clasa nou creat clasa derivat va moteni elementele clasei de baz. Se pot crea clase prin moteniri succesive, sau prin motenirea mai multor clase deodat. Clasa derivat va putea defini noi funcii i date n completarea celor motenite. Definirea unei clase se face astfel: class nume_clasa{ tip1 data1; tip2 data1[10]; tipn datan; specificator1: nume_clasa(); ~nume_clasa(); tip1 functie1(); specificator2: tip2 functie2(); tipn functien(): } [obiect1],[obiect2];

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Aceasta este structura general de definire a unei clase. Se observ cuvntul cheie class de la nceput, acesta se va regsi n toate definiiile de clase. Specificator1n sunt specificatori de acces care stabilesc accesul la membrii clasei cei care se gsesc dup el fiind afectai, pn ce apare un nou specificator de acces. nume_clasa() este o funcie constructor a clasei, se apeleaz automat cnd se declar un obiect de clasa respectiv. ~nume_clasa() este o funcie destructor a clasei, se apeleaz cnd s-a terminat lucrul cu obiectul definit, pentru a elibera memoria. Tipk functiek() este o funcie membr a clasei. Dup ce s-a definit clasa trebuie definite i funciile membre. n general pentru definirea unei funcii membre a clasei, n afara acesteia se folosete operatorul de specificare a domeniului (sau operator de rezoluie) :: . Exemplu: tipk nume_clasa::functiek() { // scriem continutul functiei return tipk; } n definiia clasei observm c opional se pot defini variabile de tipul clasei numite obiecte. Pentru a accesa membrii clasei atunci cnd avem declarat un obiect vom folosi operatorul de selecie . (punct) atunci cnd lucrm cu obiectul sau operatorul de selecie indirect -> (minus, mai mare) atunci cnd lucrm cu pointer spre obiect. Astfel: nume_clasa obiect1,obiect2,* obiect3; // definire obiecte obiect1.functiek(); obiect2.functiek(); obiect3->functiek(); // avnd un pointer spre un obiect Specificatorii de acces tipici sunt: private (setat implicit pentru toi membrii unei clase); public; protected. Primii doi n special public sunt cei mai utilizai. Private interzice accesul oricrui nemembru al clasei. Public permite accesul oricui la membrii clasei. Protected specific c membrii declarai protected n clasa de baz vor putea fi accesai n cazul unei moteniri fr specificatori de ctre clasa derivat. Pentru a avea acces fr protected la membrii clasei de baz la motenire clasa tat va fi motenit de clasa fiu n mod public. Pentru a specifica c o nou clas motenete pe altele vom folosi structura: class clasa_nou(derivat):[specificator1] clasa_de_baz1[,[specificator 2] clasa_de_baz2,] { //noi elemente specifice clasa_derivat }; Astfel o clasa_derivat poate moteni una sau mai multe clasa_de_baz, motenirea fiind filtrat prin specificatorii de acces ce preced clasa_de_baz motenit. (Este bine ca aceti specificatori s fie public - pentru ca accesul clasei derivate (fiu) s fie permis la toi membrii clasei de baz (tat)

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

indiferent de specificatorii din aceasta clasa de_baz (tata), aceasta deoarece specificatorul implicit este private n cazul unei moteniri fr precizarea specificatorului). La apelarea unei funcii membre, aceasta este informat asupra identitii obiectului asupra cruia va aciona prin transferul unui parametru implicit care este adresa obiectului. De exemplu, n cazul apelului: ob.verificare(i); funcia verificare() primete i adresa obiectului ob, n afar de valoarea i. De asemenea exist cazuri n care adresa obiectului este necesar s fie utilizat n definiia funciei. Acest lucru este realizat n C++ de cuvntul cheie this, asociat unui pointer ctre obiectul pentru care s-a apelat funcia. Cuvntul this are sens i poate apare numai n definiia unor funcii membre. Pentru a ne referi la un membru al clasei din interiorul unei funcii membru vom folosi apelare: this->membru=. Exerciiul 1. Realizati un program utiliznd clase de obiecte, ce permite calculul salariului net a unui angajat. Se va defini o clas salariu avnd salariu de baz, numrul de ore suplimentare lucrate si tariful orar pentru orele suplimentare. Clasa va avea o funcie de introducere date i funcii de calcul i afiare salariu net. Salariul net va fi 70% din salariul brut ce se va calcula ca suma dintre salariul de baz i valoarea orelor suplimentare. Exerciiu 2. Definii o clasa cu numele persoana, cu urmtoarele date: nume, prenume, adresa (stradanr),vrst, cnp. Definii o funcie constructor i una destructor. Definii funciile introduce_nume, introduce_adresa, introduce_varsta , introduce_cnp care s citeasc de la tastatura datele respective. Definii alte funcii care sa afieze aceste date, separat pentru fiecare dat n parte i toate la un loc. Nu folosii deocamdat nici un specificator de acces. ncercai s afisai numele unei persoane prin accesarea direct a datei respective. Se poate?. Ce trebuie schimbat dac nu?. La fel ncercai s folosii o funcie membr a clasei fr a avea un specificator de acces n clas. Cum trebuie modificat programul pentru ca accesul la datele membre s fie interzis i accesul la funcii membre permis? Exerciiul 3. Definii o clas angajat prin motenirea (derivarea) clasei persoana, care s aib suplimentar urmtoarele date: nume_firma, salariu_net, data_angajarii (de tip char n format zz-ll-aaaa). Creai i pentru aceasta clas funcii de citire a datelor noi, de afiare a datelor noi, de transfer de date. Facei motenirea fr precizarea unui specificator de acces. V este permis accesul direct la numele persoanei din clasa angajat ? Ce trebuie modificat ? Scriei o funcie extern claselor pentru a afia informaii despre angajat. Avei acces la membrii clasei?

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 4.

Folosirea funciilor prietene. Avnd declarat deja o funcie, pentru a permite accesul la membrii unei clase o vom declara n interiorul clasei ca fiind funcie prieten cu specificatorul friend. Acesta va fi folosit astfel: class nume_clasa{ // declaram date membre // declaram functii membre friend tip_returnat functie_prietena(); // functia a devenit prietena a //clasei }; //se observa ca definitia functiei nu se schimba deloc tip_returnat functie_prietena() { }; Astfel indiferent de ce specificatori de acces au membrii clasei, funcia prieten va avea acces nengrdit la toi membrii clasei. Se pot defini i clase prietene unei clase nu numai funcii prietene, cam n acelai mod. class nume_clasa{ // declaratii member friend class nume_clasa_prietena; } Astfel nume_clasa_prietena are acces la toi membrii nume_clasa, dar nume_clasa nu are acces neaprat la toi membrii clasei nume_clasa_prietena. Deci reciproca nu este valabil.(dect specificat n mod expres) Cnd lucrm cu pointeri la obiect, iar obiectului respectiv nu i s-a alocat memorie, va trebui ca nainte de folosire s folosim operatorul de alocare new, iar cnd nu mai lucrm cu obiectul operatorul delete. Ei au urmtoarea adresare: nume_obiect=new nume_clasa; delete nume_obiect; Putem folosi aceti operatori i cu alte tipuri dect clase. n loc de nume_obiect avnd nume_variabil i n loc de nume_clasa numele tipului.

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Cnd avem definii constructori apelarea acestora se va face n momentul alocrii, respectiv destructori la apelul operatorului delete. Pn acum nu s-a pus problema constructorilor i destructorilor cu parametri. Acetia sunt declarai i definii n modul n care sunt definite funciile desigur fr a returna un tip. n schimb la declararea obiectelor va trebui specificat ntre paranteze dup numele obiectului fiecare parametru specificat n prototip. nume_clasa obiect(p1,p2,p3); Pentru obiecte alocate dinamic : nume_obiect = new nume_clasa(p1,p2,p3); Exerciiu 1. Modificai programul care conine clasele cu numele persoana (cu urmtoarele date: nume, adresa, cnp) i angajat (nume_firma, data_angajarii) astfel nct obiectele definite s fie alocate dinamic. De exemplu se definesc char*nume, *adresa,* CNP; Pentru introducerea datelor privind persoana se va realiza o funcie constructor de iniializare avnd prototipul: persoana(char* n="", char *a="", char *c=""); Aceast funcie va fi definit n afara clasei astfel: persoana::persoana(char* n, char *a, char *c) {nume=new char[strlen(n)+1]; strcpy(nume,n); adresa=new char[strlen(a)+1]; strcpy(adresa,a); CNP=new char[strlen(c)+1]; strcpy(CNP,c); } Functia destructor persoana va fi definit astfel: persoana::~persoana() { delete[] nume; delete [] adresa; delete[] CNP; } Apelul constructorilor de iniializare se va face astfel: persoana a=persoana("NumeXX", "Calea Marasesti", "157"); angajat b = angajat("Universitatea din Bacau", "24.03.2009"); Pentru a ne referi strict la o instan a unui membru al clasei, adic cea declarat i folosit ntrun obiect anume, pentru a avea acces la datele i funciile din memoria alocat acestuia vom folosi

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

pointerul this (trad. acesta). Acesta returneaz adresa obiectului. Pentru a ne referi la un membru al clasei din interiorul unei funcii membru vom folosi apelare: this->membru=; this->functie_membru(); =this->membru; Un alt element al programrii pe obiecte este utilizarea funciilor virtuale. Declararea virtual a unei funcii are utilitate n procesul de motenire (sau derivare). Astfel o funcie declarat virtual n clasa de baz este motenit ca virtual n clasele derivate. Cu toate c avem funcia definit n clasa de baz dac ea este redefinit n clasa derivat aceast funcie va face cnd va fi apelat ceea ce s-a precizat n clasa derivat i nu ceea ce fcea n clasa de baz. Deci faptul c o funcie este virtual permite suprascrierea ei n toate clasele ce vor rezulta prin derivarea clasei de baz (prin utilizarea aceluiai nume). Exemplu: class animal_vertebrat{public: //caracteristici generale specifice oricarui animal vertebrat virtual void mod_de_deplasare() {cout<<Inoata!<<endl;} }; class peste:public animal_vertebrat{ //caracterisitici specifice // nu redeclaram functia pt ca este valabila afirmatia Inoata! }; class patruped:public animal_vertebrat{ public: void mod_de_deplasare(){cout<<Merge! <<endl;;} }; class pasare: public animal_vertebrat{ public: void mod_de_deplasare(){cout<<Zboara! <<endl;;} }; void main() { animal_vertebrat somon; peste rechin; patruped elefant; pasare vultur; cout<<"somon - >"; somon.mod_de_deplasare(); cout<<"elefant - > "; elefant.mod_de_deplasare(); cout<<"rechin - > "; rechin.mod_de_deplasare(); cout<<"vultur - > ";

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

vultur.mod_de_deplasare();} Programul va afia: somon -> Inoata! etc. Se observ c-n toate clasele derivate n afar de peste funcia mod_de_deplasare() a fost suprascris. Exerciiu 2. Creai modificnd exemplul de mai sus o clas reptila derivat din pasare, iar n aceast clas modificai funcia virtual astfel nct s afieze merge si inoata. Declarai un obiect de tip reptila i verificai dac funcia virtual a fost suprascris i programul funcioneaz corect. De remarcat c n toate celelalte clase derivate funcia declarat virtual n clasa de baz nu mai trebuie precedat de virtual, acest atribut fiind subneles. Obs. Se pare c programul nu funcioneaz. Problema apare pentru c la suprascrierea funciilor virtuale se suprascrie i specificatorul de acces, i pentru c nu este precizat este luat implicit private. Asta nseamn c accesul la funcia membru mod_de_deplasare nu v este permis. Rezolvai problema. Dup ce ai rezolvat problema adugai un constructor clasei de baz i prin acesta transmitei un ir de caractere cu numele efectiv al speciei animalului pe care l pstrai ntr-un ir de caractere. Pentru copierea irului de caractere n alt ir folosii funcia strcpy(dest,sursa) din biblioteca string.h. Funciile constructor i destructor pentru clasa vertebrat vor fi: animal_vertebrat(char*n="") {nume=new char[strlen(n)+1]; strcpy(nume,n); } ~animal_vertebrat() {delete nume;} Aceste nume l vei afia nainte de a spune cum se deplaseaz animalul fcnd o modificare n funciile virtuale din fiecare clas preferabil la aceeai apelare a cout. Vei constata erori deoarece constructorii nu se motenesc n mod implicit. Chiar i derivarea trebuie din nou specificat pentru constructori n mod obligatoriu.(sintaxa este nume_clasa(char *numeanimal):clasa_baza(numeanimal){}; Funciile constructor i destructor n acest caz vor fi: peste(char*n=""):animal_v(n){}; ~peste(){}; Iniializare obiectului rechin de tip peste se va face astfel: peste rechin=peste("rechin"); Redefinirea se va face pentru fiecare clas derivat. Trebuie reinut c la rularea unui program mai nti sunt apelai n ordinea derivrii mai nti constructorul clasei de baza, apoi cei ai clasei derivate pe urm cei ai clasei derivate din aceasta .a.m.d., ultimul apelat fiind cel al clasei din care face parte obiectul. Pentru destructori aceeai regul numai c ordinea este inversat.

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 5.
Visual C++6.0 MFC Desenarea i afiarea imaginilor Utilizarea documentelor, a reprezentrilor i a cadrelor Pentru programatorul n VisualC++, biblioteca MFC ofer un sprijin substanial la generarea unei noi aplicaii prin intermediul AppWizard, care poate s creeze automat un meniu, o bar de instrumente, o bar de stare i alte componente, permind apoi personalizarea uoar a fiecrui element. Clasele create cu AppWizard lucreaz mpreun pentru a forma o structur omogen cunoscut sub numele de arhitectura Document/View. Conceptul fundamental al arhitecturii Document/View l reprezint separarea datelor propriuzise de reprezentarea a ceea ce datele semnific pentru utilizator. Aceasta se realizeaz stocnd datele ntr-o clas (clasa document) i informaiile privind reprezentarea ntr-o alt clas (clasa vizualizare). Exist dou categorii de aplicaii Document/View: SDI (Single Document Interface) i MDI (Multiple Document Interface). Exerciiu 1. S se creeze o aplicaie de tip SDI cu AppWizard . Aplicaia pe care o vei dezvolta va afia un teanc de monede. Opiunile de meniu vor permite adugarea sau nlturarea unei monede din teanc. Datele, care reprezint de fapt numrul de monede, sunt reinute n clasa document, fiind accesate de clasa vizualizare n scopul afirii teancului sau de clasa cadru pentru actualizare. Dei este un exemplu simplu, el ofer o imagine asupra scopului fundamental al arhitecturii Document/View, i anume ncapsularea datelor. Prin ncapsulare, datele sunt stocate exclusiv n clasa document, fiind oferite funcii de acces care s permit clasei vizualizare sau clasei cadru s prezinte informaiile ctre utilizator, respectiv s permit actualizarea acestor informaii. Folosind opiunea AddMemberVariabile adugai o variabil protected cu numele NrMonede clasei document a proiectului. Aceast variabil va iniializat n funcia constructor a clasei document cu valoarea 1. O variabil protejat nu poate fi modificat dect prin intermediul funciilor membru ale clasei din care face parte sau ale unei clase derivate. Prevenind alterarea datelor documentului de ctre oricare alt clas, rmne un singur punct de modificare a unei variabile. Pentru a permite accesul la datele membre, clasa document trebuie s ofere funcii de acces sau de modificare a variabilelor membre. Folosind opiunea AddMemberFunction adugai trei metode clasei document: - o metod int GetNr() care s returneze valoarea datei membre NrMonede, - dou metode void add() i void rem() pentru incrementarea respectiv decrementarea valorii variabilei NrMonede.

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Pentru ca reprezentarea s poat extrage date ale documentului, ea trebuie s fie mai nti capabil s acceseze obiectul document. Infrastructura MFC se ocup automat de acest aspect, adugnd n clasa reprezentare a aplicaiei metoda GetDocument. Clasa derivat din CView este responsabil de afiarea teancului de monede. Codul care se ocup efectiv de desenarea monedelor se afl n funcia OnDraw()a clasei respective. AppWizard creeaz un schelet al acestei funcii, care trebuie apoi completat: void CSDIView::OnDraw(){ //Obtinerea pointerului la document CSDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); //Salvarea pensulei curente CBrush* pOldBrush=pDC->GetCurrentBrush(); //Crearea unei noi pensule de culoare galbena CBrush br; br.CreateSolidBrush(RGB(255,255,0)); //Selectarea pensulei galbene in contextul dispozitiv pDC->SelectObject(&br); //Obtinerea numarului de monede de la document si //reprezentarea fiecarei monede prin doua elipse for(int i=0;i<pDoc->GetNr();i++){ int y=200-30*i; pDC->Ellipse(40,y,100,y-30); pDC->Ellipse(40,y-5,100,y-35); } //Restaurarea vechii pensule pDC->SelectObject(pOldBrush); } Exerciiu 2. Adugai dou opiuni de meniu Add i Rem pentru adugarea i eliminarea unei monede. Tratai aceste resurse de meniu n clasa CMainFrame:
void CMainFrame::OnAdd() { //Obinerea pointerului spre document CSDIDoc* pDoc=(CSDIDoc*)GetActiveDocument(); pDoc->add(); //Actualizarea vizualizrii documentului pDoc->UpdateAllViews(NULL); } void CMainFrame::OnRem() { //Obinerea pointerului spre document CSDIDoc* pDoc=(CSDIDoc*)GetActiveDocument(); pDoc->rem();

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

//Actualizarea vizualizrii documentului pDoc->UpdateAllViews(NULL); }

Acum compilai i executai .

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 .

Programare orientat pe obiecte

Lucrarea de laborator 7.
Visual C++ 6.0 MFC Bare de control. Dialoguri comune. Foi de proprieti.

1.1.1 Bare de control


Barele de control sunt elemente de interfa cu utilizatorul, folosite pentru a conine alte controale sau alte ferestre. Exist trei categorii de bare de control: Barele de stare - reprezint cel mai simplu tip de bare de control. Barele de control sunt n permanen afiate n partea de jos a unei ferestre cadru. Bare de instrumente - conin butoane folosite drept comenzi rapide de meniu. Bare de dialog - conin butoane i alte categorii de controale, cum ar fi casetele combinate, casetele list sau controalele de desfurare.

1.1.2 Bare de stare


Barele de stare sunt un element standard al interfeei cu utilizatorul. O bar de stare este o bar de control aflat n partea de jos a cadrului unei aplicaii. Barele de stare sunt, de obicei, divizate n mai multe panouri, cunoscute i sub numele de indicatori. De exemplu, aplicaiile create cu AppWizard are panouri destinate afirii strii tastelor Num Lock i Caps Lock. ntr-un program MFC, toate barele de control aparin ferestrei principale. Clasa cadru principal, CMainFrame, conine un obiect CStatusBar denumit m_wndStatusBar care este creat i iniializat n funcia CMainFrame::OnCreate(). if(!m_wndStatusBar.Create(this)|| !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0(Nu s-a reusit crearea unei bare de stare \n) return 1; } nainte de a crea o bar de stare, trebuie creat o matrice de identificatori de resurs, folosii pentru fiecare panou al barei de stare. Aceast matrice de identificatori este transmis ca parametru funciei SetIndicators(). Identificatorii se folosesc pentru a identifica fiecare panou al barei de stare i irul text prestabilit pentru fiecare panou n parte. Este necesar atribuirea unei resurse ir prestabilite pentru fiecare panou adugat barei de stare. Proprietile unui panou din bara de stare se stabilesc apelnd funcia SetPaneInfo.
m_wndStatusbar.SetPaneInfo(4, ID_INDICATOR_TIME, SBPS_POPOUT, 80);

Funcia SetPaneInfo primete ca parametrii: indexul panoului, identificatorul panoului, stilul panoului i limea acestuia. Stilurile de panou disponibile sunt: SBPS_STRECH - arat c acel panou se poate extinde pentru a acoperi spaiul nefolosit. Un singur panou dintr-o bar de stare poate avea acest atribut, App Wizard atribuindu-l primului panou. SBPS_NOBORDER - arat c nu se va desena nici o margine tridimensional n jurul panoului. SBPS_POPOUT - indic trasarea unei margini inverse. SBPS_NORMAL - creeaz o bar de stare fr extindere, margini sau efecte de ieire n relief. SBPS_DISABLED - indic faptul c nu va scrie nici un text.

Un exemplu de bar de stare l reprezint adugarea unui nou panou care s indice ora curent. - Adugarea unui nou panou implic urmtoarele operaii; - Adugarea unui identificator n matricea de identificator; - Adugarea unui articol de text prestabilit n tabelul de iruri; - Adugarea unui instrument de actualizare a comenzii pentru panoul respectiv.

1.1.3 Adugarea unui identificator nou


Exerciiu 1. Pentru a defini un nou simbol de resurs, selectai caseta de dialog Resource Symbols din meniul View. Apsai butonul New i introducei numele unui nou simbol ca fiind ID_INDICATOR_TIME.
n fiierul surs MainFrame.cpp se afl un vector UINT utilizat pentru a defini aspectul barei de stare. Modificai vectorul indicators astfel nct s arate ca n listingul urmtor:

static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, ID_INDICATOR_TIME }; Pentru a aduga o resurs tabel de iruri folosind simbolul ID_INDICATOR_TIME se procedeaz astfel: - n eticheta Resource View din fereastra Project Workspace deschidei resursa String Table; - inserai un nou articol n tabela de iruri cu valoarea ID_INDICATOR_TIME drept identificator.

1.1.4 Definirea cronometrului i a stilurilor de panouri


Proprietile unui panou din bara de stare se stabilesc apelnd funcia SetPaneInfo .

m_wndStatusBar.SetPaneInfo(4 , ID_INDICATOR_TIME , SBPS_POPOUT , 80); Funcia SetPaneInfo are patru parametrii: indexul panoului, indentificatorul panoului, stilul panoului i limea acestuia. Stilurile de panou disponibile sunt: - SBPS_STRECH - permite extinderea panoului pentru a acoperi spaiul nefolosit; - SBPS_NOBORDER - arat c nu se va desena nici o margine tridimensional n jurul panoului; - SBPS_POPOUT - indic trasarea unei margini inverse; - SBPS_NOMAL - creeaz o bar de stare fr extindere, margini sau efecte de ieire n relief; - SBPS_DISABLED - indic faptul c nu va fi scris nici un text. Definii un stil pentru noul articol din bara de stare i iniializai un cronometru pentru fiecare secund n funcia CMainFrame::OnCreate . m_wndStatusBar.SetPaneInfo(4 , ID_INDICATOR_TIME , SBPS_POPOUT , 80); SetTimer(1,1000,NULL); Tratarea resursei de ceas Utiliznd Class Wizard, adugai o funcie de tratare a mesajelor pentru WM_TIMER n clasa CmainFrame. Aceast funcie este apelat atunci cnd ceasul setat cu ajutorul funciei SetTimer expir. void CMainFrame::OnTimer(UINT nIDEvent) { m_wndStatusBar.InvalidateRect(NULL); } Atunci cnd timpul expir, panoul principal va invalida dreptunghiul barei de state, determinnd redesenarea acesteia. Cnd bara de stare este invalidat, panoul MFC actualizeaz fiecare panou folosind un instrument CCmdUI. Dei se poate folosi ClassWizard pentru a crea asemenea instrumente pentru majoritatea obiectelor de interfa cu utilizatorul, instrumentele pentru manevrarea panourilor unei bare de stare trebuie create manual. Adugai o declaraie pentru funcia de actualizare CCmdUI n declaraia clasei CMainFrame. Este necesar adugarea unei singure linii de cod, i anume declaraia pentru OnUpdateTimer: protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnTimer(UINT nIDEvent); //}}AFX_MSG afx_msg void OnUpdateTimer(CCmdUI* pCmdUI);

DECLARE_MESSAGE_MAP() n continuare, adugai intrarea n harta de mesaje din MainFrame.cpp, dup cum urmeaz: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_TIMER() //}}AFX_MSG_MAP ON_UPDATE_COMMAND_UI(ID_INDICATOR_TIME, OnUpdateTimer) END_MESSAGE_MAP() Adugai funcia OnUpdateTimer n fiierul MainFrame.cpp: void CMainFrame::OnUpdateTimer(CCmdUI* pCmdUI){ //Activarea panoului pCmdUI->Enable(); //Obtinerea orei curente CTime theTime=CTime::GetCurrentTime(); CString szTime=theTime.Format("%I:%M:%S %p"); //Completarea panoului cu ora curenta pCmdUI->SetText(szTime); } Compilai i executai exemplul creat. Acum, bara de stare are un nou panou, situat la extremitatea dreapt, care conine ora curent.

PROGRAMAREAORIENTATPEOBIECTELaborator

Lucrarea de laborator 8.

Realizarea unui cronometru


Urmndpascupasindicaiiledinaceastlucrarerealizaiuncronometrucupreciziadeosecund. Primaaciunevaficreareaaplicaieistandard.Adouavaficreareaelementelordeinterfa(dou butoaneiocasetdeeditare).Atreiavafiintroducereavariabilelorglobaleiacoduluidefuncionare efectivacronometrului.nfinalfereastradeaplicaievaartacamaijos:

Creareaaplicaieistandard
DacpnacumamfostobinuiicuaplicaiiSDI(SingleDocumentInterfaceInterfacuunsingur Document)aplicaiicustructurrelativcomplex,naceastlucrarevomfolosioaplicaiedetipDialog. PorninddelaopiuneaNewdinmeniulVisualStudiocremunproiectnouprinopiunea MFCAppWizard(.exe)ialegemlaunuldinpainlocdeSDI,opiuneaDialogBased.Odatcreat aplicaiaocompilmiorulmcutastaF5.

PROGRAMAREAORIENTATPEOBIECTELaborator

Creareaelementelordeinterfa
UrmtorulpasestetergereabutoanelorOKiCANCELinlocuirealorcuStartiReset. Pentru a crea aceste dou butoane folosim paleta cu elemente de interfa. Selectm butonul ca element de interfa i l depunem pe suprafaa ferestrei de dialog. Facem clic dreapta pe butonul depus i accesm opiunea Properties. n cadrul tabului General observm c idul butonului este IDC_BUTTON1. Este util stim acest ID pentru a modifica butonul n timpul rulrii aplicaiei. n cadrul acestui tab mai estei opiunea Caption prin care putem specifica textul scris pe buton. Vom modifica acest text pentru a scrie Start. Repetm operaia cu butonul de Reset. Observm c i se asociaz automatIDulIDC_BUTTON2. Cremi o caset de editare prin selectarea ei din palet. O modificm prin opiunea Properties pentru aafiatextulcentrat.AceastopiunesegsetentabulStylemeniulAlignText. ncercm s aliniem ct mai bine aceste elemente de interfa n cadrul ferestrei. Eventual folosim i opiuniledemeniudealiniereLayout>Align.

Interconectareaelementelordeinterfa
Pentruaticumsinterconectmacesteelementedeinterfatrebuiescunoatemoseriedeclase. TrebuiescunoatemclaseleCButtoniCEdit,pentruconfigurareaavansataacestorinterfee. n plus avem nevoie de o clas deiruri de caractere care s permit formatarea afirii timpului scurs. UncandidatbunesteCString. PentruaaveaacceslaceasulsistemuluivomfolosiclasaCTime. O funcie important n legarea IDurilor elementelor de interfa de codul aplicaiei este GetDlgItem princareplecnddelaIDobinemunpointerlaunobiectconcret. innd cont c anumite elemente trebuie si pstreze valorile i la prsirea domeniului funciei va trebuisdeclarmtreivariabileglobalensensuldeafidisponibilencadrulclaseiC###Dlg. Unadinacestevariabileestetimp0ncarevompstramomentulncareafostapsatbutonuldeStart. Celelaltedousuntstart_ireset_pentruasemnalizastareapornitacronometruluiistareapasager deresetarealui.Acesteadousuntdetipbool,adicdetiplogic. timp0estedetipCTime. Pentru a aduga aceste variabile la clas, folosim fereastra de vizualizare a claselor aflat de obicei n partea stng a ferestrei mediului de programare. Facem clic dreapta pe C###Dlgi alegem opiunea AddMemberVariable.ncasetadesusspecificmtipulvariabileiiarnceadejosnumeleei. nconstructorulclaseivomintroduceurmtoaresecvendeiniializareavariabilelorstart_ireset_: C###Dlg::C###Dlg(CWnd*pParent/*=NULL*/) 2

PROGRAMAREAORIENTATPEOBIECTELaborator
{ } :CDialog(C###Dlg::IDD,pParent) //{{AFX_DATA_INIT(CCrono01Dlg) //NOTE:theClassWizardwilladdmemberinitializationhere //}}AFX_DATA_INIT //NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32 m_hIcon=AfxGetApp()>LoadIcon(IDR_MAINFRAME); start_=false; reset_=true;

Introducem doar secvena scris italic ngroat. Observm c ### reprezint numele aplicaiei care difernfunciedenumeleproiectului. Pentru actualizarea coninutului ferestrei este nevoie de o temporizare. Putem specifica o funcie de tratare a temporizrii prin clic dreapta pe numele clasei C###Dlg i alegerea opiunii Add Windows MessageHandler.VomalegeWM_TIMER.nmomentulconfirmriivaapreaofuncieOnTimerncare vomintroduceurmtorulcod: voidC###Dlg::OnTimer(UINTnIDEvent) { //TODO:Addyourmessagehandlercodehereand/orcalldefault if(start_||reset_) { if(reset_)timp0=CTime::GetCurrentTime(); CTimetimp2=CTime::GetCurrentTime(); CTimetimp1(timp0); CEdit*afisaj; CStrings; longdt,h1,h2,m1,m2,s1,s2; h1=timp1.GetHour(); h2=timp2.GetHour(); m1=timp1.GetMinute(); m2=timp2.GetMinute(); s1=timp1.GetSecond(); s2=timp2.GetSecond(); afisaj=(CEdit*)GetDlgItem(IDC_EDIT1); dt=(h2h1)*3600 +(m2m1)*60 +(s2s1); s.Format(_T("%02i:%02i:%02i"),(dt/3600)%24,(dt/60)%60,(dt)%60); afisaj>SetWindowText(s); reset_=false; } CDialog::OnTimer(nIDEvent); } 3

PROGRAMAREAORIENTATPEOBIECTELaborator
Observm folosirea clasei CTime cu metodele sale care returneaz orele( GetHour), minutele(GetMinute)sausecundele(GetSecond).Pentruaflareatimpuluicurentdefolosetefuncia GetCurrentTime(). Se observ c se face diferena dintre cele dou momente temporalei se afieaz formatat folosind funcia Format ca clasei CString. Specificarea formatului folosind clasa Format se face lafelcalaprintfdeosebireafiindncapsulareaexpresiin_T(). Se observ folosirea funciei GetDlgItem(IDC_###) aceasta returneaz un pointer la IDul resursei de interfa,acesteelementedeinterfapotfiunbuton,ocasetdeeditare,uncombobox,unlistbox,un bitmap etc. Pointerul returnat fiind unul general va trebui precizat ntre paranteze natura lui exemplu (CEdit*). Se observ c se declar un pointer la obiecti nu un obiect, deoarece resursa are deja alocat spaiudememorie. Funcia SetWindowText modific textul casetei de editare. Se observ iniializarea lui timp2 folosind constructoruliparametrultimp0. Pentru a asocia o funcie apsrii butonului Start folosim tabul Resource View, de lng tabul Class View, expandm ramurile i pe ramura Dialog apsm pe IDD_###_DIALOG. Facem dubluclic pe butonulStartvaapreafunciaOnStart.neavomscrie: voidC###Dlg::OnButton1() { //TODO:Addyourcontrolnotificationhandlercodehere if(!start_) { start_=true; timp0=CTime::GetCurrentTime(); SetDlgItemText(IDC_BUTTON1,"Stop"); }else { start_=false; SetDlgItemText(IDC_BUTTON1,"Start"); } } SeobservclaapsarearepetatabutonuluisefacealternanStartStopadenumiriibutonului. Procedmlafelicubutonuldereset. Funciavafiurmtoarea: voidC###Dlg::OnButton2() { //TODO:Addyourcontrolnotificationhandlercodehere reset_=true; } 4

PROGRAMAREAORIENTATPEOBIECTELaborator
Pentruainiializatimerulipentruaresetasistemulvomscrieurmtoareleliniinfunciademaijos: BOOLCCrono01Dlg::OnInitDialog() { CDialog::OnInitDialog(); //Add"About..."menuitemtosystemmenu. //IDM_ABOUTBOXmustbeinthesystemcommandrange. ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX<0xF000); CMenu*pSysMenu=GetSystemMenu(FALSE); if(pSysMenu!=NULL) { CStringstrAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if(!strAboutMenu.IsEmpty()) { pSysMenu>AppendMenu(MF_SEPARATOR); pSysMenu>AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu); } } //Settheiconforthisdialog.Theframeworkdoesthisautomatically //whentheapplication'smainwindowisnotadialog SetIcon(m_hIcon,TRUE); //Setbigicon SetIcon(m_hIcon,FALSE); //Setsmallicon //TODO:Addextrainitializationhere SetTimer(123,50,0); timp0=CTime::GetCurrentTime(); returnTRUE;//returnTRUEunlessyousetthefocustoacontrol } ntrebareMaiestenevoiedeiniializareatimpuluitimp0naceastfuncie?Justificai.

PROGRAMAREAORIENTATPEOBIECTELaborator

Lucrarea de laborator 9. Visual C++ MFC Utilizarea controalelor.


1.1.1 Controlul de tip buton CButton
Acest control este folosit pentru realizarea unei aciuni rapide fiind un element de interfa accesibil n special cu mouse-ul dar i prin tastatur. El are trei stri principale liber, selectat i apsat. Pentru a experimenta efectiv cu un buton vom crea un program prin MFC App Wizard alegem ca tip de aplicaie Dialog Based, la pasul 2 i 3 apsm Next, apoi Finish. Va aprea fereastra de creare modificare a interfeei. n aceasta fereastr putnd aduga orice control disponibil. Selectm un buton. l dispunem pe spaiul afiabil al ferestrei. Pentru a modifica proprietile implicite vom face clic cu butonul 2 al mouse-ului pe el. Alegem ultima opiune din meniu Properties.

S-a deschis fereastra de mai sus. La caracteristici generale avem ID-ul butonului care este un nume de identificare recunoscut pe tot parcursul programului i disponibil pentru orice element de interfa. La Caption avem textul ce va fi scris pe buton. Apoi o serie de opiuni ce se pot seta prin casete de validare. Principalul lucru care ne intereseaz este legare butonului de o aciune anume. Pentru aceasta vom avea nevoie de ID-ul butonului. Prin clic pe buton se va deschide o fereastr program n care avem corpul funciei n care vom scrie codul util ce va fi realizat la apsarea butonului: void CS07Dlg::OnButton1() { // Aici adaugati codul ce se executa la apasarea butonului } Unde S07 este numele programului. i funcia OnButton() este aciunea asociat butonului 1. Dac n schimb dorim s facem anumite modificri asupra butonului prin program,stau la dispoziie o serie de funcii membri dintre care s-au selectat cele mai reprezentative:

PROGRAMAREAORIENTATPEOBIECTELaborator

GetIcon,SetIcon pentru citirea,respectiv asocierea unui icon butonului; GetBitmap,SetBitmap pentru citirea,respectiv asocierea unui bitmap pentru suprafaa butonului; GetCursor,SetCursor pentru citirea, respectiv asocierea unui pointer de mouse diferit cnd aceste survoleaz butonul. Pentru a accesa o funcie membr a butonului se scrie urmtoarea secvena de cod: CButton *mybutton=(CButton *)GetDlgItem(IDC_BUTTON1); mybutton->functie_membra; Prin aceasta avem un pointer la resursa de tip buton cu ID-ul IDC_BUTTON1. Prin folosirea aceleai secvene cu specificarea clasei controlului, respectiv a ID-ului asociat acelui control, putem avea acces la oricare din membrii clasei controlului. GetButtonStyle,SetButtonStyle returneaz, respectiv seteaz stilul butonului. GetWindowText,SetWindowText returneaz, respectiv seteaz textul butonului. Exemplu: mybutton->SetWindowText("De acord!"); char s[100]; //pentru a extrage textul de pe buton mybutton->GetWindowText(s,100);//textul este returnat n variabila s Exerciiu 1. Creai un program dup modelul precizat mai sus. Creai un buton care iniial indic Liber, iar dup apsare Apsat!. Numai cu funciile SetWindowText i GetWindowText ncercai s creai un program care s numere pn la cinci la fiecare apsare crescnd cu o unitate numrul i afind numrul pe buton. O alt soluie ar fi urmtoarea: 1. Declarai o variabil contor k n fisierul header xxxdlg.h, n clasa xxxDlg la seciunea protected. 2. Iniializai contorul k la 0 i afiai valoare pe buton n xxxDlg::OnInitDialog: CButton *mybutton=(CButton *)GetDlgItem(IDC_BUTTON1); k=0; char s[100]; sprintf(s,"%d",k); mybutton->SetWindowText(s); 3. In funcia de aciune a butonului vei scrie urmtoarea secven de cod: void CS07Dlg::OnButton1() { CButton *mybutton=(CButton *)GetDlgItem(IDC_BUTTON1); k++; char s[100];

PROGRAMAREAORIENTATPEOBIECTELaborator sprintf(s,"%d",k); mybutton->SetWindowText(s); } 4. Compilai i rulai.

1.1.2 Controlul de tip caset de editare CEdit


CEdit este un tip de control ce permite introducerea unei secvene de text pe un singur rnd. Putei seta proprietile casetei de editare din fereastra de editare a controlului la fel cum s-a procedat cu CButton. Dei deine mai multe funcii membre specifice cele mai utile sunt cele ce returneaz textul coninut GetWindowText, respectiv modific textul coninut SetWindowText. Alte funcii membre: GetLimitText,SetLimitText returneaz numrul maxim de caractere ce se pot introduce prin tastare,sau inserare, respectiv stabilete acest numr. GetModify() returneaz 0 dac textul din caseta de editare nu a fost modificat, altfel valoare diferit de 0. SetModify() reseteaz steguleul de modificare al coninutului casetei trecndu-l pe starea nemodificat. SetSel seteaz poziionarea seleciei pe textul din caseta. GetSel returneaz poziia seleciei textului din caseta. Undo aduce textul din caseta la starea precedent. Clear terge selecia curenta. Copy copie selecia curent n clipboard. Cut terge selecia curent nu nainte de a o copia n clipboard. Paste insereaz text din clipboard la poziia curent. SetReadOnly seteaz accesul la textul din caset putnd interzice modificarea lui. ShowCaret,HideCaret arat ,respectiv ascunde cursurul. Exerciiu 2. Creai un program cu o caset text i un buton care la apsarea butonului textul din caset s fie transferat ca text pe buton. Asociai casetei de editare o variabil CString astfel: 5. Lansai ClassWizard. 6. Selectai pagina Member Variables. 7. Selectai din caseta combinat Class_Name clasa asociat dialogului. 8. Selectai din caseta cu list IDC_EDIT1 9. Efectuai un clic pe butonul Add Variable. 10. Asiguraiv c n caseta combinat Category este selectat Value i c n caseta Variable Type este selectat Cstring.

PROGRAMAREAORIENTATPEOBIECTELaborator 11. Introduceti numele variabilei m_str n caseta Member Variable Name i apoi efectuai un clic pe OK. 12. Introducei 15 n caseta Maximum Characters din partea inferioar a casetei de dialog ClassWizard. Aceasta limiteaz lungimea irului acceptat de ctre caseta de dialog. 13. Efectuai un clic pe OK. n continuare se va scrie funcia pentru acionarea butonului OnButton1(). void CXXXDlg::OnButton1() { // TODO: Add your control notification handler code here UpdateData(); CButton *mybutton=(CButton *)GetDlgItem(IDC_BUTTON1); mybutton->SetWindowText(m_str); } Exerciiu 3.Creai un program cu dou casete text i un buton. La apsarea butonului textul selectat din prima caset este nserat pe poziia curent a cursorului n cea de a doua caseta. Pentru afisare in caseta de dialog se va utiliza funcia Update Data(FALSE).

PROGRAMAREAORIENTATPEOBIECTELaborator

Lucrarea de laborator 10. Visual C++ MFC Utilizarea controalelor.


1.1.1 Controlul de tip caset de validare CCheckListBox
Este folosit pentru a bifa / debifa o opiune ntr-o interfa. Poate fi configurat prin interfa vizual ca i CButton. Dintre funciile membre specifice amintim: GetWindowText, SetWindowText care returneaz sau seteaz textul casetei de validare la fel ca n cazul casetei de editare. GetCheck, SetCheck returneaz, respectiv seteaz starea bifrii. GetCheckStyle, SetCheckStyle returneaz, respectiv seteaz stilul casetei. CCheckListBox *cb=(CCheckListBox *)GetDlgItem(IDC_CHECK1); cb->SetWindowText("Acum"); cb->SetCheckStyle(BS_CHECKBOX); cb->SetCheck(IDC_CHECK1,1); Este un exemplu de folosirea a acestor metode (funcii membre). n privina stilurilor exista urmtoarele constante predefinite:
BS_CHECKBOX stilul precizeaz o caset standard; BS_AUTOCHECKBOX - caseta se bifeaz sau se debifeaz doar prin simpla selectarea a

acesteia;
BS_AUTO3STATE precizeaz o caset cu trei stri care se bifeaz sau debifeaz prin

selectare;
BS_3STATE precizeaz o caset cu trei stri, astfel nct caseta poate fi n acelai timp

i bifat i dezactivat. Enable seteaz starea de activare a casetei. IsEnabled returneaz starea de activare a casetei. Exerciiu 1. Creai un program cu patru casete de validare i o caset de editare. Casetele vor avea ca etichet numerele 1,2,3,4. De fiecare dat cnd o caset va fi bifat n caseta de editare vor aprea etichetele casetelor bifate legate ntre ele prin spaiu.

PROGRAMAREAORIENTATPEOBIECTELaborator De exemplu dac sunt bifate caseta 2 i 4 n caseta de editare va aprea 2 4. Se vor parcurge urmtorii pai: Se trece n ResourceView i se introduc patru casete de validare cu Caption notat cu 1, 2, 3, respectiv 4 i o caset de editare. Acestei casete de editare i se asociaz variabila membru m_m de tip CString. n clasa ClXXXDlg se definesc patru variabile de tip CString notate cu m_1, m_2, m_3, m_4 ce vor prelua informaiile din casetele de editare ale casetelor de validare. Fcnd dublu clic pe casetele de validare se definesc funciile void CxxxDlg::OnCheck1() ,CxxxDlg::OnCheck2() , CxxxDlg::OnCheck3(), CxxxDlg::OnCheck4() dup exemplul urmtor (pentru prima caset): GetDlgItem(IDC_CHECK1)->GetWindowText(m_1); m_m=m_1+" "+m_2+" "+m_3+" "+m_4; UpdateData(FALSE); Concatenarea in CString se realizeaz cu +.

1.1.2 Controlul tip buton radio


Butoanele radio permit selectarea doar unei opiuni dintr-un grup de opiuni. Aceste butoane pot fi grupate astfel nct s avem diverse grupuri de opiuni. Se observ ca la selectarea unei opiuni cea anterior selectat se deselecteaz. Pentru a accesa textul unui buton radio vom folosi urmtoarea secven: GetDlgItem(IDC_RADIO1)->SetWindowText("Asteptare!"); De notat c butoanele radio nu au o clas specific definit putnd fi ncrcate cu CCheckListBox, chiar i cu CButton, desigur metodele nu vor fi ntotdeauna valabile. Exerciiu 2. Creai un program cu patru butoane radio grupate avnd etichetele nume de persoane i o caset de editare. n momentul cnd butonul radio va fi selectat n caset va aprea numele persoanei alese. Se vor parcurge urmtorii pai: Se trece n ResourceView i se introduc patru butoane radio i le grupm cu Group Box cu Caption notat cu nume de persoane i o caset de editare. Acestei casete de editare i se asociaz variabila membru m_str de tip CString. Fcnd dublu clic pe butoanele radio se definesc funciile void CxxxDlg:: OnRadio1() ,CxxxDlg:: OnRadio2() , CxxxDlg:: OnRadio3(), CxxxDlg:: OnRadio4() dup exemplul urmtor (pentru prima caset): GetDlgItem(IDC_RADIO1)->GetWindowText(m_str); UpdateData(FALSE);

PROGRAMAREAORIENTATPEOBIECTELaborator

Lucrarea de laborator 11 Visual C++ MFC Utilizarea controalelor.


1.1.1 Controlul de tip lista combo CComboBox
Permite selectarea unui ir de caractere dintr-o list retractabil. n momentul n care este selectat se desfoare lista i poate fi selectat opiunea dorit. Cele mai utile metode ale CComboBox sunt cele de construire a listei: AddString(s) adaug un ir de caractere la sfritul listei sau la poziia indexat alfabetic dac opiunea de auto-sortare a listei este activat; DeleteString(index) terge un element din list de pe poziia specificat de index; InsertString(index,s) insereaz un ir s n list la poziia specificat de index; FindString caut un sub-ir n list i dac l gsete i returneaz indexul; Exemplu: CComboBox *lista=(CComboBox *)GetDlgItem(IDC_COMBO1); lista->AddString("Andrei"); lista->AddString("Adrian"); lista->AddString("Radu"); lista->AddString("Mihai"); Metode pentru lucrul cu indexul: GetCount returneaz numrul de elemente din list; GetCurSel returneaz poziia elementului selectat din list; SetCurSel seteaz elementul curent selectat copiindu-l n caseta de editare, de notat c primul element are indicele 0; Clear,Copy,Cut, Paste terge, copie, decupeaz,respectiv adaug text din caseta de editare n sau din Clipboard; GetLBText obine textul unui element din list de la poziia specificat de un index; Exerciiu 1. Realizai un program cu o list de ri europene cel puin zece. Creai i o caset de editare. n momentul n care ai selectat o ar numele acesteia s fie copiat n caseta de editare.

PROGRAMAREAORIENTATPEOBIECTELaborator

Se vor parcurge urmtorii pai: Se trece n ResourceView i se introduc o caset combinat (Combo Box) i o caset de editare. Se intr n Combo Box Properties (fcnd clic pe butonul din dreapta mous-ului, atunci cnd este poziionat pe caset) i se selecteaz stilul ca fiind Drop List. Tot din Combo Box Properties se selecteaz Data, putnd introduce itemii dorii (rile). Se va putea trece la un item nou, numai dac se apas combinaia de taste CTRL+ENTER. Casetei de editare i se asociaz variabila membru m_str de tip CString. Pentru Combo Box se va introduce o funcie void CXXXDlg::OnSelchangeCombo1() ce va conine urmtoarele instruciuni: GetDlgItem(IDC_COMBO1)->GetWindowText(m_str); UpdateData(FALSE); Se ruleaz aplicaia.

1.1.2 Controlul de tip text static: CStatic


CStatic este un control care doar afieaz un text la o anumit locaie. Acest text poate fi modificat ca i la celelalte controale prezentate cu ajutorul funciei SetWindowText i poate fi aflat acel text cu GetWindowText. Un exemplu ar fi urmtoarea structur: CStatic *st=(CStatic *)GetDlgItem(IDC_STATIC); st->SetWindowText("Aceasta este un text static."); Exerciiu 2. Modificai programul precedent astfel nct n dreptul casetei de editare s apar tara aleasa, iar n dreptul listei tari disponibile.

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 12
Visual C++ MFC Utilizarea funciilor grafice. Pentru a lucra cu funciile grafice oferite n cadrul MFC vom aborda urmtoarea opiune de generare a programului schelet : 1. Selectm MFC App Wizard (.exe) i scriem numele proiectului; 2. Alegem Single Document (SDI) i apsm Next. 3. La pasul 2 apsm Next. 4. La pasul 3 apsm Next. 5. Debifm Docking Toolbar, Initial Status Bar, Printing and print preview, apsm Finish. Va aprea n stnga ecranului clasele disponibile. Alegem CxxxView expandm ramura i apsam pe OnDraw. Cursurul se va poziiona automat n fereastra codului surs: void CSs01View::OnDraw(CDC* pDC) { CSs01Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // aici se insereaz codul care deseneaz } Desenarea unei linii Nu exist efectiv o funcie care s traseze o linie, n schimb acest lucru se poate realiza prin conlucrarea a dou funcii MoveTo care stabilete poziia unui capt al liniei i LineTo care stabilete poziia celuilalt capt i traseaz linia. Ele au urmtoarele prototipuri: CPoint MoveTo( int x, int y ); CPoint MoveTo( POINT point ); BOOL LineTo( int x, int y ); BOOL LineTo( POINT point ); Astfel se pot apela fie specificnd coordonatele x, y ale capetelor, fie specificnd punctul captului. n program vom scrie: pDC->MoveTo(10,10); pDC->LineTo(100,100); ,pentru a desena o linie cu setrile implicite ale culorii, grosimii i stilului de desenare.

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

Desenarea unui arc de cerc se poate face cu trei funcii distincte : 1. Arc cu prototipurile : BOOL Arc( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); 2. ArcTo cu prototipurile: BOOL ArcTo( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL ArcTo( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); 3. AngleArc cu prototipul: BOOL AngleArc( int x, int y, int nRadius, float fStartAngle, float fSweepAngle ); Rezultatul este acelai trasarea unui arc de cerc. Vom face referire la doar un singur prototip cel expandat. Pentru Arc : x1, y1 coordonatele colului stnga sus al zonei rectangulare de ncadrarea ; x2, y2 coordonatele colului dreapta jos al zonei rectangulare de ncadrarea ; x3, y3 punctul de nceput al arcului ; x4, y4 punctul de sfrit al arcului de cerc ; Pentru ArcTo aceleai precizri numai c poziia curent a cursorului este rennoit. Pentr AngleArc : - x, y coordonatele centrului cercului ; - Radius este raza cercului ; - StartAngle reprezint unghiul de start al desenrii arcului ; - SweepAngle reprezint mrimea unghiular a arcului. Exemplu: pDC->Arc(10,10,200,200,10,10,200,200); pDC->ArcTo(10,10,200,200,10,10,200,200); pDC->AngleArc(100,100,100,10,90); Desenarea unei linii poligonale Pentru a desena o linie poligonala folosim funciile : PolyDraw, Polyline, PolyPolyline, PolylineTo, PolyBezier, PolyBezierTo care au urmtoarele prototipuri: BOOL PolyDraw( const POINT* lpPoints, const BYTE* lpTypes, int nCount ); BOOL Polyline( LPPOINT lpPoints, int nCount ); BOOL PolyPolyline( const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount );

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator BOOL PolylineTo( const POINT* lpPoints, int nCount ); BOOL PolyBezier( const POINT* lpPoints, int nCount ); BOOL PolyBezierTo( const POINT* lpPoints, int nCount ); PolyDraw deseneaz o linie poligonal cu un anumit tipic : - lpPoints este un pointer la un vector de puncte. - lpTypes este un pointer la un vector care specific pentru fiecare punct specificul desenrii ; - nCount este numrul de puncte desenate din vector. Polyline deseneaz o linie poligonal deschis fr a modifica poziia cursorului . PolyPolyline deseneaz o serie de linii poligonale acestea fiind specificate una dup alta n lpPoints, iar numrul de puncte al fiecrei linii este specificat n lpPolyPoints. PolylineTo deseneaz o linie poligonal rennoind poziia cursorului. PolyBezier deseneaz o curb Bezier ale crei puncte generative sunt specificate n lpPoints. PolyBezier deseneaz o curb Bezier cu rennoire cursorului. Exemplu : CPoint p[100]; int i; for (i=1;i<=50;i++) { p[i-1].x=i*5; p[i-1].y=100-(i%2)*40; } pDC->Polyline(p,50); Aceast secven va desena o linie n zigzag. Mai sunt funciile de specificare a direciei de desenare : GetArcDirection., SetArcDirection cu urmtoarele prototipuri: int GetArcDirection( ) const; int SetArcDirection( int nArcDirection ); Unde nArcDirection poate lua unu din urmtoarele valori constante : AD_COUNTERCLOCKWISE - specific c sensul va fi cel invers acelor de ceas; AD_CLOCKWISE - specific c sensul va fi cel al acelor de ceas. Acerte funcii influeneaz sensul n care se traseaz urmtoarele primitive grafice: Arc, ArcTo, Chord, Ellipse, Pie, Rectangle, RoundRect. Funcii de desenare de figuri umplute:

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator Pentru desenarea unei regiuni eliptice mrginite de o dreapt folosim Chord cu urmtoarele prototipuri : BOOL Chord( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Chord( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); Semnificaiile perechilor x,y sunt acelai ca la Arc. Pentru desenarea unui dreptunghi se folosete Rectangle cu urmtoarele prototipuri : BOOL Rectangle( int x1, int y1, int x2, int y2 ); BOOL Rectangle( LPCRECT lpRect ); Unde x1,y1, x2,y2 sunt coordonatele colului stnga-sus, respectiv dreapta-jos ale dreptunghiului. n cel de-al doilea prototip pentru a specifica aceste coordonate se folosete o structur de tipul CRect. Pentru desenarea unui dreptunghi avnd coluri rotunjite se folosete RoundRect cu prototipurile : BOOL RoundRect( int x1, int y1, int x2, int y2, int x3, int y3 ); BOOL RoundRect( LPCRECT lpRect, POINT point ); Unde primele patru valori, pentru primul prototip, sunt acelai ca pentru Rectangle, iar ultimele dou valori nu sunt coordonate ci raza pe ox, respectiv pe oy ale elipsei folosite la rotunjirea colurilor. Pentru desenarea unei elipse i eventual cerc, se folosete Ellipse cu urmtoarele prototipuri: BOOL Ellipse( int x1, int y1, int x2, int y2 ); BOOL Ellipse( LPCRECT lpRect ); Unde x1, y1, x2, y2 specific dreptunghiul ce ncadreaz elipsa, la fel fiind i cazul celui de al doilea prototip. Pentru desenarea unei regiuni eliptice delimitate de dou raze se folosete funcia Pie cu urmtoarele prototipuri: BOOL Pie( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); n care primele patru coordinate sunt aceleai ca la elips, urmtoarele patru specificnd punctual de nceput i de sfrit al regiunii. Pentru a desena un polygon nchis se folosete Polygon care are prototipul :

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator BOOL Polygon( LPPOINT lpPoints, int nCount ); Se observ ca avem aceeai parametri ca la Polyline, deosebire fiind c punctul de nceput este unit automat cu punctul de sfrit nchiznd astfel conturul poligonal. O variant a acestei funcii este PolyPolygon cu prototipul: BOOL PolyPolygon( LPPOINT lpPoints, LPINT lpPolyCounts, int nCount ); Care se comport la fel ca PolyPolyline n ceea ce privete funcia parametrilor utilizai. Setarea culorii i a stilului de desenare Pn acum s-a precizat cum se deseneaz o serie de primitive dar aceste sunt toate n alb i negru desenate cu umplere sau trasare simpl fr a utiliza un stil anume. Pentru a modifica penia cu care se traseaz liniile se va crea o peni proprie prin folosirea clasei CPen. Aceast peni ne permite s schimbm culoarea, grosimea liniei, i stilul liniei (linie ntrerupt). Pentru a modifica culoare de umplere vom crea o pensul proprie ce ne va permite s stabilim culoare de umplere, modelul de umplere, stilul de umplere. Pensula va fi definit prin utilizarea clasei CBrush. Configurarea peniei Pentru a crea propria peni se declara un obiect de tip CPen. Se apeleaz funcia Create cu urmtoarele prototipuri : BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor ); BOOL CreatePen( int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL ); Unde : nPenStyle specific stilul peniei; nWidth grosimea peniei; crColor reprezint culoare peniei specificate n format RGB; Stilul peniei poate fi precizat prin urmtoarele constante: PS_COSMETIC specific c modelul peniei este specificat n lpStyle; PS_GEOMETRIC specific c modelul va fi cu linii ntrerupte a cror lungimi sunt specificate n lpStzle; PS_ALTERNATE alterneaz un punct lips unul desenat n model; PS_USERSTYLE specific un model specific definit de utilizator n lpStyle. Exemplu de utilizare al peniei:

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator CPen mpen; mpen.CreatePen(PS_GEOMETRIC,3,RGB(0,0xFF,0)); CPen *oldpen=pDC->SelectObject(&mpen); CPoint p[100]; int i; for (i=1;i<=50;i++) { p[i-1].x=i*5; p[i-1].y=100-(i%2)*40; } pDC->Polyline(p,50); pDC->SelectObject(oldpen); Se va desena un zigzag verde de grosime 3. Pentru a nu mai aprea marginea unei figuri desenate ci doar umplere se seteaz grosimea peniei la 0. Configurarea pensulei Pentru a configura pensula se folosete clasa CBrush. Pentru a crea o pensul se dispune de un set bogat de metode : - CreateSolidBrush creeaz o pensul cu umplere uniform ; - CreateHatchBrush creeaz o pensul cu umplere haurat; - CreateBrushIndirect creeaz o pensul prin intermediul unei structuri LOGBRUSH; - CreatePatternBrush creeaz o pensul la care modelul de umplere este un bitmap; - CreateDIBPattternBrush creeaz o pensul la care modelul de umplere este un bitmap independent de context; - CreateSysColorBrush creeaz o pensul avnd culoare specificat de sistem, modificnd doar stilul de haurare. CreateSolidBrush are urmtorul prototip: BOOL CreateSolidBrush( COLORREF crColor ); n care doar se specific culoare de umplere, stilul de umplere va fi unul uniform. Exemplu : CPen mpen; mpen.CreatePen(PS_GEOMETRIC,3,RGB(0,0xFF,0)); CPen *oldpen=pDC->SelectObject(&mpen); CBrush mbrush; mbrush.CreateSolidBrush(RGB(0,0xFF,0xFF)); CBrush *oldbrush=pDC->SelectObject(&mbrush); CPoint p[100]; pDC->Ellipse(10,10,100,100);

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator pDC->SelectObject(oldpen); pDC->SelectObject(oldbrush); CreateBrushIndirect are urmtorul prototip: BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush ); Este cel mai indicat a fi folosit cnd se dorete un configurare completa a pensulei. Face apel la structura : LOGBRUSH typedef struct tagLOGBRUSH { // lb UINT lbStyle; COLORREF lbColor; LONG lbHatch; } LOGBRUSH; Unde lbStyle poate avea valorile: BS_DIBPATTERN pentru un model de umplere definit n DIB n acest caz lbHatch va fi indica adresa logic a DIB-ului; BS_HATCHED pentru un model cu haur; BS_HOLLOW figura nu va fi umplut; BS_NULL figura nu va fi umplut ; BS_PATTERN modelul este specificat ntr-un bitmap; BS_SOLID modelul de umplere este cel uniform. Pentru lbHatch avem urmtoarele opiuni : - HS_BDIAGONAL - haur la 45 de grade de la dreapta la stnga ; - HS_CROSS - haur n carouri formate din linii verticale i orizontale egal spaiate; - HS_DIAGCROSS - haur la 45 de grade; - HS_FDIAGONAL - haur la 45 de grade; - HS_HORIZONTAL - haur prin linii orizontale; - HS_VERTICAL - haur prin linii verticale; Exerciiu 1. S se realizeze o aplicaie de tip document avnd in meniu opiunea de DESENARE. Selectnd DESENARE vor apare opiunile PATRAT, CERC, ELIPSA, POLIGON. Aplicaia va permite desenarea unui ptrat cu peni roie, a unui cerc cu peni verde, a unei elipse pline albastre i a unui poligon atunci cnd se selecteaz opiunea corespunztoare. In ResourceView, IDR_MAINFRAME se introduce opiunea de desenare. n continuare se va defini itemul PATRAT, cruia prin ClassWizard i asociem funcia OnPatrat(), n care vom aduga codul urmtor: void CMainFrame::OnPatrat() { // TODO: Add your command handler code here

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator CClientDC pDC(this); CPen mpen; mpen.CreatePen(PS_GEOMETRIC,3,RGB(255,0,0)); CPen *oldpen= pDC.SelectObject(&mpen); pDC.Rectangle(10, 10, 100,100); } Itemului CERC, i asociem funcia OnDesenareCerc(), n care vom aduga codul urmtor: void CMainFrame::OnDesenareCerc() { // TODO: Add your command handler code here CClientDC pDC(this); // pDC.MoveTo(10,10); //pDC.LineTo(100,100); CPen mpen; mpen.CreatePen(PS_GEOMETRIC,3,RGB(0,0xFF,0)); CPen *oldpen= pDC.SelectObject(&mpen); pDC.MoveTo(195,55); pDC.AngleArc(150,55,45,0,360); } Itemului ELIPSA, i asociem funcia OnElipsa(), n care vom aduga codul urmtor: void CMainFrame::OnElipsa() { // TODO: Add your command handler code here CClientDC pDC(this); CPen lpen; lpen.CreatePen(PS_GEOMETRIC,3,RGB(0,0,255)); CPen *oldpen= pDC.SelectObject(&lpen); CBrush brBlue(RGB(0,0,255)); pDC.SelectObject(&brBlue); pDC.MoveTo(195,55); pDC.Ellipse(200,20,295,70); } Itemului POLIGON, i asociem funcia OnPoligon(), n care vom aduga codul urmtor: void CMainFrame::OnPoligon() { // TODO: Add your command handler code here CPoint p[100]; CClientDC pDC(this); CPen mpen; mpen.CreatePen(PS_GEOMETRIC,3,RGB(100,100,0)); CPen *oldpen= pDC.SelectObject(&mpen);

PROGRAMAREA ORIENTAT PE OBIECTE - Laborator p[0].x= 300; p[0].y= 55; p[1].x= 350; p[1].y= 5; p[2].x= 400; p[2].y= 55; p[3].x= 370; p[3].y= 105; p[4].x= 340; p[4].y= 105; pDC.MoveTo(300,55); pDC.Polygon(p,5); }

PROGRAMARE ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 13.


Visual C++ MFC Utilizarea intrrilor de la mouse i tastatur Oricare aciune a utilizatorului prin mouse sau tastatur sau pornind de la mouse i tastatur, sau aciune automat ciclic, care acioneaz asupra ferestrei are corespondent ntr-o structur de gestionare a acestor aciuni un mesaj sau eveniment. Lucrul cu mesaje este o caracteristic a aplicaiilor Windows, aceasta a aprut cu primele variante de Windows 3.1, apoi a devenit un standard n Win32, OWL, respectiv MFC. Astfel progresiv s-a trecut de la o asociere manual acestor mesaje unor funcii aciuni la o asociere semiautomat, respectiv automat. n ceea ce privete aciunile mouse-lui orice aciune unitar care nu mai poate fi redus la alte aciuni are asociat un mesaj sau un eveniment. Astfel unei apsri a mouse-ului ,doar apsare fr eliberare i este asociat un eveniment i dac acesta are o utilitate pentru program i se poate asocia o funcie n care s se gestioneze aceast aciune. La fel i pentru tastatur oricrei apsri de tast i este asociat un eveniment. Pentru a programa un eveniment, adic pentru a-i asocia o funcie utilizm urmtoarea abordare:

Dup cum se vede se apas butonul din dreptul comboului n care este selectat CSs02Dlg. Se apas Add Windows Message Handler cel ncercuit cu rou pentru a aduga o funcie care s gestioneze mesajul.

PROGRAMARE ORIENTAT PE OBIECTE - Laborator

Se deschide urmtoarea fereastr:

n partea stng se afl lista mesajelor disponibile, n partea dreapt list mesajelor crora li s-au asociat funcii. Se observ c denumirea mesajului are urmtorul tipic WM_nume_mesaj. Pentru a asocia o funcie mesajului dorit se selecteaz mesajul din lista din partea stng i se apas pe butonul Add Handler. Se poate aduga astfel unul sau mai multe mesaje pentru a fi tratate de program.(sau niciunul prin apsare butonului Cancel). Se observ c aici se pot aduga mesaje pentru toate obiectele definite prin selectarea corespunztoare a obiectului (lista Class or object to handle). De asemenea se dispune i de un filtru. Cu toate c putem aduga mai multe mesaje doar unuia i se va asocia o funcie n cadrul codului surs. Pentru a specifica crui mesaj i se va asocia o funcie se va face dublu clic pe acel mesaj mediul de programare va deschide automat fereastra codului surs exact la funcia asociat mesajului. Celelalte mesaje crora nu li s-au asociat funcii vor disprea automat din lista mesajelor tratate de program. Avnd acces la funcie putem programa acel eveniment. Observm c n funcie de evenimentul tratat funciei i sunt asociate anumii parametri prin care se transmit informaii de la eveniment. Pentru gestionarea mouse-lui avem definite urmtoarele mesaje: WM_LBUTTONDBLCLK trimis dac s-a fcut dublu-clic cu primul buton al mouselui; WM_LBUTTONDOWN trimis dac s-a apsat primul buton al mouseului;

PROGRAMARE ORIENTAT PE OBIECTE - Laborator WM_LBUTTONUP trimis dac s-a eliberat al doilea buton al mouselui; WM_MBUTTONDBLCLK trimis dac s-a fcut dublu clic pe butonul din mijloc al mouseului; WM_MBUTTONDOWN trimis dac s-a apsat butonul mijlociu al mouselui; WM_MBUTTONUP trimis dac s-a eliberat butonul mijlociu al mouseului; WM_MOUSEMOVE trimis dac s-a deplasat mouseul; WM_MOUSEWHEEL trimis dac s-a rotit rotia de derulare a mouseuui; WM_RBUTTONDBLCLK trimis dac s-a fcut dublu clic pe butonul doi al mouselui (butonul din dreapta n mod standard); WM_RBUTTONDOWN trimis dac s-a apsat butonul al doilea al mouseului; WM_RBUTTONUP trimis dac s-a eliberat butonul al doilea al mouseului;

Mai sunt i alte mesaje dar cu o folosire mai redus. Se va observa c toate funciile ce in de apsarea unui buton al mouseului sunt funcii identice ca parametri asociai. Astfel pentru mesajul WM_XBUTTONDBLCLK vom avea urmtorul prototip al funciei : afx_msg void OnXButtonDblClk( UINT nFlags, CPoint point ); , unde nFlags sunt o colecie de indicatori, a cror stare poate fi analizat prin constantele :
MK_CONTROL - Setat dac tasta CTRL este apsat; MK_LBUTTON - Setat dac primul buton al mouseului este apsat;

MK_MBUTTON - Setat dac butonul din mijloc al mouseului este apsat; MK_RBUTTON - Setat dac butonul al doilea al mouseului este apsat; MK_SHIFT - Setat dac tasta SHIFT este inut apsat;

point reprezint poziia curent a mouselui coordonata x este dat de point.x, iar y de point.y. Pentru mesajul WM_XBUTTONDOWN avem urmtoarea funcie asociat : afx_msg void OnXButtonDown( UINT nFlags, CPoint point );
Pentru WM_XBUTTONUP vom avea o funcie asociat cu un prototip asemntor:

afx_msg void OnXButtonUp( UINT nFlags, CPoint point ); WM_MOUSEMOVE are o funcie asociat cu urmtorul prototip: afx_msg void OnMouseMove( UINT nFlags, CPoint point );

PROGRAMARE ORIENTAT PE OBIECTE - Laborator WM_MOUSEWHEEL are o funcie asociat cu urmtorul prototip: afx_msg BOOL OnMouseWheel( UINT nFlags, short zDelta, CPoint pt ); ,unde zDelta specific unghiul de rotaie al rotiei mouselui poate avea valori positive sau negative n funcie de direcia de rotaie; i pt reprezint poziia actual a pointerului de mouse. Exerciiul 1 S se realizeze o aplicaie care deseneaz un dreptunghi la poziia curent a mouse-ului de fiecare dat cnd se apas butonul stng al mouse-ului i un cerc cnd este apsat butonul drept al mouse-ului. Pentru a realiza aplicaia vom aborda urmtoarea opiune de generare a programului schelet : 1. Selectm MFC App Wizard (.exe) i scriem numele proiectului; 2. Alegem Single Document (SDI) i apsm Next. 3. La pasul 2 apsm Next. 4. La pasul 3 apsm Next. 5. Debifm Docking Toolbar, Initial Status Bar, Printing and print preview, apsm Finish. Vom numi aplicaia Lpo. Pe clasa CLpoView se face clic dreapta i se selecteaz Add Windows Messages Handler. Se va selecta WM_LBUTTONDOWN i se va aduga un Handler (ca n figura urmtoare).

PROGRAMARE ORIENTAT PE OBIECTE - Laborator n continuare se va scrie codul pentru funcia OnLButtonDown, de exemplu se selecta Edit Existing. void CLpoView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); dc.Rectangle(point.x-5,point.y-5,point.x+5,point.y+5); CView::OnLButtonDown(nFlags, point); }} In continuare vom aduga un Handler pentru WM_RBUTTONDOWN. Se va scrie codul pentru funcia OnRButtonDown, de exemplu se selecta Edit Existing. void CLpoView::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); dc.Ellipse(point.x-20,point.y-20,point.x+20,point.y+20); CView::OnRButtonDown(nFlags, point); }

PROGRAMARE ORIENTAT PE OBIECTE - Laborator

Lucrarea de laborator 14.


Visual C++ MFC

Tratarea evenimentului de deplasare a mouse-ului Informaia de deplasarea mouse-ului poate fi utilizat n aplicaii prin intermediul mesajului WM_MOUSEMOVE. Adugarea unei funcii de tratare pentru acest mesaj se face la fel cu tratarea butoanelor mouse-ului. Execiiu 1 Realizai o aplicaie care afieaz poziia cursorului n timpul deplasrii mouse-ului. Pentru a realiza aplicaia vom aborda urmtoarea opiune de generare a programului schelet : 1. Scriem numele proiectului; 2. Alegem Dialog based (SDI) i apsm Finish 3. Se terge Butonul CANCEL i caseta TODO vizualizate n ResourceView 4. Pe clasa CxxxxDlg se face clic dreapta i se selecteaz Add Windows Messages Handler. 5. Se va selecta WM_MOUSEMOVE i se va aduga un Handler . 6. n continuare se va scrie codul pentru funcia OnMouseMove(), de exemplu se selecta Edit Existing. void CLpo14Dlg::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CString strMessage; strMessage.Format("Pozitia Mouse = (%d,%d)", point.x, point.y); SetWindowText(strMessage); // memoreaza punctul si redesenam fereastra m_ptMouse=point; Invalidate(); CDialog::OnMouseMove(nFlags, point); }

PROGRAMARE ORIENTAT PE OBIECTE - Laborator Parametrul point reprezint poziia mouse-ului. Apelul funciei Invalidate() foreaz redesenarea ferestrei. Punctul a fost memorat n variabila m_ptMouse. Aceast variabil trebuie declarat. Declararea se va realiza astfel. Pe clasa CxxxxDlg se face clic dreapta i se selecteaz Add Member Variable. Se va scrie tipul variabilei CPoint i numele variabilei m_ptMouse, se va lsa opiunea implicit PUBLIC i se va da OK. Exerciiu 2. Creai un program care s deseneze o pereche de ochi care urmresc poziia cursorului. Acest lucru se poate realiza dac n funcia de tratare OnPaint() vom introduce codul care sa utilizeze poziia mouse-ului i s deseneze perechea de ochi care urmresc poziia cursorului. Funcia OnPaint se gsete n clasa CxxxxDlg. n aceast funcie n codul existent dup else se introduce urmtorul cod: else { //se creeaza un context dizpozitiv pentru desenare CPaintDC dc(this); // se determina dimensiunea casetei de dialog CRect rcDlg; GetClientRect(&rcDlg); // facem un ciclu pentru cei doi ochi for(int i=0;i<2;i++) {//se determina centrul ochiului CPoint ptEye=rcDlg.CenterPoint(); // se stabileste pozitia pentru fiecare ochi ptEye.x+=i==0?-80:+80; //cream un un dreptunghi pentru ochi CRect rcEye(ptEye, ptEye); rcEye.InflateRect(40,60); //Desenam ochiul cu albastru si definim o culoare CBrush brBlue(RGB(0,150,255)); dc.SelectObject(&brBlue); dc.Ellipse(rcEye); rcEye.DeflateRect(20,40); //se deseneaza pupila in functie de pozitia mouse-ului CPoint ptRel=m_ptMouse-rcEye.CenterPoint(); double dX=(double)ptRel.x*(rcEye.Width()/(double)rcDlg.Width()); double dY=(double)ptRel.y*(rcEye.Height()/(double)rcDlg.Height()); // ajustam pozitia ouoilei si o desenam rcEye.OffsetRect(CPoint((int)dX, (int)dY)); dc.SelectStockObject(BLACK_BRUSH); dc.Ellipse(rcEye); } CDialog::OnPaint();

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