Laboratoare Poo

download Laboratoare Poo

of 54

description

poo

Transcript of Laboratoare Poo

  • PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

    Lucrarea de laborator 1.

    SSIISSTTEEMMUULL DDEE IINNTTRRAARRII//IIEESSIIRRII DDEE BBAAZZAA DDIINN CC++++

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

    . 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

  • PROGRAMAREA ORIENTAT PE OBIECTE - Laborator Exerciiu 1: Citii trei valori float, calculai media lor i afiai-o.

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

  • 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 #include void main() { cout.width(10); //latimea cmpului de 10 cout

  • PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

    // utilizare manipulatori cout

  • PROGRAMAREA ORIENTAT PE OBIECTE - Laborator

    Lucrarea de laborator 2.

    SSIISSTTEEMMUULL DDEE IINNTTRRAARRII//IIEESSIIRRII DDEE BBAAZZAA DDIINN CC++++ UUttiilliizzaarree mmaanniippuullaattoorrii

    UUttiilliizzaarreeaa mmaanniippuullaattoorriilloorr ppeennttrruu ffoorrmmaattaarreeaa iieeiirriilloorr 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

  • 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

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

    CCrreeaarreeaa ccllaasseelloorr ii lluuccrruull ccuu oobbiieeccttee nn CC++++ 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 (strada-

    nr),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 ntr-

    un 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

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

    VViissuuaall CC++++66..00 MMFFCC DDeesseennaarreeaa ii aaffiiaarreeaa iimmaaggiinniilloorr

    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 propriu-zise 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;iGetNr();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.

    VViissuuaall CC++++66..00 MMFFCC

    DDeesseennaarreeaa ii aaffiiaarreeaa iimmaaggiinniilloorr ffoolloossiinndd ccoonntteexxttee ddee ddiissppoozziittiivv

    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;iReleaseDC(pDC);

  • PROGRAMAREA ORIENTAT PE OBIECTE - Laborator }

    UUttiilliizzaarreeaa ccoonntteexxtteelloorr ddiissppoozziittiivv cclliieenntt -- CCCClliieennttDDCC

    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;xtop;ybottom;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.

    CCoonntteexxttee ddiissppoozziittiivv ddee mmeemmoorriiee -- CCDDCC 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

  • Programare orientat pe obiecte

    Lucrarea de laborator 7.

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

    11..11..11 BBaarree ddee ccoonnttrrooll 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.

    11..11..22 BBaarree ddee ssttaarree 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.

    11..11..33 AAdduuggaarreeaa uunnuuii iiddeennttiiffiiccaattoorr nnoouu

    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.

    11..11..44 DDeeffiinniirreeaa ccrroonnoommeettrruulluuii ii aa ssttiilluurriilloorr ddee ppaannoouurrii 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

    1

    Lucrarea de laborator 8.

    Realizarea unui cronometru

    Urmndpascupasindicaiiledinaceastlucrarerealizaiuncronometrucupreciziadeosecund.

    Primaaciunevaficreareaaplicaieistandard.Adouavaficreareaelementelordeinterfa(doubutoaneiocasetdeeditare).Atreiavafiintroducereavariabilelorglobaleiacoduluidefuncionareefectivacronometrului.nfinalfereastradeaplicaievaartacamaijos:

    Creareaaplicaieistandard

    DacpnacumamfostobinuiicuaplicaiiSDI(SingleDocumentInterfaceInterfacuunsingurDocument)aplicaiicustructurrelativcomplex,naceastlucrarevomfolosioaplicaiedetipDialog.PorninddelaopiuneaNewdinmeniulVisualStudiocremunproiectnouprinopiuneaMFCAppWizard(.exe)ialegemlaunuldinpainlocdeSDI,opiuneaDialogBased.OdatcreataplicaiaocompilmiorulmcutastaF5.

  • PROGRAMAREAORIENTATPEOBIECTELaborator

    2

    CreareaelementelordeinterfaUrmtorulpasestetergereabutoanelorOKiCANCELinlocuirealorcuStartiReset.

    Pentru a crea aceste dou butoane folosim paleta cu elemente de interfa. Selectm butonul caelementde interfa i ldepunempe suprafaa ferestreidedialog. Facem clicdreaptapebutonuldepus i accesm opiunea Properties. n cadrul tabului General observm c idul butonului esteIDC_BUTTON1.EsteutilstimacestIDpentruamodificabutonul ntimpulrulriiaplicaiei.ncadrulacestuitabmaiesteiopiuneaCaptionprincareputemspecificatextulscrispebuton.Vommodificaacest text pentru a scrie Start. Repetm operaia cu butonul de Reset. Observm c i se asociazautomatIDulIDC_BUTTON2.

    Cremiocasetdeeditareprinselectareaeidinpalet.OmodificmprinopiuneaPropertiespentruaafiatextulcentrat.AceastopiunesegsetentabulStylemeniulAlignText.

    ncercmsaliniemctmaibineacesteelementede interfa ncadrul ferestrei.Eventual folosim iopiuniledemeniudealiniereLayout>Align.

    Interconectareaelementelordeinterfa

    Pentruaticumsinterconectmacesteelementedeinterfatrebuiescunoatemoseriedeclase.

    TrebuiescunoatemclaseleCButtoniCEdit,pentruconfigurareaavansataacestorinterfee.

    nplusavemnevoiedeoclasdeiruridecaracterecarespermitformatareaafiriitimpuluiscurs.UncandidatbunesteCString.

    PentruaaveaacceslaceasulsistemuluivomfolosiclasaCTime.

    O funcie important n legarea IDurilorelementelorde interfadecodulaplicaieiesteGetDlgItemprincareplecnddelaIDobinemunpointerlaunobiectconcret.

    inndcontcanumiteelemente trebuiesipstrezevalorile i laprsireadomeniului funcieivatrebuisdeclarmtreivariabileglobalensensuldeafidisponibilencadrulclaseiC###Dlg.

    Unadinacestevariabileestetimp0ncarevompstramomentulncareafostapsatbutonuldeStart.

    Celelaltedousuntstart_ireset_pentruasemnalizastareapornitacronometruluiistareapasagerderesetarealui.Acesteadousuntdetipbool,adicdetiplogic.

    timp0estedetipCTime.

    Pentruaadugaacestevariabile laclas,folosimfereastradevizualizareaclaseloraflatdeobicei nparteastngaferestreimediului deprogramare.FacemclicdreaptapeC###DlgialegemopiuneaAddMemberVariable.ncasetadesusspecificmtipulvariabileiiarnceadejosnumeleei.

    nconstructorulclaseivomintroduceurmtoaresecvendeiniializareavariabilelorstart_ireset_:

    C###Dlg::C###Dlg(CWnd*pParent/*=NULL*/)

  • PROGRAMAREAORIENTATPEOBIECTELaborator

    3

    :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 caredifernfunciedenumeleproiectului.

    Pentruactualizareaconinutului ferestreiestenevoiedeo temporizare.Putemspecificao funciedetratare a temporizrii prin clic dreapta pe numele clasei C###Dlg i alegerea opiuniiAddWindowsMessageHandler.VomalegeWM_TIMER.nmomentulconfirmriivaapreaofuncieOnTimerncarevomintroduceurmtorulcod:

    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);}

  • PROGRAMAREAORIENTATPEOBIECTELaborator

    4

    Observm folosirea clasei CTime cu metodele sale care returneaz orele( GetHour),minutele(GetMinute)sausecundele(GetSecond).PentruaflareatimpuluicurentdefolosetefunciaGetCurrentTime().Seobservcsefacediferenadintreceledoumomentetemporale iseafieazformatatfolosindfunciaFormatcaclaseiCString.SpecificareaformatuluifolosindclasaFormatsefacelafelcalaprintfdeosebireafiindncapsulareaexpresiin_T().

    Seobserv folosirea funcieiGetDlgItem(IDC_###) aceasta returneazunpointer la IDul resurseideinterfa,acesteelementedeinterfapotfiunbuton,ocasetdeeditare,uncombobox,unlistbox,unbitmapetc.Pointerulreturnatfiindunulgeneralvatrebuiprecizat ntreparantezenatura luiexemplu(CEdit*).Seobservcsedeclarunpointerlaobiectinuunobiect,deoareceresursaaredejaalocatspaiudememorie.

    Funcia SetWindowTextmodific textul caseteide editare. Seobserv iniializarea lui timp2 folosindconstructoruliparametrultimp0.

    Pentru a asocia o funcie apsrii butonului Start folosim tabulResourceView, de lng tabul ClassView, expandm ramurile i pe ramura Dialog apsm pe IDD_###_DIALOG. Facem dubluclic pebutonulStartvaapreafunciaOnStart.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;}

  • PROGRAMAREAORIENTATPEOBIECTELaborator

    5

    Pentruainiializatimerulipentruaresetasistemulvomscrieurmtoareleliniinfunciademaijos:BOOLCCrono01Dlg::OnInitDialog(){ CDialog::OnInitDialog(); //Add"About..."menuitemtosystemmenu. //IDM_ABOUTBOXmustbeinthesystemcommandrange. ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOXAppendMenu(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.

    11..11..11 CCoonnttrroolluull ddee ttiipp bbuuttoonn CCBBuuttttoonn 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.

    11..11..22 CCoonnttrroolluull ddee ttiipp ccaasseett ddee eeddiittaarree CCEEddiitt 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.

    11..11..11 CCoonnttrroolluull ddee ttiipp ccaasseett ddee vvaalliiddaarree CCCChheecckkLLiissttBBooxx

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

    11..11..22 CCoonnttrroolluull ttiipp bbuuttoonn rraaddiioo 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.

    11..11..11 CCoonnttrroolluull ddee ttiipp lliissttaa ccoommbboo CCCCoommbbooBBooxx 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.

    11..11..22 CCoonnttrroolluull ddee ttiipp tteexxtt ssttaattiicc:: CCSSttaattiicc 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

    UUttiilliizzaarreeaa ffuunncciiiilloorr ggrraaffiiccee.. 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 }

    DDeesseennaarreeaa uunneeii lliinniiii 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);

    DDeesseennaarreeaa uunneeii lliinniiii ppoolliiggoonnaallee 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;iPolyline(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.

    FFuunncciiii ddee ddeesseennaarree ddee ffiigguurrii uummpplluuttee::

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

    SSeettaarreeaa ccuulloorriiii ii aa ssttiilluulluuii ddee ddeesseennaarree 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.

    CCoonnffiigguurraarreeaa ppeenniieeii

    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;iPolyline(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.

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

    UUttiilliizzaarreeaa iinnttrrrriilloorr ddee llaa mmoouussee ii ttaassttaattuurr

    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

    TTrraattaarreeaa eevveenniimmeennttuulluuii ddee ddeeppllaassaarree aa mmoouussee--uulluuii

    IInnffoorrmmaaiiaa ddee ddeeppllaassaarreeaa mmoouussee--uulluuii ppooaattee ffii uuttiilliizzaatt nn aapplliiccaaiiii pprriinn iinntteerrmmeeddiiuull mmeessaajjuulluuii WWMM__MMOOUUSSEEMMOOVVEE.. AAdduuggaarreeaa uunneeii ffuunncciiii ddee ttrraattaarree ppeennttrruu aacceesstt mmeessaajj ssee ffaaccee llaa ffeell ccuu ttrraattaarreeaa bbuuttooaanneelloorr mmoouussee--uulluuii..

    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