197

Borland C Builder. Ghid de Initiere

Embed Size (px)

DESCRIPTION

Ghid_de_initiere

Citation preview

Page 1: Borland C Builder. Ghid de Initiere
Page 2: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 3 -

Prefaţă

Sistemul Borland C++ Builder (BCB) este unul dintre cele mai moderne şi mai răspîndite sisteme de programare vizuală. El conţine instrumente eficiente de elaborare a aplicaţiilor de tip Windows, client-server etc. Avînd drept limbaj de programare C++ (derivat din limbajul C), este în acelaşi timp unul dintre cele mai potrivite pachete pentru învăţarea programării orientate spre obiecte şi a celei vizuale.

Prezenta lucrare este un ghid de iniţiere în programarea vizuală şi programarea orientată spre obiecte cu ajutorul sistemului BCB. Este structurată în trei capitole, care oferă informaţii de bază şi exemple demonstrative, menite să ilustreze aspectele teoretice.

În capitolul I (denumit „Platforma BCB”) sînt descrise modalităţile de utilizare a componentelor specifice majorităţii aplicaţiilor tip Windows, precum şi algoritmii de elaborare a astfel de aplicaţii (inclusiv a celor de prelucrare a informaţiei grafice).

Crearea şi gestionarea bazelor de date este una dintre cele mai prioritare domenii ale programării. Sistemul Borland C++ Builder conţine un set de utilitare, care permit crearea şi/sau întreţinerea bazelor de date, inclusiv de tip FoxPro, MySQL, Access, Oracle, etc. Algoritmii de lucru cu bazele de date sînt descrişi în capitolul II „Prelucrarea bazelor de date”.

În capitolul III (denumit „Programarea Orientată spre Obiecte cu C++”) sînt explicate caracteristicile limbajului C++ şi mecanismele POO: incapsularea, moştenirea, supraîncărcarea operatorilor, polimorfismul etc. Conştienţi de complexitatea POO, am inclus o serie de coduri de program, care (sperăm) vor ajuta la înţelegerea acestor mecanisme.

Am presupus că cititorul este iniţiat cu un limbaj de programare (preferabil cu C). Chiar dacă nu are o astfel de iniţiere, urmînd consecvent şi consecutiv paragrafele ghidului, el va reuşi să obţine cunoştinţe şi competenţe de elaborare a produselor program de tip Windows.

În variantă de manuscris, lucrarea a fost experimentată pe studenţii Universităţii de Stat din Tiraspol şi ai Colegiului Financiar-Bancar „A. Diordiţa” din Chişinău, care au şi solicitat apariţia ei.

Ea va fi utilă nu doar studenţilor specialităţilor de Informatică, dar şi tuturor celorlalţi interesaţi de programarea modernă.

Autorii

Page 3: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 4 -

Capitolul I Platforma BCB

§ 1. Mediul de dezvoltare integrat BCB

Mediul de dezvoltare BCB include următoarele elemente: Ø Bara de titlu Ø Bara meniului principal Ø Bara de instrumente Ø Paleta cu componente Ø Fereastra formei Ø Bara cu instrumente Ø Object TreeView Ø Object Inspector

După lansarea la execuţie a sistemului BCB apar următoarele ferestre:

Page 4: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 5 -

1. Bara de titlu Bara de titlu afişează numele proiectului curent (Project1) şi numele

programului (C++ Builder 6).

2. Bara meniului principal

Pe bara meniului principal se află următoarele meniuri: a) Meniul File conţine opţiunile: New – deschide o fereastră de dialog pentru adăugarea de ferestre în cadrul proiectului curent sau de creare a unei noi aplicaţii; Open – deschide un fişier sau un proiect; Open Project – deschide o fereastră de dialog pentru încărcarea unui proiect existent; Reopen – deschide un meniu care conţine denumirile proiectelor utilizate anterior; Save – salvează fişierul curent; Save As – salvează fişierul curent sub un nume nou; Save Project As – salvează proiectul curent sub un nume nou; Save All – salvează toate fişierele deschise; Close – închide proiectul curent şi toate fişierele asociate acestui proiect; Close All – închide toate fişierele deschise; Include Unit – adaugă unit-ul selectat la clauza Uses a unit-ului activ; Print – tipăreşte fişierul curent; Exit – închide proiectul curent şi părăseşte mediul BCB. b) Meniul Edit se utilizează pentru a manipula texte sau componente în timpul creării programului şi conţine opţiunile: Undo/Undelete – anulează ultima acţiune sau ultima ştergere; Redo – anulează ultima operaţie Undo; Cut – mută obiectul selectat pe masa de montaj (în Clipboard); Copy – copiază obiectul selectat în Clipboard; Paste – copiază conţinutul mesei de montaj în poziţia cursorului; Delete – şterge obiectul selectat; Select All – selectează toate componentele de pe formă (machetă, fereastră); Align to Grid – aliniază componentele selectate la cel mai apropiat punct din grilă; Bring to Front – mută componenta selectată în faţă; Send to Back – mută componenta selectată în spate; Align – aliniază componentele;

Page 5: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 6 -

Size – redimensionează componentele selectate; Scale – redimensionează proporţional toate componentele de pe formă; Tab Order – modifică ordinea în care se sare apăsînd tasta Tab; Creation Order – modifică ordinea în care sînt create componentele nevizuale; Flip Children – mută obiecte simetric faţă de axa de simetrie verticală a ferestrei; Lock Controls Secures – „înţepeneşte” toate componentele în poziţiile curente (dacă această opţiune este activată, atunci poziţiile componentelor nu pot fi modificate). c) Meniul Search se utilizează pentru a căuta texte, obiecte, erori, unit-uri, variabile şi simboluri în editorul de cod (fereastra în care se editează codul), prin intermediul următoarelor opţiuni: Find – caută un text specificat şi marchează prima apariţie a acestuia în editorul de cod; Find in Files – caută textul specificat şi afişează fiecare potrivire în fereastra aflată sub editorul de cod; Replace – caută textul specificat şi-l înlocuieşte cu un altul; Search Again – repetă ultima căutare; Incremental Search – caută textul pe măsură ce este scris; Go to Line Number – mută cursorul la linia specificată. d) Meniul View se utilizează pentru a afişa sau pentru a ascunde diverse elemente ale sistemului BCB, conţinînd următoarele opţiuni: Project Manager – afişează managerul de proiect (acesta poate fi utilizat pentru a naviga prin fişierele proiectului, pentru a le copia, şterge, adăuga, salva); Translation Manager – afişează managerul pentru traduceri; Object Inspector – afişează Inspectorul de obiecte; Object TreeView afişează fereastra Object TreeView; To-Do List – face vizibilă lista cu evenimentele care urmează a fi realizate; Alignment Palette – afişează o fereastră în care se găsesc opţiuni destinate alinierii obiectelor; Code Explorer – face vizibil editorul de cod; Component List – afişează o listă cu toate componentele BCB; Window List – face vizibilă o listă cu toate ferestrele BCB care sînt deschise; Debug Windows – afişează un meniu din care pot fi alese ferestrele necesare pentru depănarea programului; Desktops – permite afişarea, salvarea sau ştergerea modurilor de aşezare a ferestrelor; Toggle Form/Unit – comută între fereastră şi unit-ul corespunzător;

Page 6: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 7 -

Units – afişează o listă cu toate unit-urile proiectului; Forms – afişează o listă cu toate formele proiectului; Type Library – afişează editorul pentru biblioteci de tipuri (Type Library); New Edit Window – deschide încă o fereastră pentru editarea de cod; Toolbars – conţine un meniu din care pot fi selectate barele de butoane care vor fi afişate. e) Meniul Project este utilizat pentru a compila o aplicaţie. El conţine următoarele opţiuni: Add to Project – adaugă un fişier proiectului; Remove from Project – elimină un fişier din proiect; Import Type Library – afişează o listă cu bibliotecile înregistrate în sistem pentru a fi adăugate la proiect; Add to Repository – afişează o casetă de dialog pentru a salva un şablon de proiect; View Source – afişează sursa proiectului; Languages – permite adăugarea, eliminarea sau reînnoirea bibliotecilor DLL pentru alfabetul utilizat; Add New Project – adaugă la proiect o nouă aplicaţie; Add Existing Project – adaugă la proiect un proiect existent; Compile Uni t– compilează unit-ul curent; Make Project – creează proiectul, adică fişierul executabil ( implicit Project1.exe); Build project – compilează toate modulele proiectului; Information for project – afişează informaţii despre proiectul compilat; Make All Projects – compilează fişierele care au fost modificate; Build All Projects – compilează toate fişierele proiectului curent; Options – afişează o fereastră de dialog, prin intermediul căreia pot fi modificate opţiunile pentru compilare, linkeditare etc. f) Meniul Run conţine comenzi pentru executarea, depănarea şi oprirea unei aplicaţii: Run – compilează şi execută aplicaţia; Attach to Process – afişează o listă cu procesele care pot fi depănate; Parameters – specifică parametrii cu care va fi lansată în execuţie aplicaţia; Register ActiveX Server – adaugă o intrare în regiştrii Windows-ului pentru controlul elementelor ActiveX; Unregister ActiveX Server – şterge intrarea în regiştrii Windows-ului pentru controlul elementelor ActiveX; Install MTS Object – instalează obiectele MTS (Microsoft Transaction Server) din proiectul curent într-un pachet MTS;

Page 7: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 8 -

Step over – execută un program linie cu linie, fără verificarea funcţiilor; Trace Into – execută un program linie cu linie cu verificarea funcţiilor; Trace to Next Source – execută un program, oprindu-se la următoarea linie executabilă din program; Run To Cursor – execută programul curent pînă la poziţia cursorului din editorul de cod; Run Until Return – execută procesul pînă la ieşirea din funcţia curentă; Show Execution Point – poziţionează cursorul la linia care se execută; Program Pause – opreşte temporar execuţia programului; Program Reset – termină execuţia programului şi eliberează memoria ocupată de către acesta; Inspect – deschide o fereastră pentru analizarea variabilelor specificate; Evaluate/Modify – afişează o fereastră care permite evaluarea sau modificarea unei valori sau a unei expresii; Add Watch – afişează o fereastră pentru urmărirea variabilelor; Add Breakpoint – afişează un meniu folosit pentru adăugarea şi modificarea punctelor de întrerupere. g) Meniul Component conţine comenzi pentru crearea şi instalarea componentelor: New Component – deschide o fereastră, cu ajutorul căreia se pot crea componente noi; Install Component – instalează o componentă existentă; Import ActiveX Control – adaugă o bibliotecă de tip ActiveX; Create Component Template – salvează componentele modificate pe o pagină nouă; Install Packages – instalează un pachet de componente; Configure Palette – deschide o fereastră din care se poate configura paleta de componente. h) Meniul DataBase conţine comenzi pentru manipularea bazelor de date: Explore – lansează la execuţie utilitarul Database Explorer sau SQL Explorer; SQL Monitor – lansează SQL Monitor; Form Wizard – se utilizează pentru crearea rapidă a unor ferestre de vizualizare a bazelor de date. i) Meniul Tools oferă comenzi pentru programele utilitare (disponibile), fără a părăsi sistemul BCB. j) Meniul Window este un meniu de lucru cu ferestre.

Page 8: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 9 -

k) Meniul Help conţine comenzi pentru afişarea aplicaţiilor de tip Help. 3. Bara de instrumente

Bara de instrumente conţine butoane cu rol de acces la unele comenzi

(pot fi accesate prin sistemul de meniuri), care oferă posibilitatea de a adăuga sau a exclude instrumente. 4. Paleta de componente

Paleta de componente este formată din cîteva pagini de componente.

Aceste componente (care mai sînt numite şi controale) urmează a fi plasate pe suprafaţa formei pentru a fi prelucrate. Cele mai utilizate pagini de componente sînt: • Standart conţine controalele cel mai des utilizate; • DataAcces conţine controale pentru stabilirea legăturilor între componente; • DataControls conţine controale pentru prelucrarea bazelor de date (de ex.

pentru afişarea informaţiei dintr-un tabel); • BDE conţine controale ce permit stabilirea unei conexiuni cu baza de date,

prin intermediul tabelelor, interogărilor, etc; • ADO asigură accesul aplicaţiilor client la date.

5. Fereastra formei

Fereastra formei afişează o forma curentă, pe suprafaţa căreia se pot depune controale în perioada de elaborare a proiectului. 6. Fereastra Object TreeView

Object TreeView este o fereastra folosită pentru accesarea rapidă a controalelor de pe suprafaţa unei forme.

Page 9: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 10 -

7. Fereastra Object Inspector

Object Inspector (Inspectorul de obiecte) este o fereastră formată din două pagini: a) Pagina Properties se foloseşte pentru a seta proprietăţile componentelor (dimensiunile, poziţia în cadrul formei, fonturile folosite etc). De asemenea, proprietăţile pot fi setate în momentul execuţiei programului prin scrierea codului sursă: Nume_Control-> Nume_Proprietate = valoare; b) Pagina Events se utilizează pentru a stabili corespondenţa dintre fiecare eveniment şi subprogramul care descrie “reacţia” aplicaţiei la acest eveniment. Pentru a crea această corespondenţă se execută un double-click în caseta din dreptul numelui evenimentului. Elaborarea unui astfel de subprogram se face în fişiere .cpp şi în fişiere .h. În partea de sus a ferestrei Object Inspector se află o listă derulantă care conţine toate componentele de pe formă împreună cu tipul lor. Observaţie. Prin expresia prelucrarea evenimentului vom înţelege descrierea subprogramului corespunzător acestui eveniment.

Page 10: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 11 -

8. Fereastra editorului de cod

Fereastra editorului de cod se află în spatele formei. În ea se scriu subprogramele de prelucrare a evenimentelor, adică conţinutul fişierului Unit1.cpp. De asemenea, executînd un click pe fila Unit1.h (de pe bara de stare a ferestrei editorului de cod) se poate afişa conţinutul fişierului Unit1.h.

Page 11: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 12 -

§ 2. Structura unei aplicaţii BCB

Un proiect BCB este format din cîteva fişiere (de regulă, ele sînt salvate în acelaşi director).

• Fişerul Proiect1.cpp (asociat funcţiei WinMain a aplicaţiei)

Conţinutul predefinit al acestui fişier este:

#include <vcl.h> #pragma hdrstop USEFORM("Unit1.cpp", Form1); WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TForm1), &Form1); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } catch (...) { try { throw Exception(""); } catch (Exception &exception) { Application->ShowException(&exception); } } return 0; }

El poate fi afişat executînd Project \ View Sourse.

Page 12: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 13 -

• Fişierele Unit1.h, Unit1.cpp, Unit1.dfm (caracteristice unei forme)

a) Fişierul Unit1.h conţine informaţia despre componente şi evenimente (prototipul lor este scris în interiorul clasei). Conţinutul iniţial este: #ifndef Unit1H #define Unit1H //------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components private: // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner); }; //------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //------------------------------------------------------------- #endif

Dacă pe suprafaţa formei vor fi plasate componente sau vor fi prelucrate evenimente, atunci prototipurile lor vor apărea în clasă, protejate la nivel __published.

b) Fişierul Unit1.cpp conţine subprogramele de prelucrare a evenimentelor. Conţinutul inţial: #include <vcl.h> #pragma hdrstop #include "Unit1.h" //------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //-------------------------------------------------------------

Page 13: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 14 -

Funcţia __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner) reprezintă constructorul formei.

Descrierea subprogramelor de prelucrare a evenimentelor se efectuează după această declaraţie. Fiecare dintre aceste subprograme are declarat prototipul în fişierul Unit1.h.

c) Fişierul Unit1.dfm conţine informaţia despre imaginea unei forme.

Conţinutul unei forme fără componente poate arăta astfel:

object Form1: TForm1 Left = 192 Top = 114 Width = 696 Height = 480 Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 end

Fişierul formei nu este un fişier ASCII (deci nu poate fi vizualizat cu un editor de texte obişnuit). Pentru a afişa conţinutul fişierului .dfm se execută comanda View as Text din meniul contextual al formei.

Modificarea formei (redimensionarea, plasarea sau excluderea componentelor pe suprafaţa ei etc.) provoacă modificări în conţinutul fişierului ei. • Fişierul de resurse Proiect1.res conţine informaţia despre resursele utilizate în timpul proiectului (imagini, pictograme etc.). Acest fişier este creat automat de către sistemul BCB. • Fişierul proiectului Project1.bpr include toate fişierele enumerate anterior.

Page 14: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 15 -

§ 3. Aplicaţii de consolă Sistemul BCB oferă posibilitatea elaborării aplicaţiilor de consolă. Pentru a crea o astfel de aplicaţie: 1) Executăm File\New\Other. Apare fereastra New Items:

2) Efectuăm un double-click pe pictograma Console Wizard. Apare fereastra Console Wizard:

3) Selectăm limbajul de programare (C sau C++) şi executăm Ok. 4) Apare fereastra editorului de cod (Unit1.cpp) în care scriem codul de program:

Page 15: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 16 -

5) Apăsînd tasta F9 compilăm şi executăm programul. Exemplu rezolvat

Să elaborăm o aplicaţie de consolă care va citi de la tastatură două numere întregi, apoi va afişa la consolă suma acestor numere. Realizare: 1) Executăm File\New\Other. 2) Efectuăm un double-click pe pictograma Console Wizard. 3) În fereastra apărută (Console Wizard) selectăm limbajul de programare (C sau C++) şi executăm Ok. 4) În fereastra editorului de cod (Unit1.cpp) scriem programul:

Page 16: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 17 -

5) Apăsăm F9 pentru compilarea şi executarea programului. 6) Apare fereastra consolei, în care introducem date, iar programul afişează rezultatele:

Page 17: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 18 -

§ 4. Generalităţi

Structura unei clase C++ Builder nu se deosebeşte esenţial de structura unei clase C++.

În C++ Builder apare un nou modificator de acces: __published. La acest nivel de protecţie sînt declarate prototipurile controalelor şi evenimentelor.

Tipul __fastcall este creat în special pentru prelucrarea evenimentelor. În general sistemul BCB operează cu pointeri, din această cauză

proprietăţile şi metodele unui obiect sînt apelate prin intermediul operatorului săgeată: „->”. În cazul în care acestea nu sînt de tip pointer, ele sînt apelate prin intermediul operatorului punct: „.” (pentru detalii vezi capitolul III).

După elaborarea unei aplicaţii este creat fişierul final (Project1.exe). Pentru ca aplicaţia BCB să se lanseze la execuţie fără erori pe o staţie care nu are instalat sistemul BCB la salvarea proiectului final se vor efectua următoarele modificări:

1) Din meniul Project deschidem ferastra Options. 2) Alegem paleta Packages şi scoatem bifa casetei de validare Build

with runtime Packages.

Page 18: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 19 -

3) Din cadrul paletei Linker scoatem bifa casetei de validare Use dynamic RTL.

4) Din cadrul paletei Compiler efectuăm un click pe butonul Realease.

Page 19: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 20 -

§ 5. Clasa TForm O aplicaţie Windows este formată din ferestre, dintre care una este

considerată fereastră principală (implicit prima fereastră este principală). În C++ Builder ferestrele sînt descrise în clasa TForm, din care cauză ele mai sînt numite forme (sau machete).

Pa bara de titlu a formei se află titlul ei, butoanele de minimizare, de maximizare, de închidere şi meniul principal (dacă acesta există).

Pe suprafaţa zonei client a formei programatorul poate plasa componente. Pentru a prelucra o formă trebuie să cunoaştem proprietăţile, metodele şi evenimentele clasei TForm. Menţionăm că multe dintre aceste proprietăţi şi evenimente există şi pentru clasele corespunzătoare altor componente.

Unele proprietăţi ale formei § Action este utilizată pentru centralizarea răspunsurilor la comenzile date de utilizator. Majorităţii componentelor li se poate asocia o acţiune. Acţiunile sînt centralizate şi gestionate folosind componenta ActionList din pagina de componente Standard. § ActiveControl specifică controlul de pe o formă care se află în focar. Valoarea acestei proprietăţi este numele controlului de pe formă aflat în focar. § AutoSroll (de tip logic) stabileşte dacă bara de rulare va apărea (pentru valoarea true) sau nu va apărea automat în cazul în care componentele nu vor “încăpea” pe formă. § AutoSize (de tip logic) permite (pentru valoarea false) sau interzice redimensionarea formei. În cazul valorii true forma automat capătă dimensiunile necesare. § BorderIcons este o proprietate compusă formată din subproprietăţile biSystemMenu, biMinimize, biMaximize, biHelp (toate de tip logic). Precizează dacă forma va avea (pentru valoarea true) sau nu va avea respectiv meniu principal, butoane de minimizare, de maximizare şi buton pentru apelarea unui ajutor (butonul apare doar dacă sînt excluse butoanele de minimizare şi de maximizare). Valorile posibile:

- biSystemMenu (forma are un meniul de System, cu ajutorul căruia forma poate fi închisă, maximizată, minimizată etc.);

- biMinimize (forma are un buton de minimizare); - biMaximize (forma are un buton de maximizare); - biHelp (forma are un buton de help, care are desenat pe el un semn de

Page 20: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 21 -

întrebare); § BorderStyle specifică stilul chenarului formei. Valorile posibile:

- bsDialog (forma nu poate fi redimensionată, chenarul ei fiind standard);

- bsSingle (forma nu poate fi redimensionată, marginile chenarului sînt linii);

- bsNone (forma nu poate fi redimensionată, nu are chenar); - bsSizeable (forma poate fi redimensionată); - bsToolWindow (la fel ca bsSingle, doar cu un titlu mai mic); - bsSizeToolWin (la fel ca bsSizeable, doar cu un titlu mai mic).

§ BorderWitdh indică distanţa în pixeli dintre zona client şi marginile formei. § Caption specifică titlul ferestrei (textul care apare pe bara de titlu). § Color stabileşte culoarea formei. § Constrains este o proprietate compusă formată din subproprietăţile MaxWidth, MaxHeight, MinWidth, MinHeight. Indică restricţii asupra dimensiunilor formei. Dacă toate cele 4 proprietăţi au valoarea 0, atunci restricţii nu sînt. § Cursor specifică forma mouse-lui. § Font este o proprietate compusă pentru stabilirea mărimii, fontului, efectelor de stil pentru textele de pe formă şi a textelor aferente componentelor de pe formă. § FormStyle stabileşte stilul formei. Valori posibile:

- fsNormal (formă obişnuită); - fsMDIChild (formă de tip MDI copil); - fsMDIForm (formă de tip MDI părinte); - fsStayOnTop (formă afişată pe Desktop, deasupra celorlalte forme).

§ Heitch specifică înălţimea în pixeli a formei. § Hint specifică textul care va apărea la plasarea cursorului de mouse pe formă. Acest text apare numai în cazul în care proprietatea ShowHint are valoarea true. § ModalResult este utilizată pentru o formă modală. Aplicaţia principală nu “reacţionează” la evenimente atît timp cît este deschisă o fereastră modală. Prin această proprietate se poate gestiona modul în care a fost închisă fereastra modală. Din această cauză ea nu apare în lista de proprietăţi din fereastra Object Inspector. § Name stabileşte numele formei (utilizat pe post de identificator al formei). § Position specifică dimensiunile şi poziţia pe care o va avea o formă pe ecran. Valorile posibile:

- poDesigned (forma apare pe ecran în aceeaşi poziţie şi aceleaşi dimensiuni ca şi cele setate la proiectarea ei);

- poDefault (sistemul Windows alege poziţia şi dimensiunea formei);

Page 21: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 22 -

- poDefaultPosOnty (sistemul Windows alege doar poziţia formei, dimensiunile fiind cele setate la proiectare);

- poDefaultSizeOnty (sistemul Windows alege doar dimensiunile formei, poziţia rămînînd cea de la proiectare);

- poScreenCenter (forma apare centrată pe ecran, dimensiunile fiind cele setate la proiectare). § Visible (de tip logic) specifică dacă forma este (pentru valoarea true) sau nu este vizibilă. § Width specifică lăţimea în pixeli a formei. Unele metode ale formei § Bringtofront() aduce forma în faţă. § Close() închide forma. § Hide() ascunde forma. § Refresh(), Repaint() redesenează forma. § Sendtoback() trimite forma în spatele tuturor ferestrelor afişate pe ecran. § Setfocus() selectează un control de pe formă. § Show() face vizibilă forma. Unele evenimente ale formei Notă. Prezentăm şi prototipul metodei care prelucrează evenimentul. § OnActivate apare atunci cînd forma devine activă. void __fastcall TForm1::FormActivate(TObject *Sender) § OnCanResize apare atunci cînd se redimensionează forma. void __fastcall TForm1::FormCanResize(TObject *Sender, int &NewWidth, int &NewHeight, bool &Resize) § OnClick apare atunci cînd utilizatorul execută un click de mouse pe formă. void __fastcall TForm1::FormClick(TObject *Sender) § OnClose apare la închiderea formei. void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

Page 22: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 23 -

§ OnCreate apare la crearea formei. void __fastcall TForm1::FormCreate(TObject *Sender) § OnDblClick apare atunci cînd utilizatorul execută double click pe formă. void __fastcall TForm1::FormDblClick(TObject *Sender) § OnDeactivate apare cînd forma pierde focarul. void __fastcall TForm1::FormDeactivate(TObject *Sender) § OnDestroy apare cînd forma este distrusă (la închiderea ei). void __fastcall TForm1::FormDestroy(TObject *Sender) § OnDockDrop apare cînd un obiect este depus pe formă prin operaţia drag-and-dock. void __fastcall TForm1::FormDockDrop(TObject *Sender, TDragDockObject *Source, int X, int Y) § OnDockOver apare cînd un obiect este tras peste formă pentru o operaţie drag-and-dock. void __fastcall TForm1::FormDockOver(TObject *Sender, TDragDockObject *Source, int X, int Y, TDragState State, bool &Accept) § OnDragDrop apare cînd utilizatorul “eliberează” obiectul adus prin operaţia drag-and-drop. void __fastcall TForm1::FormDragDrop(TObject *Sender, TObject *Source, int X, int Y) § OnDragOver apare cînd un obiect este tras peste formă pentru o operaţie drag-and-drop. void __fastcall TForm1::FormDragOver(TObject *Sender, TObject *Source, int X, int Y, TDragState State, bool &Accept) § OnEndDock apare cînd operaţia de tragere s-a terminat. Se utilizează pentru a trata situaţia în care operaţia drag-and-dock s-a terminat.

Page 23: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 24 -

void __fastcall TForm1::FormEndDock(TObject *Sender, TObject *Target, int X, int Y) § OnGetSiteInfo apare înainte de OnDockDrop dacă proprietatea DockSite este true. void __fastcall TForm1::FormGetSiteInfo(TObject *Sender, TControl *DockClient, TRect &InfluenceRect, TPoint &MousePos, bool &CanDock) § OnHelp apare cînd forma primeşte o cerere de ajutor. bool __fastcall TForm1::FormHelp(WORD Command, int Data, bool &CallHelp) § OnHide apare atunci cînd forma este ascunsă (de exemplu dacă proprietatea Visible obţine valoarea false). void __fastcall TForm1::FormHide(TObject *Sender) § OnKeyDown apare la apăsarea unei taste, dacă forma se află în focar. Parametrul Key păstrează codul tastei apăsate. void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) § OnKeyPress apare dacă utilizatorul apasă o tastă care generează un singur caracter. Parametrul Key conţine caracterul tastei apăsate (combinaţiile de taste nu provoacă acest eveniment). void __fastcall TForm1::FormKeyPress(TObject *Sender,char &Key) § OnKeyUp apare la eliberarea unei taste. Parametrul Key păstrează codul tastei apăsate, iar parametrul Shift indică care dintre tastele Shift, Ctrl sau Alt a fost apăsată odată cu tasta Key. void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift) § OnMouseDown apare la apăsarea unui buton al mouse-ului. void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)

Page 24: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 25 -

§ OnMouseUp apare la eliberarea unui buton al mouse-ului. void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) § OnMouseMove apare la mişcarea mouse-ului pe formă. void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) § OnPaint apare atunci cînd forma este redesenată. void __fastcall TForm1::FormPaint(TObject *Sender) § OnResize apare la redimensionarea formei. void __fastcall TForm1::FormResize(TObject *Sender) § OnShortCut apare la apăsarea unei taste înainte de evenimentul OnKeyDown. Se utilizează pentru a trata short-cut-urile înainte de a trata apăsările obişnuite de taste. void __fastcall TForm1::FormShortCut(TWMKey &Msg,bool &Handled) § OnShow apare atunci cînd forma este făcută vizibilă. void __fastcall TForm1::FormShow(TObject *Sender) Exemplu rezolvat

Să creăm o aplicaţie formată dintr-o fereastră (fără componente pe ea). La efectuarea unui click suprafaţa formei va deveni de culoare roşie, iar al apăsarea tastei h titlul ferestrei se va modifica în „Salut! Prima aplicatie BCB”.

Realizare: 1) Executăm File\New\Application. 2) Prelucrăm evenimentul OnClick al formei. Scriem instrucţiunea:

Form1->Color = clRed;

Page 25: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 26 -

3) Prelucrăm evenimentul OnKeyPress al formei. Scriem instrucţiunea: if(Key=='h') Form1->Caption=" Salut! Prima aplicatie BCB";

4) Apăsăm F9 pentru compilarea şi executarea programului.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){} void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key){ if(Key=='h') Form1->Caption="Salut! Prima aplicatie BCB"; } void __fastcall TForm1::FormClick(TObject *Sender){ Form1->Color= clRed; }

Page 26: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 27 -

§ 6. Clasa TButton Butoanele sînt, probabil, cele mai des utilizate controalele în BCB. Ele sînt destinate lansării la execuţie a diferitor acţiuni. Unele proprietăţi ale clasei TButton § Default (de tip logic) stabileşte dacă butonul de comandă este (pentru valoarea true) sau nu este buton implicit al formei. Dacă butonul este implicit, atunci acţionarea tastei Enter va fi considerată eveniment al butonului, în caz contrar – al formei. Forma poate avea un singur buton implicit. § Cancel (de tip logic) stabileşte dacă butonul de comandă este (pentru valoarea true) sau nu este buton de anulare al formei. Dacă butonul este de anulare, atunci acţionarea tastei Esc va fi considerată eveniment al butonului, în caz contrar – al formei. Forma poate avea un singur buton de anulare.

Observaţie. Butonul de anulare nu închide forma. Aceasta poate vi închisă cu o instrucţiune de forma Form1->Close(); § Name specifică numele butonului. § Caption stabileşte textul care va fi afişat pe suprafaţa butonului. § Font este o proprietate compusă pentru stabilirea mărimii literelor, fontului, efectelor de stil pentru textul de pe suprafaţa butonului. § Visible (de tip logic) stabileşte dacă butonul este (pentru valoarea true) sau nu este vizibil pe suprafaţa formei. § ModalResult se foloseşte în cazul ferestrelor modale. Valori posibile: mrNone (valoare implicită), mrOk, mrCancel, mrAbort, mrRetry, mrIgnore, mrYes, mrNo.

§ 7. Clasa TEdit Un exemplar al clasei TEdit afişează o casetă de editare în care utilizatorul poate scrie un text sau poate afişa un mesaj. Unele proprietăţi ale clasei TEdit § AutoSize (de tip logic) permite (pentru valoarea false) sau interzice redimensionarea automată a casetei (în cazul în care un eveniment ar modifica

Page 27: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 28 -

mărimea textului din casetă). § Text specifică textul din casetă. § CharCase determină dacă literele textului din casetă vor fi convertite sau nu în majuscule sau minuscule. Valori posibile:

- ecLowerCase (literele vor fi convertite în minuscule); - ecUpperCase (literele vor fi convertite în majuscule); - ecNormal (literele nu vor fi convertite).

§ MaxLength specifică lungimea (numărul de simboluri) maximală a şirului din casetă. Valoarea 0 anulează restricţia pentru lungime. În regim de proiectare înainte de a seta MaxLength conţinutul casetei trebuie golit. § PasswordChar permite organizarea parolelor. Valoarea-simbol a acestei proprietăţi va apărea în locul oricărui simbol scris de utilizator în casetă. § ReadOnly (de tip logic) interzice (pentru valoarea true) sau permite modificarea textului din casetă. Unele metode ale clasei TEdit § Clear() şterge textul din casetă. § ClearSelection() şterge textul selectat din casetă. § ClearUndo() anulează metoda Undo(). § CopyToCliboard() copie textul selectat din casetă pe masa de montaj. § CutToCliboard() mută textul selectat din casetă pe masa de montaj. § PasteFromCliboard() plasează conţinutul mesei de montaj în casetă. § SelectAll() selectează textul din casetă. Exemplu rezolvat

Să creăm o aplicaţie, a cărei fereastră va conţine două casete de editare (componente de tip TEdit) şi două butoane de comandă (Copy şi Codifică). Utilizatorul va scrie un text în prima casetă, apoi după efectuarea unui click pe butonul Copy textul din prima casetă va fi copiat în caseta a doua. La efectuarea unui click pe butonul Codifică textul din caseta a doua va fi “codificat”.

Realizare: 1) Executăm File\New\Application. 2) Plasăm componentele conform enunţului.

Page 28: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 29 -

3) Modificăm valorile proprietăţilor Caption ale butoanelor de comandă conform enunţului. 4) Prelucrăm evenimentele OnClick ale butoanelor de comandă. 5) Lansăm aplicaţia le execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::Button1Click(TObject *Sender) { Edit2->Text = Edit1->Text; } void __fastcall TForm1::Button2Click(TObject *Sender){ Edit2->PasswordChar = '#'; }

§ 8. Clasa AnsiString În limbajul C++ nu există un tip de date şir de caractere, cum ar fi tipul

string în Pascal. Prelucrarea şirurilor de caractere în C++ se face prin intermediul tablourilor de tip char, care sînt numite şi şiruri de caractere. Mediul C++ Builder moşteneşte toate facilităţile oferite de limbajele C şi C++ referitoare la lucrul cu şiruri de caractere.

Page 29: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 30 -

Funcţiile care implementează lucrul cu aceste şiruri de caractere sînt definite în unit-ul string.h.

AnsiString este o clasă care implementează şirul lung de caractere. AnsiString-urile sînt şiruri pentru care primul caracter are număr de ordine 1. Subprogramele pentru prelucrarea şirurilor de tip AnsiString sînt definite în unit-ul dstring.h al bibliotecii vcl.

Unele metode ale clasei AnsiString § Constructorul AnsiString() creează un şir vid. § AnsiString (valoare) transformă valoare în şir de caractere şi returnează acest şir. Parametrul valoare poate fi de orice tip. § Delete (I, N) şterge N caractere începînd cu poziţia I. § Insert (S, I) inserează şirul de caractere S pe poziţia I în şirul obiectului curent. § Length() returnează lungimea şirului. § SetLength (newLength) trunchiază şirul la lungimea newLength. Dacă lungimea şirului este mai mică decît newLength, atunci şirul nu este trunchiat. § LowerCase () converteşte în minuscule literele şirului. § UpperCase ()converteşte în majuscule literele şirului. § Pos (subStr) returnează poziţia primei apariţii a şirului subStr în şirul obiectul curent. § SubString (I, N) returnează un subşir de lungime N care începe de pe poziţia I. § ToDouble() converteşte şirul la o valoare reală (tip double). Dacă şirul nu poate fi convertit, atunci este generată o excepţie. § ToInt () converteşte şirul la o valoare întreagă. De exemplu, expresia Edit1->Text.ToInt() returnează un număr întreg – conţinutul casetei Edit1 (evident dacă acesta este număr). § CompareStr (S1, S2) returnează: - o valoare negativă dacă şirul S1 este mai mic (lexicografic) decît şirul S2; - 0 dacă şirurile sînt egale; - o valoare pozitivă dacă şirul S1 este mai mare decît şirul S2. § CompareText (S1, S2) este similară funcţiei CompareStr doar că la comparare nu face distincţie între literele mari şi între cele mici. § AnsiPos (Sub, S) returnează poziţia începînd cu care şirul Sub apare în şirul S. Dacă Sub nu apare în S, atunci funcţia returnează valoarea 0. § Trim(S) elimină spaţiile de debut şi cele de sfîrşit ale şirului S.

Observaţie. Cu toate că tipul char şi tipul AnsiString definesc şiruri de

Page 30: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 31 -

caractere, ele nu sînt compatibile. Valorile casetelor de editare sînt de tipul AnsiString. Operatori aplicabili asupra şirurilor de caractere § Operatorul + se foloseşte pentru concatenarea şirurilor. § Operatorul = se foloseşte pentru atribuirea unei valori unei variabile. § Operatorii < (mai mic), <= (mai mic sau egal), >(mai mare), >= (mai mare sau egal), = = (egal), != (diferit) sînt operatorii de comparare.

§ 9. Clasa TLabel

O componentă de tip TLabel afişează o etichetă, care se utilizează pentru afişarea textelor. Texul poate poate fi specificat atît în perioada de elaborare a proiectului, cît şi în timpul execuţiei, prin intermediul proprietăţii Caption. Multe dintre proprietăţile controlului Label coincid cu proprietăţile controalelor studiate.

Unele proprietăţi specifice clasei TLabel § Alignment stabileşte modul de aliniere pe orizontală a textului aferent etichetei. Valori posibile: taLeftJustify, taRightJustify, taCenter. § AutoSize (de tip bool) permite (pentru valoarea false) sau interzice redimensionarea automată a etichetei. § ShowAccelChar (de tip bool) specifică dacă caracterului „&” va determina (pentru valoarea true) sau nu un caracter accelerator (caracterul accelerator este afişat subliniat). Dacă utilizatorul acţionează tasta corespunzătoare caracterului accelerator, atunci focarul va ajunge la componenta specificată de proprietatea FocusControl a etichetei. Aceasta permite transferarea rapidă a focarului la componentele care au proprietatea Caption. În cazul valorii false, caracterul „&” va fi afişat ca atare, iar proprietatea FocusControl a etichetei nu va putea fi utilizată. § Transparent (de tip bool) specifică dacă componenta este sau nu transparentă. În cazul valorii true, componenta va fi transparentă, astfel încît, de exemplu, o imagine grafică situată sub componentă nu va fi acoperită.

Page 31: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 32 -

§ FocusControl stabileşte componenta care va fi activă atunci cînd va fi apăsată tasta corespunzătoare caracterului accelerator (vezi proprietatea ShowAccelChar). § Layout stabileşte modul de aliniere verticală a textului afişat de etichetă. Poate avea una din următoarele valori: TlTop (aliniat sus, valoare implicită), TlCenter (aliniat centrat), TlBottom (aliniat jos). § WordWrap (de tip bool) specifică dacă textul etichetei poate fi afişat (pentru valoarea true) sau nu pe mai multe rînduri. În cazul valorii false textul va fi afişat într-o singură linie. Unele metode ale clasei TLabel § Hide() ascunde eticheta de pe suprafaţa formei. § Show() afişează eticheta, dacă ea a fost ascunsă. Evenimentele clasei TLabel § OnMouseEnter apare atunci cînd indicatorul mouse-ului se mută pe etichetă. § OnMouseLeave apare atunci cînd indicatorul mouse-ului „părăseşte” eticheta. Exemple rezolvate 1. Să creăm o aplicaţie care va calcula aria şi perimetrul unui dreptunghi fiind date dimensiunile dreptunghiului.

Realizare: 1) Executăm File\New\Application. 2) Plasăm două componente de tip TEdit (pentru citirea dimensiunilor dreptunghiului), trei de tip TLabel (pentru denumirile dimensiunilor şi pentru afişarea rezultatelor), un buton de comandă. 3) Prelucrăm evenimentul OnClick al butonului de comandă.

Page 32: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 33 -

4) Pentru un design mai atractiv modificăm proprietatea Font a fiecărei componente. 5) Salvăm, apoi lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::Button1Click(TObject *Sender) { double a,b,arie,perimetru; Form1->Caption="DREPTUNGHIUL"; Label3->Caption=""; a=Edit1->Text.ToDouble(); //convertirea din sir in numar b=Edit2->Text.ToDouble(); arie=a*b; perimetru=(a + b)*2; Label3->Font->Color=clRed; Label3->Caption="Aria : "+AnsiString(arie)+" Perimetrul : " + AnsiString(perimetru); }

2. Calculatorul Să creăm o aplicaţie care va efectua operaţii aritmetice cu numere reale, a cărei

Page 33: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 34 -

fereastră va arăta ca în următoarea imagine.

Realizare: 1) Executăm File\New\Application. 2) Plasăm pe formă o casetă de editare, 17 butoane de comandă conform imaginii. 3) Modificăm valoarea proprietăţii Caption a fiecărui buton de comandă şi cea a formei conform imaginii. 4) Atribuim proprietăţii Text a casetei de editare valoare vidă. 5) Prelucrăm evenimentul OnClick al fiecărui buton de comandă (la efectuarea unui click pe unul din butoanele 0 .. 9 este necesară adăugarea valorii butonului în caseta de editare). 6) Deoarece datele iniţiale sînt de tip AnsiString, le vom transforma în număr, le vom prelucra şi apoi le vom transforma înapoi în text pentru a le afişa. Pentru a exclude introducerea datelor greşite din punct de vedere sintactic (se acceptă doar cifre şi caracterul „.”) vom prelucra evenimentul OnKeyPress a casetei de editare. 7) Pentru a interzice scrierea caracterelor în cutia de editare se va seta proprietatea ReadOnly la valoarea true.

Page 34: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 35 -

8) Prelucrăm evenimentul OnCreate al formei. 9) Salvăm şi lansăm aplicaţia la execuţie. Conţinutul fişierului Unit1.cpp #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; AnsiString s=""; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} double eval(AnsiString exp){ AnsiString op="",c=""; double a; int i; for(i=1;i<=exp.Length();i++) { if( exp[i]>='0' && exp[i]<='9' || exp[i]=='.') c=c+exp[i]; else { if(op=='+' || op=='-' || op=='*' || op=='/') { if(op=='+') a=a+c.ToDouble(); if(op=='-') a=a-c.ToDouble(); if(op=='*') a=a*c.ToDouble(); if(op=='/') a=a/c.ToDouble(); op=s[i]; } else { a=c.ToDouble(); op=exp[i]; } c=""; } } if(op=='+') a=a+c.ToDouble(); if(op=='-') a=a-c.ToDouble(); if(op=='*') a=a*c.ToDouble(); if(op=='/') a=a/c.ToDouble(); return a; } void __fastcall TForm1::FormCreate(TObject *Sender){

Page 35: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 36 -

Edit1->Clear(); Edit1->SetFocus(); } void __fastcall TForm1::Button12Click(TObject *Sender){ Edit1->Clear(); Edit1->Text=AnsiString(eval(s)); s=""; Edit1->SetFocus(); } void __fastcall TForm1::Button13Click(TObject *Sender){ Edit1->Clear(); s=s+"+"; Edit1->SetFocus(); } void __fastcall TForm1::Button14Click(TObject *Sender){ Edit1->Clear(); s=s+"-"; Edit1->SetFocus(); } void __fastcall TForm1::Button15Click(TObject *Sender){ Edit1->Clear(); s=s+"*"; Edit1->SetFocus(); } void __fastcall TForm1::Button16Click(TObject *Sender){ Edit1->Clear(); s=s+"/"; Edit1->SetFocus(); } void __fastcall TForm1::Button9Click(TObject *Sender){ Edit1->Text=Edit1->Text+"1"; s=s+"1"; Edit1->SetFocus(); } void __fastcall TForm1::Button10Click(TObject *Sender){ Edit1->Text=Edit1->Text+"0"; s=s+"0"; Edit1->SetFocus(); } void __fastcall TForm1::Button11Click(TObject *Sender){ Edit1->Text=Edit1->Text+"."; s=s+"."; } void __fastcall TForm1::Button5Click(TObject *Sender){ Edit1->Text=Edit1->Text+"5"; s=s+"5"; Edit1->SetFocus(); } void __fastcall TForm1::Button6Click(TObject *Sender){ Edit1->Text=Edit1->Text+"4";

Page 36: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 37 -

s=s+"4"; Edit1->SetFocus(); } void __fastcall TForm1::Button7Click(TObject *Sender){ Edit1->Text=Edit1->Text+"3"; s=s+"3"; Edit1->SetFocus(); } void __fastcall TForm1::Button8Click(TObject *Sender){ Edit1->Text=Edit1->Text+"2"; s=s+"2"; Edit1->SetFocus(); } void __fastcall TForm1::Button1Click(TObject *Sender){ Edit1->Text=Edit1->Text+"9"; s=s+"9"; Edit1->SetFocus(); } void __fastcall TForm1::Button2Click(TObject *Sender){ Edit1->Text=Edit1->Text+"8"; s=s+"8"; Edit1->SetFocus(); } void __fastcall TForm1::Button3Click(TObject *Sender){ Edit1->Text=Edit1->Text+"7"; s=s+"7"; Edit1->SetFocus(); } void __fastcall TForm1::Button4Click(TObject *Sender){ Edit1->Text=Edit1->Text+"6"; s=s+"6"; Edit1->SetFocus(); } void __fastcall TForm1::Button17Click(TObject *Sender){ Edit1->Clear(); Edit1->SetFocus(); } void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key) { switch(Key){ case '.' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' :

Page 37: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 38 -

case '9' : case '0' : Edit1->Text=Edit1->Text+Key;s=s+Key;break; case '+' : Button13Click(Sender);break; case '-' : Button14Click(Sender);break; case '*' : Button15Click(Sender);break; case '/' : Button16Click(Sender);break; case '=' : Button12Click(Sender);break; } }

Page 38: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 39 -

§ 10. Ferestre pentru afişarea mesajelor Cu C++ Builder se pot crea diferite tipuri de ferestre pentru afişarea

mesajelor. • Apelarea funcţiei ShowMessage(S) afişează o fereastră cu mesajul S.

De exemplu, instrucţiunea ShowMessage("Salut!") afişează următoarea fereastră:

• Pentru afişarea ferestrelor cu mesaje de atenţionare, eroare, confirmare

etc. se foloseşte funcţia MessageDlg (S, Tip, LB, N), unde S este mesajul, Tip – tipul messajului, LB – lista de butoane ale ferestrei, iar N – numărul ecranului de ajutor care va fi afişat la solicitare atunci cînd fereastra este activa.

Valorile parametrului Tip sînt mtCustom, mtInformation, mtWarning, mtError, mtConfirmation.

Valorile parametrului LB sînt mbOk, mbCancel, mbYes, mbNo, mbAbort, mbRetry, mbIgnore, mbYesNoCancel, mbOKCancel, mbAbortRetryIgnore.

În cazul valorilor care corespund unui singur buton acestea se scriu după expresia TMsgDlgButtons(). De exemplu, instrucţiunea MessageDlg("Noroc!", mtConfirmation, TMsgDlgButtons()<< mbIgnore << mbNo, 0) afişează următoarea fereastră:

Instrucţiunea MessageDlg("Salut!", mtInformation, mbYesNoCancel, 0) afişează următoarea fereastră:

Page 39: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 40 -

Valoarea returnată de funcţia MessageDlg depinde de modul de închidere a ferestrei şi poate fi una din valorile mrOk, mrCancel, mrYes, mrNo, mrAbort, mrRetry, mrIgnore.

• Funcţia MessageDlgPos (S, Tip, LB, N, X, Y) are efect similar

funcţiei MessageDlg cu deosebirea că fereastra cu mesaje este afişată în poziţia specificată de parametrii X, Y (colţul stînga sus al ferestrei va avea coordonatele (X, Y) în raport cu colţul stînga sus al ecranului).

• Funcţia MessageBox de asemenea se utilizează pentru afişarea

mesajelor. Aşa cum ea face parte din clasa TApplication, pentru apelarea ei se va scrie o instrucţiune de forma Application->MessageBox(S, T, LB), unde S este mesajul, T – titlul ferestrei, iar LB precizează lista de butoane ale ferestrei şi poate fi una din valorile prezentate în următorul tabel:

Valoarea parametrului LB Butoanele ferestrei de dialog MB_ABORTRETRYIGNORE Abort, Retry, şi Ignore. MB_OK OK. MB_OKCANCEL OK şi Cancel. MB_RETRYCANCEL Retry şi Cancel. MB_YESNO Yes şi No. MB_YESNOCANCEL Yes, No, şi Cancel.

Funcţia MessageBox returnează una din valorile IDOK, IDCANCEL, IDABORT, IDRETRY, IDIGNORE, IDYES, IDNO care oferă posibilitatea verificării modului de închidere a ferestrei. De exemplu, instrucţiunea if (Application->MessageBox("Salut !!!", "Exemplu", MB_ABORTRETRYIGNORE)==IDRETRY) ShowMessage("Ati apasat Retry"); afişează următoarea fereastră de dialog:

Page 40: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 41 -

Dacă această fereastră va fi închisă prin tastarea tastei Retry, atunci se va afişa fereastra

§ 11. Ferestre pentru citirea datelor

O aplicaţie C++ Builder poate primi date dintr-o fereastră de introducere a datelor, dintr-un cîmp al unei casete de editare sau dintr-un fişier. Pentru a citi datele dintr-o fereastră de introducere a datelor se utilizează funcţia InputBox sau funcţia InputQuery.

• Funcţia InputBox (S1, S2, S3) afişează o fereastră cu titlul S1, S2 este textul ce comentează introducerea, iar S3 – textul care se află iniţial în fereastră. Dacă utilizatorul va închide fereastra prin apăsarea tastei Ok, atunci rezultatul funcţiei va fi conţinutul casetei de editare din cadrul ferestrei, altfel – valoarea S3. De exemplu, în urma executării instrucţiunii Edit1->Text=InputBox("Date personale", "Scrie virsta", "20");

se va afişa următoarea fereastră:

Page 41: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 42 -

• Funcţia InputQuery (S1, S2, S3) are efect similar funcţiei InputBox cu deosebirea că textul din linia de editare se returnează prin parametrul S3. Valoarea returnată de funcţie este de tip logic şi este true doar în cazul cînd fereastra a fost închisă prin apăsarea tastei Ok. În caz contrar S3 primeşte valoare vidă. De exemplu, în urma executării instrucţiunii if (InputQuery("Date personale", "Numele", S)) Label1->Caption = S; se va afişa următoarea fereastră:

Eticheta Label1 va afişa textul din caseta de editare a ferestrei doar dacă utilizatorul va apăsa butonul Ok.

§ 12. Aplicaţii multiforme. Ferestre modale

• Am menţionat că o aplicaţie Windows este formată din cîteva ferestre, una fiind considerată fereastră principală (implicit prima fereastră este principală). Pentru a crea o aplicaţie multiformă (adică formată din cîteva ferestre) se pot folosi formularele-proiecte MDI (Multiple Document Interface – interfaţă cu documente multiple).

Deci, un proiect MDI este format dintr-o fereastră principală (numită fereastră părinte) şi una sau mai multe ferestre subordonate ferestrei principale (numite ferestre copil) . Fereastra copil se află doar în interiorul ferestrei părinte (nu poate fi deplasată, redimensionată în afara ferestrei părinte).

Tipul ferestrei poate fi specificat cu ajutorul proprietăţii FormStyle, a cărei valori posibile sînt: fsNormal, fsMDIChild, fsMDIForm, fsStayOnTop.

Page 42: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 43 -

Exemplu rezolvat Să creăm o aplicaţie MDI cu 3 ferestre. La efectuarea unui click pe fereastra principală (fereastra părinte), ferestrele subordonate vor fi aranjate una lîngă alta în interiorul ferestrei principale. La efectuarea unui click pe o fereastră subordonată, toate ferestrele vor fi aranjate sub formă de casccadă. Realizare 1) Includem 3 forme în proiect (Form1 – forma principală, Form2 şi Form3 – forme subordonate). 2) Modificăm proprietatea Caption a fiecărei forme ( vezi fig.1). 3) Prelucrăm evenimentul OnClick al fiecărei forme. 4) Salvăm şi lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "Unit2.h" #include "Unit3.h" #pragma package(smart_init)

Page 43: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 44 -

#pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::FormClick(TObject *Sender){ Form2->Top=0; Form2->Left=0; Form2->Width=Form1->Width/2; Form3->Top=0; Form3->Left=Form1->Width/2; Form3->Width=Form1->Width/2; } Conţinutul fişierului Unit2.cpp: #include <vcl.h> #pragma hdrstop #include "Unit2.h" #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm2 *Form2; __fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner){} void __fastcall TForm2::FormClick(TObject *Sender){ Form1->Cascade();} Conţinutul fişierului Unit3.cpp: #include <vcl.h> #pragma hdrstop #include "Unit3.h" #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm3 *Form3; __fastcall TForm3::TForm3(TComponent* Owner): TForm(Owner){} void __fastcall TForm3::FormClick(TObject *Sender){ Form1->Cascade();}

• În timpul execuţiei ferestrele unei aplicaţii pot fi afişate obişnuit sau

exclusiv. În ultimul caz fereastra se numeşte modală. Deci, o fereastră modală este o fereastră care interzice orice acţiune asupra ferestrei principale pînă această fereastră modală nu este închisă. De exemplu, ferestrele de dialog sînt ferestre modale.

Page 44: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 45 -

Pentru a afişa o fereastră în mod exclusiv se apelează metoda ShowModal(). Valoarea returnată de această funcţie stabileşte starea (afişată sau închisă) şi modul de închidere ferestrei. Ea este atribuită automat proprietăţii ModalResult a ferestrei. Valori posibile:

- 0 – fereastra este afişată (valoare implicită); - mrOk – fereastra a fost închisă prin apăsarea butonului OK; - mrCancel – fereastra a fost închisă prin apăsarea butonului Cancel; - mrAbort – fereastra a fost închisă prin apăsarea butonului Abort; - mrRetry – fereastra a fost închisă prin apăsarea butonului Retry; - mrIgnore – fereastra a fost închisă prin apăsarea butonului Ignore; - mrYes – fereastra a fost închisă prin apăsarea butonului Yes; - mrNo – fereastra a fost închisă prin apăsarea butonului No.

Amintim că un buton de comandă, de asemenea, are proprietatea ModalRezult cu aceleaşi valori posibile.

Pentru a afişa o formă în mod obişnuit se va utiliza metoda Show().

Exemplu rezolvat

Să creăm o aplicaţie a cărei fereastră va avea un buton de comandă (cu denumirea Intrare). Butonul va afişa următoarea fereastră modală.

Utilizatorul va scrie în casetele de editare numele si parola. În cazul

scrierii şi confirmării parolei corecte (şirul 123) se va afişa mesajul Corect, iar fereastra aplicaţiei îşi va modifica culoarea. În caz contrar se va afişa mesajul Scrie parola corecta si confirma. Realizare 1) Executăm File\New\Application. 2) Executăm File\New\Form.

Page 45: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 46 -

3) Plasăm pe formă doua două etichete, două casete de editare şi un buton de comandă conform imaginii din enunţ. 4) Modificăm proprietatea Caption a formei Form2, a etichetelor şi a butoanelor de comandă conform enunţului. Proprietăţii ModalResult al butonului Confirma îi atribuim valoarea mrOk. 5) În fişierul Unit1.cpp adăugăm directiva #include "Unit2.h". 6) Prelucrăm evenimentul OnClick al fiecărui buton de comandă. 7) Salvăm şi lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "Unit2.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::Button1Click(TObject *Sender){ Form2->Edit2->Text=""; Form2->ShowModal(); Form2->Edit1->Text=""; if(Form2->Edit2->Text=="123" && Form2->ModalResult==mrOk) {ShowMessage("Corect"); Color=clLime;} else ShowMessage("Scrie parola corecta si confirma");}

Page 46: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 47 -

Conţinutul fişierului Unit2.cpp: #include <vcl.h> #pragma hdrstop #include "Unit2.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm2 *Form2; __fastcall TForm2::TForm2(TComponent* Owner): TForm(Owner){ }

§ 13. Butoane şi cutii de grupare

Să examinăm cîteva clase de componente care se folosesc deseori la

elaborarea unui proiect.

13.1. Clasa TBitBtn Spre deosebire de un buton de comandă obişnuit (de tip TButton), un

obiect de tip TBitBtn este un buton, pe suprafaţa căruia se poate plasa o imagine. Componenta BitBtn se află pe paleta Additional. Unele proprietăţi ale clasei TBitBtn § Glyph specifică imaginea de pe suprafaţa butonului. § Kind indică tipul butonului. § Layout indică amplasamentul imaginii faţă de textul afişat pe buton.

13.2. Clasa TUpDown

Un obiect de tip TUpDown este un buton pentru incrementare şi pentru decrementare. Se poate asocia cu un alt component, de exemplu cu o cutie de editare pentru incrementarea sau decrementarea unei valori numerice. Componenta TUpDown se află pe paleta Win32. Unele proprietăţi ale clasei TUpDown § Associate specifică controlul cu care este asociat butonul de incrementare/decrementare. § AlignButton determină poziţia butonului faţă de controlul asociat (stînga sau dreapta).

Page 47: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 48 -

§ Increment indică cu cîte unităţi se va mări sau se va micşora valoarea iniţială la efectuarea unui click pe una din tastele butonului. Iniţial are valoarea 1. § Orientation specifică orientarea controlului (orizontal sau vertical). § Min specifică valoarea minimală (0 este valoare implicită) a butonului. § Max specifică valoarea maximală (100 este valoare implicită) a butonului. § Position specifică valoarea returnată de buton şi atribuită controlului asociat.

13.3. Clasa TGroupBox

Componenta GroupBox este o cutie de grupare, se află pe paleta Standard şi este utilizată pentru gruparea logică a componentelor de pe suprafaţa unei forme. Are rol de container, în a cărui interior pot fi plasate alte componente. Aceste componente vor aparţine aceluiaşi grup. Între cutie şi componentă se creează o relaţie de tip părinte-copil. În regim de proiectare la deplasarea cutiei se vor deplasa şi toate componentele din interiorul ei.

13.4. Clasa TCheckBox

O componentă de tip TCheckBox afişează un buton de opţiune (se mai spune casetă de validare). De regulă, se utilizează pentru activarea (conectarea, selectarea) sau dezactivarea (deconectarea) unei stări sau a unui regim. Starea selectată se caracterizează prin prezenţa “bifei” în casetă. Componenta CheckBox se află pe paleta Standard. Unele proprietăţi ale clasei TCheckBox § Aligment determină poziţia textului ataşat butonului faţă de acesta. Valori posibile: taRightJustify (dreapta), taLeftJustify (stîngă). § AllowGrayed (de tip bool) permite (pentru valoarea true) sau interzice starea estompată (se mai spune starea gri) a butului de opţiune. În cazul valorii true butonul poate avea trei stări (selectată, neselectată, estompată), altfel – două stări (selectată şi neselectată). § Checked (de tip bool) determină dacă butonul este (pentru valoarea true) sau nu este selectat. § State indică starea butonului. Valori posibile: cbUnchecked (valoare

Page 48: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 49 -

implicită, butonul nu este selectat), cbChecked (butonul este selectat), cbGrayed (butonul se află în stare estompată).

13.5. Clasa TRadioButton Componenta RadioButton se află pe paleta Standard şi afişează un buton

radio, care, în cazul în care este singur, are acelaşi rol ca şi un buton de opţiune. De regulă, butoanele radio se folosesc în grup. La selectarea unui buton din grup celelalte butoane din grup automat devin neselectate. De fapt, pentru a crea grupuri de butoane radio se recomandă utilizarea componentei RadioGroup. Unele proprietăţi ale clasei TRadioButton § Aligment determină poziţia textului ataşat butonului faţă de acesta. § Checked (de tip boolean) determină dacă butonul este sau nu este selectat.

13.6. Clasa TRadioGroup

Componenta RadioGroup se află pe paleta Standard şi afişează un grup de butoane radio. Butoanele unui astfel de grup cooperează: în orice moment de timp se poate selecta doar un singur buton. La selectarea unui buton, celelalte devin neselectate.

Unele proprietăţi ale clasei TRadioGroup § Columns specifică numărul de coloane în care sînt aşezate butoanele grupului. Valori posibile: 1 (valoare implicită), 2, ... 16. § ItemIndex specifică numărul de ordine al butonului radio selectat. Indicele butonului al n-lea este n – 1. Valoarea –1 este implicită şi corespunde situaţiei cînd nu este selectat nici un buton. § Items defineşte numărul şi denumirea butoanelor din grup. Se utilizează ca şi proprietatea Items a componentei Memo. Exemplu rezolvat

Să creăm o aplicaţie care va conţine un grup de butoane radio (componentă de tip TRadioGroup), un buton de opţiune (componentă de tip TCheckBox), trei casete de editare, o etichetă şi un buton de

Page 49: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 50 -

incrementare/decrementare (componentă de tip TUpDown). Ultimul buton va fi asociat casetei Edit3.

La selectarea unui buton radio în caseta Edit1 va apărea numele lui. Un click pe una din tastele butonului de incrementare/decrementare va mări sau va micşora valoarea din caseta Edit3. Caseta Edit2 va afişa starea butonului de opţiune. Realizare 1) Executăm File\New\Other. 2) Plasăm pe formă componentele conform enunţului. 3) Modificăm proprietatea Caption a formei, a etichetei, a butonului de opţiune conform enunţului. Creăm butoanele radio cu ajutorul proprietăţii Items a componentei RadioGroup1. 4) Proprietăţii Asociate a butonului de opţiune îi atribuim valoarea Edit3. 5) Prelucrăm evenimentul OnClick al butonului de opţiune şi cel al componentei RadioGroup1. 6) Salvăm şi lansăm aplicaţia la execuţie.

Page 50: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 51 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::RadioGroup1Click(TObject *Sender){ int nr=RadioGroup1->ItemIndex; Edit1->Text=RadioGroup1->Items->Strings[nr]; } void __fastcall TForm1::CheckBox1Click(TObject *Sender){ if(CheckBox1->Checked==true) Edit2->Text="Bifat"; else Edit2->Text="Nebifat"; }

§ 14. Clasa TMemo O componentă de tip TMemo este o cutie de editare formată din mai multe linii, numită şi zonă de editare.

Numerotarea liniilor zonei începe cu 0. Informaţia din zonă se păstrează în proprietatea Lines (de tipul TStrings). Tipul TStrings descrie o listă de şiruri de caractere. Accesul la linia a n-a a listei se realizează prin construcţia Strings[n-1].

Page 51: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 52 -

TMemo are unele dintre proprietăţi identice cu proprietăţile clasei TEdit: MaxLength, ReadOnly, Text, Name, Color, BorderStyle, Cursor, etc. Unele proprietăţi specifice clasei TMemo § Align stabileşte poziţia zonei pe formă şi poate lua una din următoarele valori:

- alNone – componenta nu-şi va schimba poziţia; - alRight – componenta se va alinia în partea dreaptă a formei; - alLeft – componenta se va alinia în partea stîngă a formei; - alBottom – componenta va fi plasată în partea de jos a formei; - alClient – componenta va ocupa tot spaţiul formei.

§ Aligment stabileşte tipul de aliniere a textului în zonă. § Lines conţine textul din zonă, sub formă de şiruri de caractere. § Scoolbars indică dacă zona are sau nu are bare de defilare. Valori posibile: ssNone, ssHorizontal, ssVertical, ssBoth. § WantReturns (de tip bool) stabileşte dacă utilizatorul poate (pentru valoarea true, valoare implicită) să insereze în zonă sfîrşituri de linii cu ajutorul tastei Enter. În cazul valorii false evenimentul de acţionare a tastei Enter va fi prelucrat de către formă. În acest caz trecerea la linie nouă se realizează prin combinaţia Ctrl + Enter. § WantTabs (de tip bool) stabileşte dacă utilizatorul poate (pentru valoarea true) să insereze în zonă spaţieri cu ajutorul tastei Tab. În cazul valorii false (valoare implicită) la acţionarea tastei Tab se va trece la următoarea componentă de pe formă. În acest caz spaţierile se vor insera prin combinaţia Ctrl + Tab. § WordWrap (de tip bool) stabileşte (pentru valoarea true, valoare implicită) regimul de trecere automat la linie nouă atunci cînd se ajunge la muchia din dreapta a zonei (fără inserarea automată a caracterelor de trecere la linie nouă). Evident, în acest caz bara de defilare orizontală n-are sens.

Clasa TMemo este destinată editării/gestionării textelor, de aceea

pentru prelucrarea informaţiei din zona de editare pot fi utilizate metodele clasei TEdit. În acelaşi timp, graţie proprietăţii Lines (de tip TStrings), de asemenea, pot fi folosite proprietăţile şi metodele clasei TSrings. Unele proprietăţi şi metode ale clasei TStrings

Page 52: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 53 -

§ Count păstrează numărul de şiruri ale zonei de editare. § Strings[i] specifică al i+1 –lea şir al zonei. § SaveToFile (F) salvează lista de şiruri în fişierul cu numele F. § LoadFro1File (F) umple lista cu linii de text din fişierul F. § Add(S) adaugă şir de caractere S la sfîrşitul listei. § Clear goleşte lista de şiruri de caractere. De exemplu, instrucţiunea Memo1->Lines->SaveToFile(“C: \\fis.txt”) salvează conţinutul zonei Memo1 în fişierul fis.txt de pe discul C. Exemplu rezolvat Să elaborăm o aplicaţie care va determina toţi divizorii unui număr natural. Pentru a citi valoarea numărului va fi utilizată o cutie de editare, iar pentru afişarea rezultatului – o zonă de editare. Butonul Determină Divizorii va calcula şi va afişa în zonă divizorii numărului. Butonul Salveaza va salva rezultatul într-un fişier, a cărui nume va fi specificat de utilizator. Realizare: 1) Plasăm controalele necesare pe suprafaţa formei.

2) Prelucrăm evenimentul OnClick al controlului Button1 (fişierul Unit1.cpp) 3) Prelucrăm evenimentul OnClick al controlului Button2 (fişierul Unit1.cpp) 4) Modificăm proprietatea Caption a formei şi a controalelor de pe formă. 5) Salvăm şi lansăm aplicaţia la execuţie.

Page 53: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 54 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; int num; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){ } void __fastcall TForm1::Button1Click(TObject *Sender){ num=Edit1->Text.ToInt(); Memo1->Lines->Add("Divizorii numarului "+AnsiString(num)); AnsiString s=""; for(int i=1;i<=num;i++) if(num%i==0) s=s+AnsiString(i)+" "; Memo1->Lines->Add(s); } void __fastcall TForm1::Button2Click(TObject *Sender){ AnsiString cale; cale=InputBox("Salvare rezultate","Dati calea fisierului",""); Memo1->Lines->SaveToFile(cale); }

Page 54: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 55 -

§ 15. Gestiunea meniurilor

Majoritatea aplicaţiilor Windows conţin meniuri. Deosebim meniuri principale (de regulă, plasate orizontal în partea de sus a ferestrelor aplicaţiei) şi meniuri flotante (care se apelează printr-un click pe butonul drept al mouse-lui).

15.1. Clasa TMainMenu Pentru crearea unui meniu principal se foloseşte componenta MainMenu

(de tip TMainMenu) de pe paleta Standard de componente. Un meniu principal este format din unul sau mai multe elemente de meniu (comenzi), aşezate orizontal pe o bară. Fiecare element de meniu este de tipul TMenuItem, ceea ce înseamnă că unui astfel de element i se poate ataşa o fereastră derulantă. Fereastra derulantă poate conţine unul sau mai multe elemente (aşezate vertical) de asemenea de tip TMenuItem. Fiecărui din aceste elemente i se pot ataşa submeniuri etc.

Algoritmul de creare şi prelucrare a meniului principal

1) Plasăm o componentă MainMenu pe formă. 2) Crearea elementelor de meniu se realizează cu ajutorul utilitarul de proiectare a meniurilor. Pentru a afişa utilitarul de proiectare a meniurilor: - se execută un double-click pe componenta MainMenu (de pe formă) sau - se execută un double-click în caseta de valori a proprietăţii Items a componentei MainMenu sau pe butonul cu trei puncte din această casetă sau - se execută comanda Menu Designer a meniului contextual al contextual al componentei MainMenu.

Trecerea la un subnivel se realizează prin apăsarea tastei Enter sau a combinaţiei de taste Ctrl + tastă-săgeată, sau se execută comanda Insert a meniului contextual al elementului pentru care se doreşte crearea subnivelului.

Fiecare element de meniu apare în lista derulantă a Inspectorului de obiecte. Numele acestui element în mod predefinit este urmat de simbolul 1 (sau de simbolul 2 dacă există deja un astfel de nume etc.).

Page 55: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 56 -

Astfel, un element de meniu are propriile evenimente şi proprietăţi. Dacă o literă L din numele elementului este precedată de simbolul & , atunci elementul respectiv va putea fi selectat (eventual executat) şi prin combinaţia de taste Alt + L. În acelaşi timp, o combinaţie de taste corespunzătoare elementului de meniu (indiferent de prezenţa simbolului & în numele lui) poate fi stabilită prin intermediului proprietăţii ShortCut.

În faţa numelui fiecărui element de meniu poate fi introdusă o imagine (prin intermediul proprietăţii Image).

3) În urma alegerii unui element de meniu se declanşează evenimentul OnClick al acestui element.

15.2. Clasa TPopUpMeniu Componenta PopupMenu (are tipul TPopupMenu) se foloseşte pentru

crearea meniului contextual (se mai spune meniu flotant). Un meniu contextual poate fi afişat prin executarea unui click-dreapta şi apare în poziţia în care se află cursorul de mouse în momentul efectuării acestui click. Unul sau mai multe meniuri flotante pot fi atribuite atît formelor, cît şi componentelor prin intermediul proprietăţii PopupMenu a formei sau a componentei.

Unele proprietăţi şi evenimente specifice componentei PopupMenu

§ Proprietatea Alignment specifică locul în care va apărea meniul contextual faţă de cursorul de mouse (în momentul excutării click-dreapta). Aligment poate lua următoarele valori:

Page 56: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 57 -

- paLeft - meniul va fi afişat în colţul din stînga sus al cursorului de mouse

- paCenter - meniul va fi afişat în centrul marginii de sus al curorului de mouse.

- paRight - meniul va fi afişat în colţul din dreapta sus al cursorului de mouse. § Proprietatea Items este un obiect de tip TMenuItems prin care se definesc

elementele meniului. § Proprietatea PopupComponent stabileşte componenta care este

proprietarul actual al meniului contextual. Se utilizează atunci cînd mai multe componente folosesc acelaşi meniu contextual.

§ Proprietatea AutoPopup (de tip bool) permite (în cazul valorii true) afişarea meniului contextual prin executarea unui click-dreapta asupra componentei-proprietar al acestui meniu. În cazul valorii false meniul va putea fi afişat numai prin program, apelînd metoda Popup a componentei-proprietar. Această metodă permite specificarea poziţiei de ecran în care va apărea meniul.

§ Evenimetul OnPopup se declanşează în momentul în care urmează să fie afişat meniul.

Observaţie. După crearea meniului este obligatoriu ca el să fie asociat unui control (proprietatea PopupMenu a controlului). Exemple rezolvate

1. Să creăm o aplicaţie cu două ferestre. Prima fereastră va avea următoarele meniuri:

Meniul principal Meniul contextual Comanda Forma Noua va afişa fereastra a doua. Comanda Inchide va

închide aplicaţia. Selectarea celorlalte elemente de meniu va modifica corespunzător forma.

Inaltime► 100 200 300

Latime ► 100 200 300

File View Forma Noua

Inchide

Marime► Mica Mijlocie Mare

Culoare ► Verde Rosu Albastru

Page 57: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 58 -

Realizare:

1) Executăm File\New\Application. 2) Executăm File\New\Form. Atribuim proprietăţii Visible a formei Form2 valoarea false. 3) Plasăm componentele MainMenu şi PopupMenu pe formă. 4) Lansăm utilitarul de proiectare a meniurilor executînd un click în caseta de valori a proprietăţii Items a fiecărei componente. Scriem elementele de meniu conform enunţului. 5) Atribuim proprietăţii PopupMenu a formei valoarea PopupMenu1. 6) Prelucrăm evenimentul OnClick al fiecărui element de meniu. 7) Salvăm şi lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: # include "Unit1.h" #include "Unit2.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::FormaNoua1Click(TObject *Sender){ Form2->Show();

Page 58: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 59 -

} void __fastcall TForm1::Inchide1Click(TObject *Sender){ Form1->Close(); } void __fastcall TForm1::Mica1Click(TObject *Sender){ Form1->Width=50; Form1->Height=50; } void __fastcall TForm1::mijlocie1Click(TObject *Sender){ Form1->Width=200; Form1->Height=200; } void __fastcall TForm1::Mare1Click(TObject *Sender){ Form1->Width=400; Form1->Height=400; } void __fastcall TForm1::Verde1Click(TObject *Sender){ Form1->Color=clGreen; } void __fastcall TForm1::Galben1Click(TObject *Sender){ Form1->Color=clRed; } void __fastcall TForm1::Albastru1Click(TObject *Sender){ Form1->Color=clBlue; } void __fastcall TForm1::N1001Click(TObject *Sender){ Form1->Height=100; } void __fastcall TForm1::N2001Click(TObject *Sender){ Form1->Height=200; } void __fastcall TForm1::N3001Click(TObject *Sender){ Form1->Height=300; } void __fastcall TForm1::N1002Click(TObject *Sender){ Form1->Width=100; } void __fastcall TForm1::N2002Click(TObject *Sender){ Form1->Width=200; } void __fastcall TForm1::N3002Click(TObject *Sender){ Form1->Width=300; }

Observaţie. N1001, N2001, N3001 sînt valorile proprietăţilor Name ale elementelor din submeniul Inaltime, iar N1002, N2002, N3002 sînt valorile proprietăţilor Name ale elementelor din submeniul Latime.

Page 59: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 60 -

2. Fiecare rînd al fişierului student.txt conţine informaţia despre studentul unei grupe (numele, prenumele, denumirea grupei şi nota medie).

Să creăm o aplicaţie a cărei fereastră va conţine un meniu principal

pentru prelucrarea informaţiei din fişier. Vom crea clasele student (care va descrie un student) şi lista (care va conţine metode de citire din fişier, de afişare a listei, de filtrare a înregistrărilor după cîmpuri cu valori maxime sau minime). Realizare:

1) Executăm File\New\Application. 2) Plasăm pe formă un meniu principal, o zonă de editare şi o etichetă. 3) Scriem elementele meniului principal:

Afisare Iesire Eminentii Restantierii Toti studentii

4) Modificăm proprietatea Caption a etichetei şi a formei. Definim clasele student şi lista în fişierul Unit1.cpp. 5) Prelucrăm evenimentul OnClick al fiecărui element de meniu. 6) Salvăm şi lansăm aplicaţia la execuţie.

Page 60: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 61 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "fstream.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){ } fstream f("student.txt"); class student{ public: char nume[20], prenume[20], grupa[10]; double media; student *next; student(){next=NULL;} void citire(); AnsiString linie(); }; class lista{ public: student *l,*prim; lista(){prim=NULL;} void creare(); void afisare(); void lenesi(); void eminenti(); ~lista(); }; void student::citire(){f>>nume>>prenume>>grupa>>media;} AnsiString student::linie(){

Page 61: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 62 -

AnsiString s1,s2,s3,s4,sir; int i; s1=AnsiString(nume); for(i=s1.Length();i<21;i++) s1=s1+" "; s2=AnsiString(prenume); for(i=s2.Length();i<21;i++) s2=s2+" "; s3=AnsiString(grupa); for(i=s3.Length();i<16;i++) s3=s3+" "; s4=AnsiString(media); for(i=s4.Length();i<11;i++) s4=s4+" "; sir=s1+s2+s3+s4; return sir; } void lista::creare(){ student *p; while(!f.eof()){ p=new student; p->citire(); if(prim==NULL){prim=l=p;} else{l->next=p;l=p;} } } void lista::afisare(){ l=prim; while(l->next!=NULL){ Form1->Memo1->Lines->Add(l->linie()); l=l->next; } } void lista::lenesi(){ l=prim; while(l->next!=NULL){ if(l->media<=6) Form1->Memo1->Lines->Add(l->linie()); l=l->next; } } void lista::eminenti(){ l=prim; while(l->next!=NULL){ if(l->media>=8.88) Form1->Memo1->Lines->Add(l->linie()); l=l->next; } } lista::~lista(){ while(prim!=NULL){ l=prim; prim=prim->next; delete l; } }

Page 62: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 63 -

lista p; void __fastcall TForm1::Iesire1Click(TObject *Sender){ Application->Terminate(); } void __fastcall TForm1::FormCreate(TObject *Sender){ p.creare(); } void __fastcall TForm1::Totistudentii1Click(TObject *Sender){ Memo1->Clear(); p.afisare(); } void __fastcall TForm1::Studentilenesi1Click(TObject *Sender){ Memo1->Clear(); p.lenesi(); } void __fastcall TForm1::Studentieminenti1Click(TObject *Sender){ Memo1->Clear(); p.eminenti(); } void __fastcall TForm1::Button1Click(TObject *Sender){ Memo1->Clear(); }

Page 63: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 64 -

§ 16. Elemente de grafică

În Borland C++ Builder pentru prelucrarea informaţiei grafice se

folosesc trei tipuri de obiecte: ü Graphics, care există în formă de fişiere sau resurse.

Moştenitoare ale clasei TGraphics sînt clasele TBitmap, TIcon, TMetafile. ü Picture, care reprezintă containere care păstrează obiecte

grafice. De regulă, obiectele de tip TWinControl conţin proprietatea Picture (de tip TPicture)

ü Canvas, care reprezintă o suprafaţă (pînză de desenare) formată din puncte (Bitmapped). Obiectele clasei TCanvas există doar în calitate de proprietăţi ale altor obiecte sau componente. Astfel, componentele Form, Image, PaintBox conţin proprietatea Canvas.

16.1. Unele proprietăţi ale obiectului Canvas

§ Brush (proprietate compusă, de tip TBrush) stabileşte proprietăţile pensulei

utilizate pentru colorarea sau haşurarea interiorului domeniilor. Classa TBrush are următoarele proprietăţi: ü Bitmap conţine modul (în format de biţi) de colorare a domeniului.

Dacă se utilizează această proprietate, atunci nu au efect proprietăţile Color şi Style. În calitate de model de colorare poate fi o imagine.

ü Color stabileşte culoarea pensulei. Valoarea clWhite (alb) este implicită.

ü Handle conţine descrierea pensulei Windows GDI. ü Style determină stilul pensulei. Valori posibile: bsSolid, bsClear,

bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross.

§ ClipRect (de tip TRect, are atributul readonly) determină domeniul

dreptunghiular de pînză care poate fi desenat. În cazul formei acest domeniu coincide cu domeniul client al formei. Tipul TRect este definit astfel:

struct TRect { TRect() {} TRect(const TPoint& TL, const TPoint& BR) { left=TL.x; top=TL.y; right=BR.x; bottom=BR.y; }

Page 64: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 65 -

TRect(int l, int t, int r, int b) {left=l; top=t; right=r; bottom=b;} TRect(RECT& r) { left=r.left; top=r.top; right=r.right; bottom=r.bottom; } } § CopyMode determină regimul de copiere a informaţiei dintr-un obiect de

tip TGraphics. § Font (proprietate compusă) specifică fontul şi stilul textelor care se vor

afişa pe pănză. A se vedea proprietatea Font a formei. § Handle conţine descrierea mecanismului, în baza căruia este construită

pînza. Se foloseşte pentru operaţii de nivel jos. § Pen (proprietate compusă) stabileşte proprietăţile creionului de desenare.

Clasa TPen are următoarele proprietăţi: Color, Handle, Mode, Style, Width. § PenPos (de tip TPoint) specifică coordonatele indicatorului poziţiei

curente. Tipul TPoint se defineşte astfel: struct TPoint { TPoint() {} TPoint(int _x, int _y) : x(_x), y(_y) {} TPoint(POINT& pt) { x=pt.x; y=pt.y; } } § Pixels[X][Y] stabileşte culoarea punctului de coordonate X, Y. § TextAlign stabileşte modul de aliniere a textului care urmează a fi afişat pe

pînză. Valori posibile: taTop, taBottom.

16.2. Unele metode ale obiectului Canvas § Arc (X1, Y1, X2, Y2, X3, Y3, X4, Y4) construieşte un segment de elipsă

înscrisă în dreptunghiul determinat de coordonatele întregi X1, Y1, X2, Y2 şi mărginit de semidreptele cu originea în centrul dreptunghiului şi care trec prin punctele (X3, Y3), (X4, Y4). Se desenează împotriva acelor de ceas.

§ Chord (X1, Y1, X2, Y2, X3, Y3, X4, Y4) construieşte o elipsă înscrisă în

dreptunghiul determinat de coordonatele întregi X1, Y1, X2, Y2, domeniul

Page 65: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 66 -

mărginit de elipsă şi coarda determinată de punctele (X3, Y3), (X4, Y4) este haşurat.

§ CopyRect (Dest, I, Source) copie imaginea I (de tip TCanvas) din domeniul Sourse în domeniul Dest (ambele de tipul TRect).

§ Draw (X, Y, Graphic) desenează obiectul Graphic (de tip TGraphic),

astfel încît colţul stînga-sus al desenului are coordonatele întregi (X, Y). § DrawFocusRect (Rect) copie domeniul dreptunghiular Rect (de tip TRect)

cu ajutorul operaţiei XOR, de aceea la desenarea repetată desenul anterior se şterge.

§ Ellipse (D) construieşte şi colorează o elipsă înscrisă în dreptunghiul D (de

tip TRect). § FillRect(D) colorează dreptunghiul D. § LineTo(X, Y) construieşte un segment din poziţia curentă pînă-n punctul

de coordonate întregi (X, Y). § Lock blochează pînza. § MoveTo(X, Y) deplasează indicatorul poziţiei curente în punctul (X, Y). § Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4) construieşte un sector de elipsă

înscrisă în dreptunghiul determinat de coordonatele X1, Y1, X2, Y2 şi mărginit de semidreptele cu originea în centrul dreptunghiului şi care trec prin punctele (X3, Y3), (X4, Y4). Se desenează împotriva acelor de ceas.

§ Polygon (Points, PointsSize) construieşte şi colorează un poligon cu

PointsSize vîrfuri definite de vectorul de puncte Points. De exemplu, procedura

void __fastcall TForm1::Button1Click(TObject *Sender){ TPoint points[4]; points[0] = Point(10,10); points[1] = Point(210,10); points[2] = Point(210,110); points[3] = Point(160,160); Form1->Canvas->Brush->Color = clTeal; Form1->Canvas->Polygon(points, 3); }

Page 66: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 67 -

construieşte următorul patrulater:

§ Polyline (Points, PointsSize) construieşte o linie frîntă cu PointsSize

vîrfuri definite de vectorul de puncte Points. § Rectangle (X1, Y1, X2, Y2) construieşte şi colorează un dreptunghi, a

cărui diagonală este mărginită de punctele (X1, Y1), (X2, Y2). § Refresh stabileşte pentru creion şi pensulă valori predefinite. § ResetClipRegion restabileşte domeniul de desenare stabilit anterior cu

procedura SetClipRect. § RoundRect (X1, Y1, X2, Y2, X3, Y3: Integer) construieşte şi colorează

un dreptunghi cu colţurile rotunjite, a cărui diagonală este mărginită de punctele (X1, Y1), (X2, Y2).

§ StretchDraw (D, Graphic) desenează obiectul Graphic (de tip

TGraphics) în domeniul D (de tip TRect). § TextOut(X, Y, S) afişează textul S pe poziţia (X, Y). § TextRect(D, X, Y, S) afişează textul S în interiorul dreptunghiului D (de

tip TRect). Textul care nu încape în dreptunghi este trunchiat. Colţul stînga-sus al dreptunghiului are coordonatele (X, Y).

§ TextHeight (S) returnează înălţimea (în pixeli) a dreptunghiului în care

este inclus textul S.

Page 67: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 68 -

§ TextWidth (S) returnează lăţimea dreptunghiului, în a cărui interior este inclus textul S.

§ TextExtent (const S) (de tip TSize) returnează înălţimea şi lăţimea dreptunghiului în care este inclus textul S. Tipul TSize este definit astfel:

typedef struct TSize { long cx; long cy; } § TryLock (de tip bool) returnează valoarea true dacă pînza de desenare nu

este blocată de alte comenzi, apoi o blochează.

16.3. Evenimentele obiectului Canvas § OnChange se declanşează în momentul cînd imaginea de pe pînză a fost

modificată. § OnChanging se declanşează înainte de începerea modificării imaginii de

pe pînză.

16.4. Clasa TImage

Componenta Image (are tipul TImage, aparţine unit-ului QExtCtrls)

reprezintă un container pentru afişarea imaginilor. Imaginea poate fi încărcată şi în timpul proiectării aplicaţiei prin apelarea proprietăţii Picture a componentei.

Unele proprietăţi ale clasei TImage § Canvas reprezintă pînza de desenare corespunzătoare componentei Image. § Center (de tip bool) stabileşte dacă centrul imaginii afişate de componentă

va coincide (pentru valoarea true) sau nu cu centrul ei. În cazul valorii false, colţul stînga-sus al imaginii va fi poziţionat în colţul-stînga sus al componentei. Proprietatea Center nu are nici un efect atunci, cînd proprietatea AutoSize are valoarea true, sau atunci cînd proprietatea Stretch este true şi proprietatea Picture nu specifică un simbol grafic de extensie *.ICO.

Page 68: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 69 -

§ Picture (de tip TPicture) specifică imaginea care va fi afişată de componenta Image. Clasa TPicture are proprietăţile Bitmap, Graphic, Height, Icon, Width şi metodele Assign, LoadFromFile, LoadFromMimeSource, LoadFromStream, RegisterFileFormat, RegisterFileFormatRes, SaveToFile, SaveToMimeSource, SaveToStream, TPicture (creează un obiect de tip TPicture), UnregisterGraphicClass.

§ Stretch (de tip bool) stabileşte dacă imaginea va fi redimensionată (pentru

valoarea true) sau nu la dimensiunile containerului. Exemple rezolvate 1. Să creăm o aplicaţie care va desena pe fereastra aplicaţiei un disc în poziţia în care utilizatorul va efectua un click de mouse. Meniul contextual al aplica ţiei va conţine comenzile Curata şi Inchide pentru “curăţirea” ferestrei şi respectiv pentru închiderea aplicaţiei. De asemenea, la apăsarea tastei ‘x’ aplicaţia va fi închisă. Pentru determinarea poziţiei mouse-lui vom folosi expresiile:

Mouse->CursorPos.x – returnează coordonata x; Mouse->CursorPos.y – returnează coordonata y.

Realizare 1) Executăm File\New\Application. Plasăm pe formă o componentă de tip TPopupMenu. 2) Prelucrăm evenimentele OnClick şi OnKeyPress ale formei. 3) Modificăm proprietatea Caption a formei. Scriem elementele meniului contextual şi prelucrăm evenimentul OnClick al fiecărui element de meniu. 4) Salvăm şi lansăm aplicaţia la execuţie.

Page 69: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 70 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; int X=10; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void desen(int a,int b){ Form1->Canvas->Brush->Color = clRed; Form1->Canvas->Ellipse(a-X, b-X, a+X, b+X); } void __fastcall TForm1::FormClick(TObject *Sender) { int x,y; x=Mouse->CursorPos.x-Form1->Left; y=Mouse->CursorPos.y-X*2.5-Form1->Top; desen(x,y); } void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key){ if(Key=='c'){ Form1->Hide(); Form1->Show();} if(Key=='x') Form1->Close(); } void __fastcall TForm1::curata1Click(TObject *Sender){ Form1->Hide(); Form1->Show(); } void __fastcall TForm1::Inchide1Click(TObject *Sender){ Form1->Close();} 2. Să creăm o aplicaţie care afişa graficul funcţiei y = x3 pe intervalul [–5, 5]. La redimensionarea ferestrei aplicaţiei graficul se va redimensiona corespunzător. Realizare: 1) Executăm File / New Application.

2) Prelucrăm evenimentele OnPaint şi OnResize ale formei. 3) Lansăm aplicaţia la execuţie.

Page 70: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 71 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::FormPaint(TObject *Sender) { double x,y; int x1, y1; Form1->Canvas->Pen->Width=1; Color=clWhite; Canvas->MoveTo(ClientWidth /2,0); Canvas->LineTo(ClientWidth / 2, ClientHeight); Canvas->MoveTo(0, ClientHeight / 2); Canvas->LineTo(ClientWidth, ClientHeight / 2); Canvas->TextOut(ClientWidth-10, ClientHeight / 2 + 2, "X"); Canvas->TextOut(ClientWidth / 2 + 20, ClientHeight / 2, "1"); Canvas->TextOut(ClientWidth / 2 + 2, 5, "Y"); Canvas->TextOut(ClientWidth / 2 + 2, ClientHeight / 2 - 20, "1"); Form1->Canvas->Pen->Width=3; x=-5; while (x<=5) { y=x*x*x; x1=20*x+ (ClientWidth / 2); y1=(ClientHeight / 2)-20*y; Canvas->Pixels[x1][y1]=clRed;

Page 71: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 72 -

x=x+0.001; }} void __fastcall TForm1::FormResize(TObject *Sender){ double x,y; int x1, y1; Form1->Canvas->Pen->Width=1; Canvas->Rectangle(0,0, ClientWidth, ClientHeight); Color=clWhite; Canvas->MoveTo(ClientWidth /2,0); Canvas->LineTo(ClientWidth / 2, ClientHeight); Canvas->MoveTo(0, ClientHeight / 2); Canvas->LineTo(ClientWidth, ClientHeight / 2); Canvas->TextOut(ClientWidth-10, ClientHeight / 2 + 2, "X"); Canvas->TextOut(ClientWidth / 2 + 20, ClientHeight / 2, "1"); Canvas->TextOut(ClientWidth / 2 + 2, 5, "Y"); Canvas->TextOut(ClientWidth / 2 + 2, ClientHeight / 2 - 20, "1"); Form1->Canvas->Pen->Width=3; x=-5; while (x<=5) { y=x*x*x; x1=20*x+ ClientWidth / 2; y1=ClientHeight / 2-20*y; Canvas->Pixels[x1][y1]=clRed; x=x+0.001; }}

16.5. Clasa TTimer . Efecte de animaţie

Componenta Timer (de tip TTimer) se află pe pagina de componente System şi este utilizată pentru apelarea periodică (după scurgerea unui interval de timp) a unei funcţii. De fapt dacă proprietatea Enabled a aceste componente este true, atunci periodic se declanşează evenimentul OnTimer (în care se poate defini funcţia menţionată) Componenta Timer nu este vizibilă în regim de execuţie. Unele proprietăţi ale clasei TTimer § Enabled (de tip bool) specifică dacă periodic se va declanşa (pentru valoarea true) sau nu evenimentul OnTimer. § Interval specifică numărul de milisecunde (perioada) dintre două apeluri consecutive ale handlerului de evenimente OnTimer.

Page 72: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 73 -

Exemplu rezolvat

Să creăm o aplicaţie a cărei fereastră va conţine două butoane de comandă (Start şi Stop). Butonul Start va lansa un proces care va desena în poziţii aleatoare discuri de culori aleatorii la fiecare 0,5 secunde. Butonul Stop va întrerupe procesul. Realizare:

1) Executăm File / New /Application. 2) Plasăm pe formă două butoane de comandă şi o componentă de tip

TTimer.

3) Atribuim proprietăţii Caption a butoanelor de comandă valori conform enunţului.

4) Prelucrăm evenimentul OnTimer al componentei Timer1 şi

evenimentul OnClick al fiecărui buton de comandă.

5) Lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "fstream.h" #pragma package(smart_init) #pragma resource "*.dfm" int X=10; TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){}

Page 73: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 74 -

void desen(int a,int b,int c){ switch(c){ case 0 : Form1->Canvas->Brush->Color = clBlue; break; case 1 : Form1->Canvas->Brush->Color = clRed; break; case 2 : Form1->Canvas->Brush->Color = clNavy; break; case 3 : Form1->Canvas->Brush->Color = clTeal; break; case 4 : Form1->Canvas->Brush->Color = clGreen; break; case 5 : Form1->Canvas->Brush->Color = clAqua; break; } Form1->Canvas->Ellipse(a-X, b-X, a+X, b+X); } void __fastcall TForm1::Timer1Timer(TObject *Sender){ int x,y,culoare; x=random(Form1->Width); y=random(Form1->ClientHeight-40)+40; culoare=random(6); desen(x,y,culoare); } void __fastcall TForm1::Button1Click(TObject *Sender){ Timer1->Interval=500; Timer1->Enabled=true; } void __fastcall TForm1::Button2Click(TObject *Sender){Timer1->Enabled=false;} 2. Să creăm o aplicaţie care va conţine două butoane de comandă (Start şi Stop) şi va simula plutirea unui pătrat. Plutirea va începe după efectuarea unui click pe butonul Start şi se va opri la efectuarea unui click pe butonul Stop. Realizare: 1) Executăm File / New /Application. 2) Plasăm componentele necesare pe suprafaţa formei (Timer1 şi Button1). 3) Prelucrăm evenimentele Button1Click, Button2Click şi FormPaint. Prin prelucrarea evenimentului FormPaint va fi posibilă stergerea ultimei figuri desenate. 4) Salvăm şi lansăm în execuţie aplicaţia.

Page 74: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 75 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "math.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; double a,b,i,x,y; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void figura(int x, int y); void __fastcall TForm1::Button1Click(TObject *Sender){ x=10; y=Form1->Height/2; a=x; b=Form1->Width ; i=a; Timer1->Enabled=true; } void figura(int x, int y){ int l=25; Form1->Canvas->Rectangle(x-l/2,y-l/2,x+l/2,y+l/2); } void __fastcall TForm1::FormPaint(TObject *Sender){ Form1->Canvas->Pen->Color=clRed; Form1->Color=clWhite; Form1->Canvas->Brush->Color=clBlue; Form1->Canvas->Pen->Mode=pmNotXor; } void __fastcall TForm1::Timer1Timer(TObject *Sender){ if(i>b) i=a; figura(x+i,y-sin(i/25)*50); i+=5; figura(x+i,y-sin(i/25)*50); } void __fastcall TForm1::Button2Click(TObject *Sender){Timer1->Enabled=false;}

§ 17. Cutii de dialog

Există un tip de ferestre, numite cutii de dialog, prin intermediul cărora

se pot simplifica operaţiile de introducere şi extragere a datelor unei aplicaţii. Componentele care afişează aceste cutii se află pe paleta Dialogs.

Page 75: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 76 -

17.1. Clasa TOpenDialog

Componenta OpenDialog afişează o cutie de dialog pentru a selecta fişierele care urmează a fi deschise. Unele proprietăţi şi metode ale clasei TOpenDialog § Propretatea Title specifică titlul cutiei. Dacă valoarea acestei proprietăţi va fi vidă, atunci titlul cutiei va fi Open. § Propretatea DefaultExt specifică extensia implicită pentru un fişier. § Propretatea FileName indică numele (inclusiv calea) ultimului fişier selectat în cutie. § Propretatea Filter specifică filtrul pentru selecţia de fişiere. Pentru a crea un filtru efectuăm un click pe cele trei puncte din caseta de valori a proprietăţii. Apare editorul de filtre care afişează un tabel cu două coloane. În coloana Filter Name se scrie numele filtrului, iar în coloana Filter – extensia fişierelor specificate de aceste filtre.

Filtrul poate fi scris direct în caseta de valori a proprietăţii Filter (din Inspectorul de Obiecte). De exemplu, filtrul din imagine poate fi creat prin atribuirea valorii

texte MS WORD|.doc|Pascal|.pas § Proprietatea FilterIndex specifică numărul de ordine al filtrului care urmează a fi ales. § Metoda Execute() afişează cutia de dialog. De exemplu, pentru a încărca într-o zonă de editare (Memo1) conţinutul unui fişier prin intermediul unei cutii de dialog (OpenDialog1) se va scrie instrucţiunile: OpenDialog1->Execute(); Memo1->Lines->LoadFromFile(OpenDialog1->FileName);

Page 76: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 77 -

17.2. Clasa TSaveDialog

Componenta SaveDialog afişează o cutie de dialog pentru salvarea unui fişier. Utilizatorul poate specifica numele şi locul unde va fi salvat fişierul. Ea are proprietăţi asemănătoare cu cele ale componentei OpenDialog.

17.3. Clasele TOpenPictureDialog şi TSavePictureDialog

Componentele OpenPictureDialog şi SavePictureDialog afişează cutii

de dialog pentru încărcarea şi respectiv salvarea imaginilor. Proprietăţile şi metodele acestor componente sînt similare cu ale

componentelor OpenDialog şi SaveDialog. De exemplu, pentru a încărca o imagine în componenta Image1 (de tip TImage) se va scrie instrucţiunile:

OpenPictureDialog1->Execute(); Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);

Pentru salvarea imaginii afişată de componenta Image1 se va scrie: SavePictureDialog1->Execute(); Image1->Picture->SaveToFile(SavePictureDialog1-> FileName);

17.4. Clasa TFontDialog

Componenta FontDialog afişează o cutie de dialog pentru selectarea unui font. De exemplu, pentru a modifica fontul textului din zona de editare Memo1 se va scrie:

FontDialog1->Execute(); Memo1->Font->Assign(FontDialog1->Font);

17.5. Clasa TColorDialog Componenta ColorDialog generează o cutie de dialog pentru selectarea unei culori. Astfel, pentru modificarea culorii creionului pentru desenare se va scrie:

if(ColorDialog1->Execute(); Canvas->Pen->Color=ColorDialog1->Color;

Page 77: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 78 -

17.5. Clasa TReplaceDialog

Componenta ReplaceDialog afişează o cutie de dialog pentru căutarea şi substituirea automată a unui text prin alt text. Comparativ cu celelalte cutii de dialog, în acest caz trebuie prelucrat evenimentul OnReplace al componentei ReplaceDialog. De exemplu, pentru a efectua căutarea şi substituirea automată unui text prin alt text în zona de editare Memo1 se poate prelucra evenimentul OnClick al unui buton de comandă (acesta va afişa cutia) şi evenimentul OnReplace:

void __fastcall TForm1::Button1Click(TObject *Sender){ ReplaceDialog1->Execute(); Label1->Caption= ReplaceDialog1->ReplaceText; } void __fastcall TForm1::ReplaceDialog1Replace(TObject

*Sender){ TReplaceDialog *dlg = (TReplaceDialog *)Sender; int SelPos = Memo1->Lines->Text.Pos(dlg->FindText); if (SelPos > 0) { Memo1->SelStart = SelPos - 1; Memo1->SelLength = dlg->FindText.Length(); Memo1->SelText = dlg->ReplaceText; } }

Observaţie. Componentele PrinterDialog , PrinterSetupDialog şi FindDialog se utilizează similar. Exemple rezolvate 1. Să creăm o aplicaţie a cărei fereastră va conţine două butoane de comandă: unul va încărca conţinutul unui fişier într-o zonă de editare, celălalt va salva conţinutul zonei într-un fişier. Realizare: 1) Executăm File / New /Application. 2) Plasăm pe formă două butoane de comandă şi cîte o componentă de tip TMemo, TSaveDialog şi TOpenDialog. Modificăm valorile proprietăţilor Caption ale butoanelor de comandă.

Page 78: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 79 -

3) Prelucrăm evenimentele OnClick ale componentelor Button1 şi Button2. 4) Lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::Button1Click(TObject *Sender){ OpenDialog1->Execute(); Memo1->Lines->LoadFromFile(OpenDialog1->FileName); } void __fastcall TForm1::Button2Click(TObject *Sender){ SaveDialog1->Execute(); Memo1->Lines->SaveToFile(SaveDialog1->FileName); } 2. Să creăm un editor de texte cu următorul meniu principal:

File Edit Font New Open Save As Close

Copy Paste Select All

Page 79: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 80 -

Realizare: 1) Executăm File / New /Application. 2) Plasăm pe suprafaţa formei trei cutii de dialog (OpenDialog1, SaveDialog1, FontDialog1), o zonă de editare (Memo1), un meniu principal (MainMenu1). Creăm elementele meniului principal. 3) Prelucrăm evenimentul OnClick al fiecărui element de meniu. 4) Aşa cum la redimensionarea ferestrei aplicaţiei, dimensiunile zonei de editare trebuie să fie racordate cu dimensiunile acestei ferestre, prelucrăm evenimentele OnResize şi OnShow ale formei. 5) Lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::FormShow(TObject *Sender){ Memo1->Top=0; Memo1->Left=0; Memo1->Height=Form1->Height-55; Memo1->Width=Form1->Width-10;

Page 80: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 81 -

} void __fastcall TForm1::FormResize(TObject *Sender){ Memo1->Top=0; Memo1->Left=0; Memo1->Height=Form1->Height-55; Memo1->Width=Form1->Width-10; } void __fastcall TForm1::SaveAs1Click(TObject *Sender){ SaveDialog1->Execute(); Memo1->Lines->SaveToFile(SaveDialog1->FileName); } void __fastcall TForm1::Open1Click(TObject *Sender){ OpenDialog1->Execute(); Memo1->Lines->LoadFromFile(OpenDialog1->FileName); } void __fastcall TForm1::New1Click(TObject *Sender){ int i=Application->MessageBoxA("Doriti sa salvati fisierul","Save", MB_YESNO); if(i==IDYES){ OpenDialog1->Execute(); Memo1->Lines->SaveToFile(SaveDialog1->FileName); } Memo1->Clear(); } void __fastcall TForm1::Close1Click(TObject *Sender){ Form1->Close();} void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action){ int i=Application->MessageBoxA("Doriti sa salvati fisierul","Save", MB_YESNO); if(i==IDYES){ OpenDialog1->Execute(); Memo1->Lines->SaveToFile(SaveDialog1->FileName); } } void __fastcall TForm1::Copy1Click(TObject *Sender){ Memo1->CopyToClipboard(); } void __fastcall TForm1::Paste1Click(TObject *Sender){ Memo1->PasteFromClipboard(); } void __fastcall TForm1::SelectAll1Click(TObject *Sender){ Memo1->SelectAll();} void __fastcall TForm1::Font1Click(TObject *Sender) { FontDialog1->Execute(); Memo1->Font=FontDialog1->Font; }

Page 81: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 82 -

§ 18. Liste de opţiuni şi casete combinate

Listele de opţiuni şi casetele combinate se folosesc pentru alegerea elementelor dint-o listă derulantă.

18.1. Clasa TListBox O componentă de tip TListBox afişează o listă de opţiuni (elemente,

articole), dintre care utilizatorul poate alege una sau mai multe. Dacă toate opţiunile nu încap în zona listei, atunci automat apare o bară de defilare verticală.

Unele proprietăţi ale clasei TListBox § Columns determină numărul de coloane vizibile. Valoarea 0 înseamnă că nu este permisă afişarea pe mai multe coloane. § Items (de tip TStrings) reprezintă elementele din casetă. Se utilizează ca şi proprietatea Items a componentei Memo. § Style stabileşte stilul de desenare a listei. Valori posibile: lbStandard (elementele listei sînt şiruri de caractere şi au aceeaşi înălţime, valoare implicită), lbOwnerDrawFixed (elementele listei au aceeaşi înălţime şi sînt desene desenate cu procedura evenimentului OnDrawItem al fiecărui element), lbOwnerDrawVariable (elementele listei au înălţime variabilă, sînt imagini desenate cu procedura evenimentului OnDrawItem al fiecărui element, înălţimea fiind specificată în procedura evenimentului OnMeasureItem). § ItemHeight specifică înălţimea în puncte a tuturor elementelor listei (dacă proprietatea Style are valoarea lbOwnerDrawFixed). § IntegralHeight (de tip bool) stabileşte dacă înălţimea listei va fi (pentru valoarea true) sau nu un multiplu al valorii proprietăţii ItemHeight. În cazul valorii false (valoare implicită) posibil ca ultimul element al listei să fie trunchiat. § ItemIndex indică numărul de ordine al elementului selectat din cutie. Dacă nici un articol nu este selectat, atunci ItemIndex întoarce –1. Primul articol are indexul 0. § MultiSelect (de tip bool) specifică dacă utilizatorul poate (pentru valoarea true) selecta simultan articole. § ExtendedSelect (de tip bool) specifică dacă utilizatorul poate selecta mai multe elemente consecutive. Dacă MultiSelect este false, atunci ExtendedSelect nu are nici un efect.

Page 82: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 83 -

§ SelCount returnează numărul de elemente selectate, dacă sînt permise selectări multiple. § Selected[i] (de tip bool) returnează true dacă articolul cu numărul de ordine i+1 este selectat. § Sorted (de tip bool) determină dacă elementele listei sînt afişate (pentru valoarea true) sau nu în ordine alfabetică. § TabWidth stabileşte lungimea (în puncte de ecran) a spaţiului de tabulare. § TopIndex stabileşte indicele elementului care apare în partea superioară a listei. Se utilizează şi pentru a determina indicele elementului aflat în partea superioară a listei. Unele metode ale clasei TListBox § Funcţia ItemAtPos (Pos, Existing) returnează:

- indicele unui element al listei dacă punctul de coordonatele Pos (de tip TPoint) aparţine acestui element;

- – 1 dacă Existing este true şi acest punct este situat după ultimul element al listei;

- returnează indicele ultimului element al listei plus 1 dacă Existing este false şi acest punct este situat după ultimul element al listei.

§ Funcţia ItemRect (I) (de tip TRect) returnează coordonatele dreptunghiului care conţine elementul cu indicele I. Evenimenteşe specifice clasei TListBox § OnDrawItem se declanşează atunci cînd urmează să fie desenat un element al listei (dacă proprietatea Style are valoarea lbOwnerDrawFixed sau lbOwnerDrawVariable). § OnMeasureItem se declanşează atunci cînd urmează să fie desenat un element al listei (dacă proprietatea Style are valoarea lbOwnerDrawVariable). Exemplu rezolvat Fereastra următoarei aplicaţii va conţine:

- o casetă de editare în care vom scrie un text; - o listă de opţiuni în care se va adăuga cîte o opţiune – textul din caseta

de editare;

Page 83: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 84 -

- butonul Adauga care va adăuga cîte o opţiune – textul din caseta de editare;

- butonul Sterge care va şterge elementul selectat din lista de opţiuni; - butonul Selectat care va afişa într-o fereastră de mesaje elementul

selectat; - butonul Iesire care va închide aplicaţia.

Realizare: 1) Executăm File / New /Application. 2) Plasăm pe formă componentele conform enunţului. 3) Prelucrăm evenimentul OnClick al fiecărui buton de comandă. 3) Modificăm proprietatea Caption a formei şi a butoanelor de comandă. 4) Apăsăm F9 pentru compilarea şi executarea programului.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::Button2Click(TObject *Sender){

Page 84: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 85 -

if (!(ListBox1->ItemIndex == -1)) ListBox1->Items->Delete(ListBox1->ItemIndex); } void __fastcall TForm1::Button1Click(TObject *Sender){ ListBox1->Items->Add(Edit1->Text); Edit1->Clear(); } void __fastcall TForm1::Button3Click(TObject *Sender){ Close(); } void __fastcall TForm1::Button4Click(TObject *Sender){ ShowMessage(ListBox1->Items->Strings[ListBox1->ItemIndex]); }

18.2. Clasa TComboBox O componentă de tip TComboBox este o casetă combinată formată

dintr-o casetă de editare şi o listă de opţiuni. Utilizatorul poate alege unul sau mai multe articole din lista de opţiuni sau poate scrie denumirea unui articol în casetă. TComboBox are multe dintre proprietăţile şi metodele claselor TListBox (de exemplu, Items, Sorted, SelText, ItemIndex, ItemHeight) şi TEdit (de exemplu, Text, MaxLength).

Unele proprietăţi ale clasei TComboBox § DropDownCount (valoarea implicită este 8) specifică numărul maxim de elemente care se afişează simultan în listă. § DroppedDown (de tip bool) stabileşte dacă lista derulantă a listei combinate este (pentru valoarea true) sau nu vizibilă. § Style stabileşte stilul listei combinate. Valori posibile: - csDropDown (lista este formată dintr-o casetă de editare şi o listă derulantă care poate fi ascunsă sau afişată cu ajutorul unui buton-săgeată, elementele listei sînt şiruri de caractere de aceeaşi înălţime); - csSimple (lista este formată dintr-o casetă de editare şi o listă derulantă care nu poate fi ascunsă); - csDropDownList (lista este formată dintr-o casetă de editare formală în care utilizatorul nu poate scrie un text, fiind utilizată doar pentru afişarea elementului selectat, şi o listă derulantă care poate fi ascunsă sau afişată cu ajutorul unui buton-săgeată, elementele listei sînt şiruri de caractere de aceeaşi înălţime);

Page 85: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 86 -

- csOwnerDrawFixed (listă similară cu lista care are stilul csDropDownList, elementele listei au aceeaşi înălţime şi sînt desenate de utilizator în procedura evenimentului OnDrawItem); - csOwnerDrawVariable (listă similară cu lista care are stilul csDropDownList, înălţimea fiecărui element al listei se defineşte în procedura evenimentului OnMeasureItem, apoi aceste elemente sînt desenate de utilizator în procedura evenimentului OnDrawItem).

Unele evenimente ale componentei ComboBox

§ OnChange apare în momentul în care un alt articol este selectat sau un text este introdus în caseta de editare. § OnDropDown se declanşează în momentul în care urmează să fie deschisă lista derulantă a listei combinate.

Exemplu rezolvat

Fereastra următoarei aplicaţii va conţine o casetă combinată

(ComboBox1) cu numerele 1, 2, ..., 40. La selectarea unui număr din listă, într-un titlu de etichetă (Label2) va fi afişată rădăcina pătrată a acestui număr. Realizare: 1) Executăm File / New /Application. 2) Plasăm pe formă componentele conform enunţului. 3) Prelucrăm evenimenul OnCreate al formei (pentru a completa cu valori caseta combinată) şi evenimentul OnClick al acestei casete. 4) Modificăm proprietatea Caption a formei şi a etichelor Label1 şi Label3. 5) Apăsăm F9 pentru compilarea şi executarea programului.

Page 86: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 87 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "math.h" #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::ComboBox1Click(TObject *Sender){ double r; r=sqrt((ComboBox1->Items->Strings[ComboBox1->ItemIndex]).ToInt()); Label1->Caption=AnsiString(r); } void __fastcall TForm1::FormCreate(TObject *Sender){ for(int i=1;i<=40;i++) ComboBox1->Items->Add(IntToStr(i)); }

§ 19. Clasa TStringGrid

Componenta StringGrid afişează un tabel, a cărui celule conţin valori de tip AnsiString. Unele proprietăţi ale componentei TStringGrid § Cells [col][row] determină celula care se obţine la intersecţia coloane col şi rîndului row. Numerotarea coloanelor şi a rîndurilor începe de la 0. § Cols [I] (de tip TStrings) determină coloana I de celule. § Col specifică indicele coloanei căreia îi aparţine celula curentă.

Page 87: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 88 -

§ ColCount specifică numărul de coloane ale reţelei. § ColWidths [I] specifică lăţimea celulelor coloanei I. § DefaultColWidth specifică lăţimea tuturor celulelor coloanelor, pentru care nu a fost stabilită lăţimea cu ColWidths. § DefaultRowHeight specifică înălţimea tuturor celulelor coloanelor, pentru care nu a fost stabilită lăţimea cu ColWidths. § FixedColor (de tip TColor) stabileşte culoarea de fondal a celulelor de antet. § FixedCols specifică numărul de coloane de antet. § FixedRows specifică numărul de rînduri de antet. § GridHeight (readonly) determină înălţimea (în pixeli) a reţelei. § GridLineWidth determină lăţimea (în pixeli) liniilor care delimitează celulele reţelei . § GridWidth (readonly) determină lăţimea reţelei. § Row specifică indicele rîndului căruia îi aparţine celula curentă. § Rows [I] (de tip TStrings) determină rîndul I de celule. § RowCount specifică numărul de rînduri ale reţelei. § RowHeights [I] specifică înălţimea celulelor rîndului I. § ScrollBars stabileşte dacă reţeaua va fi sau nu înzestrată cu bare de defilare. Valori posibile: ssNone, ssHorizontal, ssVertical, ssBoth. § TopRow specifică indicele primului rînd vizibil cu bara de defilare. § VisibleColCount numărul de coloane vizibile în reţea. Celelalte coloane se vor lista cu bara de defilare. § VisibleRowCount numărul de rînduri vizibile în reţea. Celelalte rînduri se vor lista cu bara de defilare. § Options (proprietate compusă, de tip TGridOption) stabileşte diferite opţiuni de lucru cu celulele reţelei. Elementele mulţimii TGridOption: goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goRowSizing, goColSizing, goRowMoving, goColMoving, goEditing, goTabs, goRowSelect, goAlwaysShowEditor, goThumbTracking. De exemplu, instrucţiunea

StringGrid1->Options = StringGrid1->Options >> goEditing; interzice editarea reţelei, iar instrucţiunea

StringGrid1->Options = StringGrid1->Options << goEditing; permite editarea.

Unele evenimente ale clasei TStringGrid § OnColumnMoved apare atunci cînd este modificată poziţia coloanelor. § OnDrawCell se declanşează în momentul în care trebuie desenată o celulă a reţelei.

Page 88: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 89 -

§ OnGetEditText apare atunci cînd urmează editarea unei celule a reţelei. § OnRowMoved apare atunci cînd este modificată poziţia rîndurilor. § OnSelectCell apare atunci cînd este selectată o celulă a reţelei. § OnSetEditText apare atunci cînd utilizatorul editează o celulă a reţelei § OnTopLeftChanged apare imediat după modificarea proprietăţii TopRow sau a proprietăţii LeftCol. Exemplu rezolvat

Să creăm o aplicaţie care va efectua adunarea a două matrice pătratice

de ordinul 4. Vom folosi pentru stocarea matricelor şi a rezultatului trei componente de tip TStringGrid. Butonul de comandă Generează elementele (Button1) va genera aleator elementele celor două matrice cu ajutorul funcţiei random, iar butonul Calculeaza suma va calcula matricea-sumă. Realizare: 1) Executăm File / New /Application. 2) Plasăm pe formă componentele conform enunţului. 3) Atribuim proprietăţilor FixedCols şi FixedRows ale fiecărei componente de tip TStringGrid valoarea 0. 5) Modificăm proprietatea Caption a formei şi a butoanelor de comandă. 6) Prelucrăm evenimentul OnClick al fiecărui buton de comandă 7) Apăsăm F9 pentru compilarea şi executarea programului.

Page 89: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 90 -

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include<stdlib.h> #include "Unit1.h" #define dim 4 #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; int i,j,a,b; char c; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::Button1Click(TObject *Sender){ StringGrid1->ColCount=dim; StringGrid1->RowCount=dim; StringGrid2->ColCount=dim; StringGrid2->RowCount=dim; StringGrid3->ColCount=dim; StringGrid3->RowCount=dim; randomize(); for(i=0;i<dim;i++) for(j=0;j<dim;j++) StringGrid1->Cells[i][j]=random(100); for(i=0;i<dim;i++) for(j=0;j<dim;j++) StringGrid2->Cells[i][j]=random(100); } void __fastcall TForm1::Button2Click(TObject *Sender){ for(i=0;i<dim;i++) for(j=0;j<dim;j++) { a=StringGrid1->Cells[i][j].ToInt(); b=StringGrid2->Cells[i][j].ToInt(); StringGrid3->Cells[i][j]=a+b; } }

§ 20. Prelucrarea datelor calendaristice

Pentru prelucrarea datelor calendaristice în Borland C++ Builder se foloseşte clasa TDateTime, care este definită în biblioteca systdate.h. Valorile acestui tip sînt de fapt numere reale de tipul double. Partea întreagă a unei valori pozitive de tip TDateTime reprezintă numărul de zile care au trecut de la 30 decembrie 1899. În cazul unei valori negative partea întreagă este numărul

Page 90: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 91 -

de zile care preced data menţionată. Partea fracţionară semnifică fracţiuni din ziua corespunzătoare valorii.

De exemplu, numărul 2.75 reprezintă data 1 ianuarie 1900 ora 18:00, iar numărul –3.25 – data 27 decembrie 1899 ora 6:00.

Formatul de reprezentare a datei printr-un string depinde de opţiunile regionale stabilite în Windows. De exemplu, noi folosim formatul dd.MM.yy. H:mm:ss, unde dd este numărul zilei în lună, MM – numărul lunii, yy – anul, H – ora, mm – numărul minute, ss – numărul de secunde.

Dacă utilizatorul nu specifică ora, minutele sau secundele, atunci acestea se consideră nule. Unele metode ale clasei TDateTime § Date (de tip TDateTime) returnează data curentă (fără timp). § DateTimeToStr (D) returnează reprezentarea simbolică a datei (cu timp, dacă parametrul D (de tip TDateTime) îl conţine). § DateTimeToString (Result, Format, D) transformă valoarea lui D (de tip DateTime) în text respectînd formatul specificat de parametrul Format (de tip AnsiString) şi atribuie rezultatul parametrului Result (de tip AnsiString). § DateToStr (D) returnează reprezentarea simbolică a datei D (fără timp, D este de tipul TDateTime). § DayOfWeek (D) returnează numărul de ordine al zilei în săptămînă corespunzătoare datei D (de tip TDateTime). (Numărul 1 corespunde duminicii, 2 – zilei de luni, 3 – zilei de marţi etc.) § DecodeDate (D, Year, Month, Day) determină anul Year, numărul lunii Month din an şi numărul de ordine Day în lună corespunzătoare valorii D (de tip TDateTime). § DecodeDateFully (D, Year, Month, Day, DOW) determină anul Year, numărul lunii Month din an, numărul de ordine Day în lună şi numărul de ordine în săptămînă DOW corespunzătoare valorii D (de tip DateTime). Funcţia DecodeDateFully returnează valoarea true dacă şi numai dacă D corespunde unui an bisect. § DecodeTime (Time, Hour, Min, Sec, MSec) determină ora Hour, minutele Min, secundele Sec, milisecundele MSec corespunzătoare valorii Time (de tip TDateTime). § EncodeDate (Year, Month, Day) returnează valoarea de tip calendaristic (adică de tip TDateTime) corespunzătoare anului Year, lunii Month şi zilei Day. § EncodeTime (Hour, Min, Sec, MSec) returnează valoarea de tip calendaristic (adică de tip TDateTime) corespunzătoare orei Hour, minutelor

Page 91: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 92 -

Min, secundelor Sec şi milisecundelor MSec. § FormatDateTime (Format, D) returnează reprezentarea simbolică a valorii D (de tip DateTime) respectînd formatul specificat de parametrul Format (de tip AnsiString). De exemplu, dacă la moment este ora 20:56, miercuri, 18 martie, 2009, atunci expresia FormatDateTime ("Acum este " dddd, d, mmmm yyyy, " ora " hh:mm AM/PM', Now) va returna textul ‘Acum este miercuri, 18, martie 2009, ora 8:56 PM’. § Now() returnează timpul curent (de tip TDateTime). § StrToDate (S) returnează valoarea de tip calendaristic (adică de tip TDateTime) corespunzătoare reprezentării simbolice S a datei (fără timp). § StrToDateTime (S) returnează valoarea de tip calendaristic (adică de tip TDateTime) corespunzătoare reprezentării simbolice S a datei (cu timp). § StrToTime (S) returnează valoarea de tip calendaristic (adică de tip TDateTime) corespunzătoare reprezentării simbolice S a datei (doar cu timp). § Time returnează timpul curent (de tip TDateTime). § TimeStampToMSecs (TimeStamp) transformă valoarea TimeStamp în numărul întreg de milisecunde. Tipul TTimeStamp este definit astfel: struct TtimeStamp { int Time; int Date; }; § TimeToStr (Time) returnează reprezentarea simbolică a timpului (data nu se include în rezultat). Astfel, TimeToStr(Now()) returnează reprezentarea simbolică a timpului curent, DateToStr(Now()) – a datei curente, iar DateTimeToStr(Now()) a datei şi timpului curent. § TryEncodeDate (Year, Month, Day, Date) returnează valoarea Date de tip TDateTime corespunzătoare valorilor Year (cuprinsă între 1 şi 9999 inclusiv), Month (cuprinsă între 1 şi 12 inclusiv), Day (cuprinsă între 1 şi 28, 29, 30 sau 31, în funcţie de valoarea Month). Dacă valorile parametrilor actuali nu se încadrează între limitele permise, atunci valoarea funcţiei TryEncodeDate va fi false, altfel – true. § TryEncodeTime (Hour, Min, Sec, Msec, Time) returnează valoarea Time de tip TDateTime corespunzătoare valorilor Hour (cuprinsă între 0 şi 24 inclusiv), Month (cuprinsă între 1 şi 12), Min şi Sec (cuprinse între 0 şi 59 inclusiv), MSec (cuprinsă între 0 şi 999 inclusiv). Dacă valorile parametrilor actuali nu se încadrează între limitele permise, atunci valoarea funcţiei va fi false, altfel – true. Exemplu rezolvat

Să creăm o aplicaţie a cărei fereastră va conţine două etichete şi două

butoane de comandă. Butonul Data curenta va afişa în titlul etichetei Label1 data curentă, iar butonul Timpul curent – în titlul etichetei Label2 timpul

Page 92: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 93 -

curent. La închiderea aplicaţiei va apărea o fereastră cu un mesaj de informare despre durata de execuţie a aplicaţiei. Realizare:

Pentru a afla durata de execuţie a aplicaţiei create vom prelucra evenimentele OnCreate şi OnClose ale formei. În procedura fiecărui eveniment se va fixa într-o variabilă timpul curent. 1) Executăm File / New /Application. 2) Plasăm componentele conform enunţului. Modificăm proprietatea Caption a formei şi a butoanelor. 3) Prelucrăm evenimentele OnCreate şi OnClose ale formei, precum şi evenimentul OnClick al fiecărui buton de comandă. 4) Apăsăm F9 pentru compilarea şi executarea programului.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; TDateTime p1,p2,d,w; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::FormCreate(TObject *Sender){p1=Time();} void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action){ p2=Time(); d=p2-p1;

Page 93: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 94 -

ShowMessage("Timpul executiiei este "+AnsiString(d)); } void __fastcall TForm1::Button1Click(TObject *Sender){ w=Date(); Label1->Caption=" Data Curenta "+AnsiString(w); } void __fastcall TForm1::Button2Click(TObject *Sender){ w=Time(); Label2->Caption=" Timpul Curent "+AnsiString(w); }

20.1. Clasa TMonthCalendar

Componenta MonthCalendar (de tip TMonthCalendar) se află pe pagina Win32 şi este proiectată în special pentru a introduce tipuri de date calendaristice. Ea afişează un calendar, din care utilizatorul poate selecta o data. Unele proprietăţi ale clasei TMonthCalendar § CalColor (de tip TMonthCalColors) indică culorile folosite pentru fiecare parte din calendar. Clasa TMonthCalColors are proprietăţile:

- BackColor (defineşte culoarea de fundal pentru lunile din calendar); - MonthBackColor (defineşte culoarea de fundal pentru calendar); - TextColor (defineşte culoarea textului datelor lunii curente); - TitleBackColor(defineşte culoarea de fundal a barei de titlu a

calendarului); - TitleTextColor (defineşte culoarea textului de pe bara de titlu a

calendarului); - TrailingTextColor (defineşte culoarea datelor lunii care nu conţin data

curentă). § MaxDate indică data maximă (de tip TDate) pînă la care utilizatorul poate parcurge calendarul. TDate reprezintă un tip special de TDateTime care nu are partea zecimală. Deci, o valoare de tip TDate reprezintă numărul de zile care s-au scurs de la 30 decembrie1899. § MinDate indică data maximă (de tip TDate) pînă la care utilizatorul poate parcurge calendarul. § Date (de tip TDate) specifică data selectată de utilizator. Valoarea datei trebuie să se afle în intervalul specificat de proprietăţile MaxDate şi MinDate.

Page 94: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 95 -

20.2. Clasa TDateTimePicker

Componenta DateTimePicker (de tip TDateTimePicker), de asemenea, se află pe pagina Win32 şi se foloseşte pentru a introduce tipuri de date calendaristice. Ea afişează o casetă combinată formată dintr-o linie de editare şi un calendar, din care utilizatorul poate selecta o data. În acelaşi timp utilizatorul poate scrie data în linia de editare a componentei. Clasa TDateTimePicker conţine unele (CalColors, Date, DateTime, MaxDate, MinDate) dintre proprietăţile clasei TMonthCalendar. Unele proprietăţi specifice clasei TDateTimePicker § DateFormat indică modul în care este afişată o dată. Valori posibile: dfShort (formatul scurt, de exemplu, 21/11/2008), dfLong (formatul lung – 21 noiembrie 2008). § DateMode indică modul de afişare a componentei. Valori posibile: dmComboBox (valoarea impliită), dmUpDown (calendarul nu se afişează, caseta va avea un buton de incrementare/ decrementare pentru selectarea datei). § DroppedDown (de tip bool) returnează true doar dacă calendarul este afişat. § Kind specifică dacă componenta DateTimePicker va afişa o dată sau un moment de timp. Valori posibile: dtkDate, dtkTime. § Time specifică timpul selectat de utilizator. Se foloseşte doar dacă proprietatea Kind este setată la valoarea dtkTime. § ShowCheckbox (de tip bool) ataşează (pentru valoarea true) componentei o casetă de validare. § Ckeched (de tip bool) specifică starea casetei de validare ataşată componentei. Exemplu rezolvat

Se creăm o aplicaţie a cărei fereastră va afişa două calendare (unul de tip TMonthCalendar, altul de tip TDateTimePicker) şi un ceas digital care va arăta timpul curent. Selectarea unei date în unul dintre calendare va selecta aceeaşi dată în celălalt calendar.

Page 95: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 96 -

Realizare: 1) Executăm File / New /Application. 2) Plasăm pe formă cîte o componentă de tip TMonthCalendar, TDateTimePicker, TTimer şi două etichete 3) Prelucrăm evenimentele OnTimer al componentei Timer1, OnCreate al formei, OnClick al componentei MonthCalendar1 şi OnChange al componentei DateTimePicker1. 4) Modificăm proprietatea Caption a formei şi a etichetelor. 5) Apăsăm F9 pentru compilarea şi executarea programului.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::Timer1Timer(TObject *Sender){

Page 96: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 97 -

TDateTime d; d=Time(); Label1->Caption=AnsiString(d); } void __fastcall TForm1::FormCreate(TObject *Sender){ Timer1->Enabled=true; Timer1->Interval=100; } void __fastcall TForm1::MonthCalendar1Click(TObject *Sender){ DateTimePicker1->Date=MonthCalendar1->Date; } void __fastcall TForm1::DateTimePicker1Change(TObject *Sender){ MonthCalendar1->Date=DateTimePicker1->Date; }

§ 21. Prelucrarea fişierelor şi cataloagelor

Pentru prelucrarea fişierelor şi cataloagelor în Borland C++ Builder se pot folosi componentele paletei Win 3.1.

21.1. Clasa TFileListBox Componenta FileListBox (de tip TFileListBox) este o cutie care afişează fişierele unui catalog.

Unele proprietăţi ale componentei FileListBox § Directory (de tip AnsiString) specifică catalogul (împreună cu calea) a cărui fişiere sînt afişate în cutie. § Drive (de tip char) specifică unitatea de disc pe care se află fişierele afişate

Page 97: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 98 -

de cutie. § FileEdit (de tip TEdit) stabileşte cutia de editare care va afişa numele fişierului selectat de utilizator în cutie. § FileName (de tip AnsiString) păstrează numele (împreună cu calea) fişierului selectat de utilizator în cutie. § FileType (de tip mulţime) determină ce tip de fişiere va afişa cutia. Valori posibile: ftReadOnly, ftHidden, ftSystem, ftVolumeID, ftDirectory, ftArchive, ftNormal. § Mask specifică care fişiere pot fi afişate, asemeni proprietăţii Filter a componentei OpenDialog. § ShowGlyphs (de tip bool) stabileşte dacă în faţa fiecărui fişier va apărea (pentru valoarea true) sau nu va apărea pictograma.

21.2. DirectoryListBox Componenta DirectoryListBox (de tip TDirectoryListBox) este o cutie care afişează subcataloagele unei unităţi de disc sau a unui catalog.

Unele proprietăţi ale componentei DirectoryListBox § Directory (de tip AnsiString) indică denumirea catalogului, a cărui conţinut este afişat. § Drive indică unitatea de disc pe care se află catalogul, a cărui conţinut este afişat. § FileList specifică numele componentei de tip TFileListBox în care se vor afişa fişierele catalogului deschis în componenta DirectoryListBox. § DirLabel (de tip TLabel) specifică numele etichetei care va afişa denumirea catalogului curent. De exemplu, în urma instrucţiunii DirectoryListBox1->DirLabel=Label1 eticheta Label1 va afişa denumirea catalogului selectat în cutia DirectoryListBox1.

Page 98: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 99 -

21.3. Tipul TSearchRec

TSearchRec defineşte tipul de date fişier, avînd următoarea declaraţie: struct TSearchRec{ int Time; int Size; int Attr; AnsiString Name; int ExcludeAttr; int FindHandle; _WIN32_FIND_DATAA FindData; }; El este folosit pentru căutarea fişierelor cu ajutorul funcţiilor FindFirst şi FindNext.

Funcţia FindFirst (Path, Attr, F) caută în catalogul specificat de Path (de tip AnsiString) primul fişier cu numele specificat de Path şi cu atributul Attr. Rezultatul se returnează prin parametrul F (de tip TSearchRec). Funcţia FindFirst returnează 0 doar dacă fişierul specificat a fost găsit (altfel returnează un cod de eroare).

Funcţia FindNext (F) caută următorul fişier cu numele şi atributele menţionate anterior într-un apel FindFirs. Rezultatul se returnează prin parametrul F (de tip TSearchRec). Funcţia FindNext returnează 0 doar dacă fişierul specificat a fost găsit. Exemplu rezolvat

Să creăm o aplicaţie a cărei fereastră va conţine trei etichete (Atribute,

Nume fisier, Volum), un buton de comandă (Cauta), şapte butoane de validare (fiecare caseta corespunde unui atribut de fişier), o casetă de editare şi un tabel cu două coloane (de tip TStringGrid). Utilizatorul va scrie în caseta de editare numele unui fişier (sau o mască de fişier). Butonul Cauta va afişa în tabel denumirile şi volumul fişierelor specificate de casetă, care au atributele butoanelor validate. Realizare: 1) Executăm File / New /Application. 2) Plasăm pe formă componentele conform enunţului.

Page 99: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 100 -

3) Modificăm valorile proprietăţii Caption a etichetelor, a butonului de comandă şi a butoanelor de validare. 4) Prelucrăm evenimentul OnClick al butonului de comandă. 5) Apăsăm F9 pentru compilarea şi executarea aplicaţiei.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fabstcall TForm1::Button1Click(TObject *Sender) { TSearchRec Rez; int iAttributes = 0; iAttributes |= faReadOnly * CheckBox1->Checked; iAttributes |= faHidden * CheckBox2->Checked; iAttributes |= faSysFile * CheckBox3->Checked; iAttributes |= faVolumeID * CheckBox4->Checked; iAttributes |= faDirectory * CheckBox5->Checked; iAttributes |= faAnyFile * CheckBox6->Checked; StringGrid1->RowCount = -1;

Page 100: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 101 -

if (FindFirst(Edit1->Text, iAttributes, Rez) == 0) { do { if ((Rez.Attr & iAttributes) == Rez.Attr) { StringGrid1->RowCount = StringGrid1->RowCount + 1; StringGrid1->Cells[0][StringGrid1->RowCount-1] = Rez.Name; StringGrid1->Cells[1][StringGrid1->RowCount-1] = IntToStr(Rez.Size); } } while (FindNext(Rez) == 0); FindClose(Rez); } } Unele funcţii de prelucrare a fişierelor şi cataloagelor § FileAge (F) returnează data creării fişierului F (de tip AnsiString). § FileExist (F) (de tip bool) returnează valoare true dacă fişierul F (de tip AnsiString) există. § DeleteFile (F) şterge fişierul F (de tip AnsiString). De exemplu, instrucţiunea DeleteFile(OpenDialog1->FileName); va şterge fişierul selectat de utilizatorul în fereastra OpenDialog1. § RenameFile (F, F_nou) modifică numele fişierului F în F_nou (ambele de tip AnsiString). § ExtractFilePath (F) returneză calea fişierului F (de tip AnsiString). § ExtractFileDrive (F) returnează numele discului pe care se află fişierul F (de tip AnsiString). § CreateDir (C) creează catalogul C (de tip AnsiString). § RemoveDir (C) şterge catalogul C (de tip AnsiString), dacă acesta este gol. Exemplu rezolvat

Să creăm o aplicaţie pentru a ilustra un mod de lucru cu directoare şi

fişiere. Fereastra aplicaţiei va conţine patru etichete, un meniu principal (MainMenu1) cu opţiunile Creare (catalog), Sterge (catalog, fişier), un meniu contextual (PopupMenu1) cu opţiunea Sterge, cîte o componentă de tip TDirectoryListBox, TFileListBox, TEdit, TButton. Utilizatorul va putea viziona, crea, şterge cataloage.

Page 101: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 102 -

Realizare: 1) Executăm File / New /Application. 2) Plasăm componentele pe formă conform enunţului. Modificăm proprietatea Caption a formei şi a controalelor de pe formă conform enunţului. Atribuim proprietăţii PopupMenu1 a componentei FileListBox1 valoarea PopupMenu1. 3) Pentru a crea legătura dintre componentele DirectoryListBox1 şi FileListBox1 atribuim valoarea FileListBox1 proprietăţii ListBox a controlului DirectoryListBox1. 4) Prelucrăm evenimentul OnClick al butonului de comandă şi al fiecărui element de meniu. 5) Apăsăm F9 pentru compilarea şi executarea programului.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1;

Page 102: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 103 -

__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ } void __fastcall TForm1::Button1Click(TObject *Sender) { DirectoryListBox1->Directory=Edit1->Text; } void __fastcall TForm1::catalog1Click(TObject *Sender){ AnsiString nume; nume=InputBox("Crearea catalogului","Numele catalogului",""); CreateDir(nume); DirectoryListBox1->Update(); FileListBox1->Update(); } void __fastcall TForm1::catalog2Click(TObject *Sender) { AnsiString nume; nume=InputBox("Sterge catalog","Numele catalogului care va fi sters",""); RemoveDir(nume); DirectoryListBox1->Update(); FileListBox1->Update(); } void __fastcall TForm1::fisier1Click(TObject *Sender){ AnsiString nume; nume=InputBox("Sterge fisier","Numele complet al fisierului",""); DeleteFile(nume); DirectoryListBox1->Update(); FileListBox1->Update(); } void __fastcall TForm1::Sterge2Click(TObject *Sender) { if(FileListBox1->ItemIndex==-1) ShowMessage("Nici un fisier nu este selectat"); else if(DeleteFile(FileListBox1->FileName)) { FileListBox1->Update(); ShowMessage("Fisierul a fost sters"); } else ShowMessage("Fisierul nu a fost sters"); }

Page 103: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 104 -

§ 22. Crearea obiectelor în timpul

execuţiei aplicaţiei

Am menţionat deja că în Borland C++ Builder obiectele vizuale se

numesc componente. Deci, o componentă este de fapt un exemplar al unei clase. De exemplu Button1 este un obiect (sau un exemplar ) al clasei TButton.

Uneori programatorul nu cunoaşte din timp numărul de componente necesare pentru derularea eventuală a unui proces al aplicaţiei lansat de utilizator sau de însăşi aplicaţie. Prin urmare, apare problema creării şi distrugerii obiectelor în timpul execuţiei aplicaţiei.

Pentru soluţionarea acestei probleme se folosesc operatorii new şi delete pot fi utilizaţi pentru alocare, respectiv eliberea memorie în cazul obiectelor. Modaliatea de utilizarea a acestor operatori nu se deosebeşte esenţial de utilizare lor în cazul claselor (C++).

În continuarevom analiza problema aqlocaării dinamice a obiectelor. La plasarea unei componente pe suprafaţa formei declararea obiectului în cauză este scrisă în fişierul unuit.h. În cazul alocării dinamice nu se va lucra cu acel fişier, adică nu se vor efectua careva declaraţii ale evntualeor obiecte. Pentru a aloca dinamic a mai multe obiecte de tip (Nume_clasa), se va proceda astfel:

1) În antetul fişierului (.cpp) de declară un pointer (de obicei dublu pointer) de tipul clasei.

Nume_clasa **obiect; 2) Se alocă memoria pentru pointerul în cauză. obiect=new Nume_clasa*[nr];// nr reprezintă numărul de

obiecte for(i=0;i<nr;i++) obieect[i]=new Nume_clasa(this);/* pentru

fiecare dintre obiect este apelat constructorul cu parametric impliciţi pentru fiecare obiect*/

3) Setăm valorile iniţiale pentru fiecare obiect, de exemplu for(i=0;i<nr;i++){ obieect[i]->Width=i+100; obieect[i]-> Height=i+50; // alte initializari, dupa necessitate } 4) Se indică care este părintele obiectului (dacă se va aloca memorie,

acest obiect va fi creat, dar nu va fi posibil de-l utilizat ca componentă vizuală), pentru ca indica obiectele create mai sus să fie vizibile pe formă, vom scrie:

for(i=0;i<nr;i++) obieect[i]->Parent=Form1; 5) Se utilizează obiectele în cadrul aplicaţiei 6) Se eliberează memoria ocupată de obiectele respective. for(int i=0;i<nr;i++) obiect[i] ;/*se eliberează memoria

Page 104: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 105 -

ocupată de fiecare obiect*/ delete obiect;//se eliberează adresa de memorie ocupată de

fiecare obiect

Exemplu rezolvat

1. Pe supraţa formei vor fi plasate următoare componete: O cutie de editare, în cadrul căreia utilizatorul va introduce numărul de

obiecte. O cutie Label pentru afişarea rezultatului. Trei componete TButton.

De elaborat o aplicaţie care va permite utilizatorului să introducă un număr, care să reprezinte numărul de cutii de tip TEdit. În aceste cutii utilizatorul va introduce cîte o valoare numerică. La efectuarea unui click pe butonul determina suma, în Label1 va fi scrisă valoarea sumei, iar efectuarea unui click pe butonul Distruge obiectele create, obiectele create vor dispărea de pe formă.

Realizare Pentru comoditatea vor mai fi create dinamic şi obiecte de tip TLabel,

Pentru a sugera utilizatorului introducerea valorilor numerice în cutiile TEdit recent create

1) File/New/Application 2) Plasăm componentele pe formă, şi modificăm proprietatea caption (Fig.1)

Fig.1 Forma în timpul proiectării

3) Prelucrăm evenimentele (Unit1.cpp) 4) Salvăm şi lansăm în execuţie aplicaţia (Fig. 2)

Page 105: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 106 -

Fig.2 Aplicaţia în execuţie

Fişierul Unit1.cpp #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; int n; TEdit **Edit; TLabel **Label; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::Button1Click(TObject *Sender){ int s=0; for(int i=0;i<n;i++) s+=Edit[i]->Text.ToInt(); Label1->Caption="Suma este: "+AnsiString(s); } void __fastcall TForm1::Button2Click(TObject *Sender){ n=Edit1->Text.ToInt(); Edit = new TEdit *[n]; Label=new TLabel *[n]; for(int i=0;i<n;i++) { Edit[i] = new TEdit(this); Label[i]=new TLabel(this); Edit[i]->Parent = Form1; Label[i]->Parent = Form1; Label[i]->Caption="Introdu valoarea "+AnsiString(i+1); Edit[i]->Top = i*25+70; Edit[i]->Left = 120; Edit[i]->Width = 50; Edit[i]->Height = 23; Label[i]->Top = i*25+70; Label[i]->Left = 20;

Page 106: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 107 -

Label[i]->Height = 23; } } void __fastcall TForm1::Button3Click(TObject *Sender){ for(int i=0;i<n;i++) { delete Edit[i] ; delete Label[i]; } delete Edit; delete Label; } 2. Să se creze o aplicaţie care va permite să creeye în mod dinamic o formă, iar pe suprfaţa acestieia să conţină n cutii de edutare. În fiecare din aceste cutii se va scrie valori numerice generate în mod aleator. Valorea maximală şi minimală va fi colorată. Forma principală a plicaţiei va connţine două butoane, unul pentru crearea dinamică a formei şi altul pentru distrugerea ei, deasemeni va mai conţine o cutie de editare, prin intermediul căreia utilizatorul va introduce valoarea n.

Realizare 1) File/New/Application 2) Plasăm componentele pe formă, şi modificăm proprietatea caption (Fig.3)

Fig.3 Forma în timpul proiectării

3) Prelucrăm evenimentele (Unit1.cpp) 4) Salvăm şi lansăm în execuţie aplicaţia (Fig. 4)

Page 107: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 108 -

Fig.4 Aplicaţia în execuţie

Fişierul Unit1.cpp #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; int n; TEdit **Edit; TForm *Forma; TButton *Buton; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::Button2Click(TObject *Sender){ Forma= new TForm(this); Forma->Caption="Vector"; n=Edit1->Text.ToInt(); Edit = new TEdit *[n]; for(int i=0;i<n;i++){ Edit[i] = new TEdit(this); Edit[i]->Parent = Forma; Edit[i]->Top = 50; Edit[i]->Left = 50+i*50; Edit[i]->Width = 50; Edit[i]->Height = 50; Edit[i]->Text=AnsiString(random(100)); } int max,min,p1,p2,y; max=min=Edit[0]->Text.ToInt(); for(int i=1;i<n;i++){ y=Edit[i]->Text.ToInt(); if(max<y) {max=y;p1=i;} if(min>y) {min=y;p2=i;} } Edit[p1]->Color=clMoneyGreen; Edit[p2]->Color=clSkyBlue;

Page 108: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 109 -

Forma->Show(); } void __fastcall TForm1::Button1Click(TObject *Sender){ for(int i=0;i<n;i++) delete Edit[i]; delete Edit; delete Forma; }

Page 109: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 110 -

Capitolul II Prelucrarea bazelor de date

§ 1. Noţiuni generale

O baza de date (BD) reprezintă o modalitate de stocare a unor informaţii (date) pe un suport extern, cu posibilitatea regăsirii acestora. În BCB baza de date este un spaţiu în memorie organizat într-un anumit mod pentru păstrarea grupurilor de date. Sistemul de gestiune a bazelor de date (SGBD) realizează întreţinerea BD şi accesul la datele bazei.

Grupurile de date în Borland C++ Builder sînt prezentate prin tabele şi funcţii de păstrare. Prin înregistrări se are în vedere liniile tabelelor.

Calculatoarele pe care se plasează bazele de date se numesc servere, iar cele de pe care sînt accesate datele se numesc clienţi. Bazele de date pot fi de diferite tipuri:

bazele de date locale pot fi de tipul Paradox, dBase, Access, etc. prin reţea: InterBase, Informix, SyBase, Oracle, etc.

1.1.Crearea unui alias

Pentru a accesa o sursă de date, o aplicaţie BCB utilizează mecanismul

BDE (Borland Database Engine). Acest mecanism serveşte pentru managementul bazelor de date, fiind un mediator între program şi baza de date. Pentru crearea unei conexiuni cu baza de date, BDE utilizează un alias.

Aliasul (sau pseudonimul) unei BD descrie setările conexiunii la baza de date. Tabelele sînt stocate într-o bază de date. O bază de date de tip Paradox sau de tip dBase, de regulă, este formată din cîteva fişiere (spre deosebire de o bază de date Acces), toate fiind incluse în acelaşi catalog. Adresa acestui catalog este stocată într-un fişier de configurare. Această abordare oferă posibilitatea de a avea uşor acces la date fără a recompila programul.

Page 110: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 111 -

Pentru crearea unui alias: 1. Lansăm BDE Administrator (Start\Programs\Borland C++ Builder\BDE

Administrator). 2. În opţiunea Database alegem tipul aliasului (sau a bazei de date). Vom

alege tipul BCDEMOS. Apare pagina Definitions, în care descriem caracteristicile bazei de date.

3. Din meniul Object alegem comanda New. Apare fereastra New Database

Alias în care alegem tipul aliasului. Alegem STANDARD şi apăsăm OK.

4. În pagina Databases apare un cîmp nou cu numele iniţial STANDARD1 (numele aliasului) şi scriem numele nou (de exemplu, MyBase). În cîmpul Path indicăm locului de pe disc al aliasului.

5. În obţiunea Configuration alegem Drivers\Native\Paradox, iar în cîmpul LANGDRIVER al paginii Definition alegem driverele pentru alfabet. Salvăm aliasul prin acţionarea unui click pe opţiunea Apply din meniul Object

Page 111: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 112 -

Observaţie. La instalarea pachetului BCB, în dosarul Program Files este creat dosarul Common Files. Acest dosar conţine un set de informaţii suplimentare, printrea care şi aliasul BCDEMOS (Program Files\Common Files\Borland Shared\Data).

Page 112: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 113 -

1.2. Crearea tabelelor Pentru a crea un tabel vom folosi utilitarul DatabaseDesktop, care

permite crearea sau modificarea tabelelor de tip Paradox, dBASE şi SQL. DatabaseDesktop poate fi lansat prin selectarea comenzii DataBaseDesktop din meniul Tools al sistemului Borland C++ Builder.

În fereastra deschisă selectăm succesiv File/New /Table. Apare o feastră

de dialog în care putem alege tipul tabelului, care trebuie să coincidă cu tipul bazei de date create anterior.

Alegem Paradox7 şi acţionăm OK. Apare feastra Create Paradox Table

pentru definirea cîmpurilor tabelului.

Page 113: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 114 -

Zona Field roster este formată din patru coloane: § Field Name – numele cîmpului; § Type – tipul datelor cîmpului (se poate alege dintr-o listă care se afişează prin acţionarea tastei Space sau din meniul contextual al coloanei); § Size – dimensiunea cîmpului; § Key – stabileşte dacă cîmpul va fi cîmp-cheie primară. Un cîmp-cheie primară:

- exclude înregistrările repetate; - face ca înregistrările tabelului să fie sortate după acest cîmp.

Butonul Borrow... oferă posibilitatea crearii uni tabel după un model deja existent. La efectuarea unui clic pe acest buton apare o fereastră din care se alege modelul (ulterior tabelul poate fi modificat).

Pentru eliminarea unui cîmp îl selectăm şi apăsăm combinaţia de taste Ctrl+Delete.

1.3. Stabilirea proprietăţilor unui tabel În partea dreaptă a ferestrei se află o listă derulantă, prin intermediul

careia se pot stabili proprietăţile tabelului. Pentru un tabel pot fi stabilite următoarele opţiuni:

Page 114: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 115 -

§ Validity Checks asigură o completare mai bună a datelor prin verificarea lor după următorii parametri: ü Minimul value – valoarea minimă; ü Maximum value – valoarea maximă; ü Default value – valoarea implicită; ü Picture – specifică tipul informaţiei care urmează a fi plasată (crează o

mască pentru introducerea datelor; de exemplu, masca [-]#*# permite utilizatorului să scrie doar numere întregi negative sau pozitive, iar masca #*# – doar a celor pozitive); Butonul Assist... afişează o fereastră prin care utilizatorul poate alege o

mască pentru caseta Picture. § Table Lookup permite introducerea valorilor în masă, folosind datele existente dintr-un alt tabel. § Secondary Indexes este un index care permite sortarea datelor nu doar după cîmpul cheie-primară. Cu ajutorul acestui index se poate indica: ü o nouă sortare a datelor; ü cîmpul, care poate lega tabelul cu alt tabel; ü o metodă de căutare.

Un tabel poate avea mai multe tipuri de index cum ar fi: ü Unique interzice înregistrările cu aceleaşi valori într-un anumit cîmp; ü Case Sensitive face diferenţă dintre majuscule şi minuscule în timpul

sortării; ü Maintained (poate fi activat doar dacă nu este activat Unique) reinoieşte

indexul; ü Descending stabileşte sortarea descrescătoare a înregistrărilor.

§ Referential Integrity stabileşte proprietăţile relaţiei dintre două tabele. Între două tabele de tip paradox poate fi creată o relaţie „Parinte – Copil”, unde tabelul de tip „Copil” primeşte datele de la tabelul „Părinte”. § Password Security creează parole pentru protejarea tabelului de un acces neautorizat. § Table Language permite alegerea alfabetului pentru tabel.

Observaţie. Tabelele create se salvează în catalogul bazei de date sau a aliasului acestei baze.

Page 115: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 116 -

§ 2. Realizarea accesului la date

Pentru organizarea şi gestionarea bazelor de date Borland C ++ Builder

oferă următoarele palete de componente: § Data Access (include componente nevizuale concepute pentru accesul la date, care sînt comune tuturor tehnologiilor); § BDE (conţine componente pentru gestionarea bazelor de date, care permit crearea legăturilor dintre program şi baze de date de diferite formate); § dbExpress (conţine componente de acces la date prin intermediul mecanismului dbExpress); § ADO (conţine componente de acces la date prin intermediul mecanismului ADO); § InterBase (conţine componente de acces a datelor la distanţă, adică prin reţea); § Data Controls (conţine componente pentru afişarea şi listarea datelor); § Decision Cube (conţine componente, prin intermediul cărora se analizează datele provenite de la o sursă de date a unei structuri multidimensionale); § Quick Reports (conţine componente pentru generarea rapoartelor).

2.1. Clasa TTable

Cel mai simplu mod de accesare a tabelelor unei BD, este utilizarea

clasei TTable. Componenta Table se află pe paleta de componente BDE. Ea asigură o legătură directă cu tabelele unei BD.

Unele proprietăţi ale clasei TTable § Active (de tip bool) permite (pentru valoarea true) sau interzice accesul către tabel. § Bof (de tip bool) determină dacă cursorul se află (pentru valoarea true) sau nu la începutul tabelului. § Eof (de tip bool) determină dacă cursorul se află (pentru valoarea true) sau nu la sfîrşitul tabelului. § Database Name indică numele sau pseudonimul bazei date. § TableName specifică numele tabelului. § TableType indică tipul tabelului. Valori posibile: ttDefault, ttParadox, ttDBase, ttFoxPro, ttASCII.

Page 116: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 117 -

§ DefaultIndex (de tip bool) stabileşte dacă la deschiderea tabelului înregistrările lui vor fi afişate (pentru valoarea true) sau nu în ordinea cîmpului-cheie primară. § Exclusive (de tip bool) intrezice (pentru valoarea truei) sau permite accesul altei aplicaţii către tabel atunci cînd acesta este deschis. § ReadOnly (de tip bool) stabileşte dacă datele din tabel vor putea fi (pentru valoarea false) sau nu modificate. § FieldValues permite scrierea/citirea datelor din cîmpurile tabelului. Pentru citire vom scrie: Nume_tabel->FieldValues["Nume_Cimp"]="Valoare"; iar pentru citire: V = Nume_tabel ->FieldValues["Nume_Cimp"], unde V este o variabilă de tipul cîmpului. De exemplu, instrucţiunea

Label1->Caption=Table1->FieldValues["Nume"]; păstrează în titlul etichetei Label1 valoarea din cîmpul Nume a înregistrării curente (adică a celei aflate în focar). § Fields (de tip TFields) conţine lista cîmpurilor tabelului. Prin intermediul acestei proprietăţi compuse se poate lucra cu cîmpurile tabelului. Subproprietatea Count specifică numărul de cîmpuri ale listei. Fields conţine propria subproprietate Fields[I] (de tip TField), aceasta specificînd cîmpul cu indicele I. Primul cîmp are indicele 0. De exemplu, instrucţiunea

Edit1->Text=Table1->Fields->Fields[0]->FieldName; păstrează în caseta Edit1 numele primului cîmp al tabelului Table1 (se consideră că tabelul a fost în prealabil deschis cu metoda Open() a tabelului). Unele metode ale clasei TTable § CreateTable() cează un tabel. § DeleteTable() distruge tabelul activ din baza de date. § EmptyTable() şterge toate înregistrările din tabel. § Open() deschide tabelul. § Close() închide tabelul. § First(), Last(), Next(), Prior() plasează focarul pe prima, respectiv ultima, următoarea, precedenta înregistrare din tabel. La deschiderea tabelului, în focar se află prima înregistrare. § MoveBy(n) mută focarul pe înregistrarea a n-a. § Insert() inserează o înregistrare vidă. § Delete() sterge înregistrarea activă (adică cea din focar). § Append() adaugă o înregistrare vidă la sfîrşitul tabelului. § Post() salvează modificările tabelului în BD. § Cancel() anulează salvarea efectuată de metoda Post().

Page 117: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 118 -

2.2. Clasa TDBGrid

Componenta TDBGrid (de tip TDBgrid) se află pe paleta de componente DataControls. Ea creează o reţea pentru afişarea informaţiei unui tabel (de tip TTable). Unele proprietăţi ale clasei TDBGrid § DataSource specifică sursa, prin intermediul căreia se va extrage informaţia. Valoarea acestei proprietăţi este numele unei componente de tip TDataSourse. § Colums descrie coloanele care vor fi afişate în reţea § Color determină culoarea de fundal a reţelei. § FixedColor specifică culoarea pentru cîmpuri. § Options stabileşte diferite opţiuni pemtru reţea. De exemplu, dacă opţiunea dgEditing este activă, atunci datele pot fi redactate. § TitleFont specifică formatul textului pentru cîmpurile tabelului.

2.3. Clasa TDataSource

Componenta DataSource (de tip TDataSource) se află pe paleta de componente DataAcces şi se utilizează pentru a crea legătura dintre componentele Table şi DBGrid. Unele proprietăţi ale clasei TDataSourse § AutoEdit (de tip bool) permite (pentru valoarea true) sau interzice editarea datelor. § DataSet specifică setul de date. Valoarea acestei proprietăţi poate fi numele unei componente de tip TTable. Prin urmare, pentru afişarea înregistrărilor din tabelul Table1:

1. Plasăm pe suprafaţa formei cîte o componetă de tip TDataSource,

TDBGrid.

2. Atribuim proprietăţii DataSet a componentei DataSource1 valoarea

Page 118: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 119 -

Table1.

3. Atribuim proprietăţii DataSource a componentei DBGrid1 valoarea

DataSource1.

4. Stablim valoarea true pentru proprietatea Active a controlului Table1.

Observaţie. Evident, proprietăţile DatabaseName şi TableName ale componentei Table1 au fost setate în prealabil.

2.4. Clasa TDBNavigator Componenta DBNavigator (de tip TDBNavigator) se află pe paleta DataControls afişează un panou de instrumente care poate fi ataşat (prin intermediul proprietăţii DataSourse1) unui tabel pentru gestionarea rapidă şi comodă a înregistrărilor.

Butoanele componentei DBNavigator Prin intermediul proprietăţii VisibileButtons se poate stabili care dintre butoanele panoului DBNavigator vor fi vizibile. § First stabileşte cursorul pe prima înregistrare. § Prior stabileşte cursrul pe înregestrarea precedentă. § Next stabileşte cursorul pe înregistrarea următoare. § Last stabileşte cursorul pe ultima înregistrare. § Insert inserează o înregistrare vidă şi activează regimul de editare. § Delete şterge înregistrarea curentă şi poziţionează cursorul pe următoarea înregistrare.

Page 119: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 120 -

§ Edit activează pentru înregistrarea curentă regimul de editare.

§ Post salvează modificarile efectuate în setul de date. § Cancel ignoră redactarea înregistrărilor curente. § Refresh reînoieşte datele din setul de date active. Exemplu rezolvat Să creăm un tabel de tip Paradox (avînd numele Muncitori) cu următoarea cîmpuri:

Numele cîmpului Tipul cîmpului Nume Şir de caractere (Alpha) Prenume Şir de caractere (Alpha) Anul_ang Numeric (Number) Categoria Numeric (Number) Sal_Calculat Numeric (Number) Impozite Numeric (Number) Sal_Primit Numeric (Number)

Astfel, Nume, Prenume sînt respectiv numele şi prenumele salariatului, Anul_ang – anul cînd acesta a fost agajat, Categoria – categoria salariului, Sal_Calculat – salariul, Impozite – suma de bani care este reţinută pentru impozite, Sal_primit – salariul care urmează a fi primit de către angajat. Considerăm că impozitul este de 8%

Utilizatorul va completa doar cîmpurile Nume, Prenume, Categoria (care poate fi 1, 2 sau 3) şi Anul_ang. Aplicaţia va calcula salariul fiecărui angajat utilizînd următoarele formule: ü Salariul de bază este egal cu numărul ore*zile, unde ore şi zile sînt

constante egale respectiv cu 8 şi 24. ü Dacă muncitorul are categoria 1 (respectiv 2, 3), atunci el are un adaos

de 20 % (respectiv 50 %, 80 %) la salariul de bază. ü Muncitorii cu o vechime în muncă mai mare de 5 ani (respectiv 15 ani)

primesc un adaos de 10% (respectiv 20%) din salariu calculat după adaosul categoriei.

Page 120: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 121 -

Considerăm impozitul pe venit egal 8%, din salariul calculat împreună cu vechimea în muncă, asigurarea medicală – 4%, iar fondul social – 5% din salariul calculat. Realizare Vom afla salariul calculat (sc), impozitele (Impozit) şi salariul primit (Sal_primit) după formulele: sc = ore*zile*coef_cat, unde coef_cat este egal cu 1,2, sau 1,5, sau 1,8; Dacă vecimea în muncă este mai mare decît 15 ani (respectiv 5 ani), atunci sc+ = sc*0,2 ( respectiv sc+ = sc*0,1). Impozit = impozitul pe venit + asigurarea medicală + fondul social. Sal_primit = sc – Impozit. 1. Creăm un alias în care vom păstra tabelul (vezi § 1).

2. Lansăm Database Descktop şi creăm tabelul Muncitori conform enunţului.

3. Salvăm tabelul Muncitori în aliasul creat la pasul 1.

4. Introducem datele în tabel (proprietatea Name a tabelului are valoarea

Table1).

5. Plasăm pe formă cîte o componentăde tip TDataSourse, TDBGrid, TButton.

Page 121: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 122 -

6. Atribuim proprietăţii DataSet a componentei DataSource1 valoarea Table1.

7. Atribuim proprietăţii DataSource a componentei DBGrid1 valoarea

DataSource1.

8. Stablim valoarea true pentru proprietatea Active a controlului Table1.

9. Prelucrăm evenimentul OnClick al butonului de comandă.

10. Salvăm şi lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #define anul_curent 2009 #pragma resource "*.dfm"

Page 122: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 123 -

TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){} void __fastcall TForm1::Button1Click(TObject *Sender){ double sc,imp,iv,fs,am; int cat,anul,ore,zile; ore=8; zile=24; Table1->First(); while(!Table1->Eof)// cit timp nu sîntem la ultima inregistrare { cat=Table1->FieldValues["Categoria"]; anul=Table1->FieldValues["Anul_Ang"]; switch(cat) { case 1: sc=1.2*ore*zile; break; case 2: sc=1.5*ore*zile; break; case 3: sc=1.8*ore*zile; break; } if(anul_curent-anul>=15) sc+=sc*0.2; else if(anul_curent-anul>=5) sc+=sc*0.1; iv=sc*0.08; fs=sc*0.05; am=sc*0.04; Table1->Edit();//Pregateste tabelul pentru a inscrie date Table1->FieldValues["Sal_Calculat"]=sc; Table1->FieldValues["Impozite"]=fs+am+iv; Table1->FieldValues["Sal_Primit"]=sc-fs-am-iv; Table1->Post();//Salveaza modificarele efectuate in tabel Table1->Next();//trece la urmatoarea inregistrare } }

§ 3. Alte componente ale paletei Data Controls

În afară de componentele DBGrid şi DBNavigator pe paleta DataControls se află următoarele controale:

§ DBText este un control asemeni etichetei Label. Prin intermediul proprietăţii DataSource poate fi creată legătura dintre acest control şi un tabel sau o interogare. După crearea legăturii în proprietatea DataField se indică cîmpul, a cărui informaţie va fi afişată de componenta DBText.

Page 123: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 124 -

§ DBEdit este un control asemeni casetei de editare Edit. Se poate folosi pentru afişarea sau pentru editarea datelor unui cîmp al unei surse de date. Modalitatea de lucru este similară cu a controlului DBText.

§ DBMemo este un control asemeni zonei de editare Memo. Modalitatea de lucru este similară cu a controlului DBText. DBMemo este utilizat deseori pentru prezentarea informaţiei din cîmpurile care conţin un volum mai mare de informaţie.

§ DBImage este un control asemeni componentei Image. Este utilizat pentru reprezentarea imaginilor unei baze de date.

§ DBListBox reprezintă o listă asemeni controlului ListBox. Conţinutul listei este valoarea proprietăţii Items (de tip TStrings). Astfel, pentru a adăuga în lista DBListBox1 informaţia din cîmpul Virsta al tabelului Table1 se vor scrie instrucţiunile:

while(!Table1->Eof){ DBListBox1->Items->Add(AnsiString(Table1-> FieldValues["Virsta"])); Table1->Next(); };

De regulă, componenta DBListBox nu se foloseşte pentru încărcarea înregistrărilor unei baze de date (pentru aceasta există controlul DBLookupListBox).

§ DBComboBox este un control asemeni casetei combinate ComboBox. Modalitatea de lucru este similară cu a componentei DBListBox.

§ DBCheckBox este un control asemeni casetei de validare CheckBox şi, de regulă, este utilizat pentru afişarea valorilor unui cîmp de tip logic.

§ DBRadioGroup este un control asemeni butonului RadioGroup.

Page 124: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 125 -

§ DBLookupListBox se utilizeză pentru crearea casetelor de căutare a înregistrărilor

§ DBLookupComboBox este un control asemeni controlului DBLookupListBox.

§ DBRichEdit este un control asemeni controalelor DBEdit şi DBMemo.

§ DBChart este un control pentru crearea diagramelor pe baza informaţiei tabelelor unei baze de date (modalitatea de creare este asemănătoare cu cea din Microsoft Excel).

Exemple rezolvate 1. Să elaborăm o aplicaţie prin intermediul căreia utilizatorul va putea modifica cîmpul Categoria al tabelulului Muncitori (creat în paragraful anterior). În cîmpul Categoria pot fi introduse valori de la 1 la 5. Realizare: Pentru prezentarea informaţiei din tabel vor fi utilizate componente de tip DBText, iar pentru navigarea datelor tabelului va fi utilizată o componentă de tip TDBNavigator. Prin intermediul butonului Post şi a componentei de tip TDBListBox, va fi posibilă modificarea cîmpului Categoria. În cadrul proprietăţii Items a componentei vor fi introduse valori de la 1 la 5.

1. Considerăm aliasul şi tabelul Muncitori create, iar componentele Table1 şi DataSourse1 plasate pe formă (vezi § 1 şi exemplul rezolvat din § 2), precum şi setate proprietatea DataSet a componentei DataSourse1 şi proprietatea Active a componentei Table1. 2. Plasăm pe formă 5 componente de tip TDBText, cîte o componentă de tip TDBListBox, TDBNavigator. 3. Creăm legătura între sursă şi controlul DBNavigator1: atribuim proprietăţii DataSourse a componentei DBNavigator1 valoarea DataSourse1.

Page 125: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 126 -

4. Setăm proprietăţile DataField şi DataSourse ale componentelor DBText astfel:

5. Salvăm şi lansăm aplicaţia la execuţie.

Pentru editarea cîmpului Categoria utilizatorul se va deplasa la inregistrarea necesară, după care va alege una din valorile date în cutie şi va

efectua un click pe butonul Post . 2. Considerăm tabelul Muncitori (creat un exemplele precedente), în care a fost adăugat cîmpul NrOrdine. Considerăm creat în acelaşi alias încă un tabel, numit Locuinta şi format din cîmpurile Adresa şi NrOrdine (ultimul este cîmp cheie-primară). Să elaborăm o aplicaţie care va pune în corespondenţă fiecărui muncitor o adresă din cîmpul Adresa. Deci, între tabelele Locuinta şi Muncitori se va stabili o relaţie de tipul unu la mulţi.

Page 126: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 127 -

Realizare: 1. Considerăm create aliasul şi tabelele Muncitori şi Locuinta, iar componentele Table1, Table1, DataSourse1, DataSourse2, TDBText1, TDBText2, TDBText3 plasate pe formă (vezi § 1 şi exemplul rezolvat din § 2), precum şi setate proprietatea DataSet ale componentelor DataSourse1, DataSourse2, proprietatea Active ale componentelor Table1, Table2, proprietăţile DataField şi DataSourse ale componentelor de tip TDBText. 2. Plasăm pe formă o componentă de tip TDBLookupComboBox. 3. Creăm relaţia între tabele (după cîmpul NrOrdine) prin intermediul componentei DBLookupComboBox1. Setăm proprietăţile componentei DBLookupComboBox1 astfel:

DataSource=DataSource1 DataField=NrOrdine ListSource= DataSource1 KeyField= NrOrdine ListField=Adresa

4. Salvăm şi lansăm aplicaţia la execuţie.

3. Să creăm o diagramă cu bare pentru salariul muncitorilor înregistraţi în tabelul Muncitori. Realizare: 1. Considerăm aliasul şi tabelul Muncitori create, iar componentele Table1 şi DataSourse1 plasate pe formă (vezi § 1 şi exemplul rezolvat din § 2), precum şi setate proprietatea DataSet a componentei DataSourse1 şi proprietatea

Page 127: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 128 -

Active a componentei Table1. 2. Plasăm pe formă o componentă de tip TDBChart. 3. Efectuăm double-click pe componenta DBChart1. 4. Efectuăm click pe butonului Add şi alegem tipul diagramei (Bar). 5. Indicăm titlul (butonul Title).

6. Îndicăm sursa (tabelul din care vor fi extrase datele): din paleta Series alegem pagina DataSource, iar de aici DataSet. Efectuăm modificările necesare.

Page 128: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 129 -

6. Executăm un click pe butonul Close. Pe formă apare diagrama:

Page 129: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 130 -

§ 4. Interogări

Interogarea este un obiect, prin intermediul căruia din baza de date se extrag înregistrări, care corespund condiţiilor indicate. Cu ajutorul interogărilor se pot vizualiza, analiza şi modifica datele din tabele. Pentru crearea interogărilor, BCB oferă componenta Query, care se află pe paleta DBE. Interogările se scriu în limbajul SQL.

4.1. Tipuri de interogări ● Interogările de selecţie sînt cele mai des solicitate interogări şi se

creează utilizînd cuvîntul cheie SELECT. Sintaxa generală a unei cereri de interogare:

SELECT [domeniu] listă_selecţie FROM nume_tabel1, nume_tabel2,… [WHERE criteriu_selecţie] [HAVING criteriu_de_grupare] [ORDER BY cîmpuri_criteriu];

unde domeniu specifică o opţiune de includere sau de eliminare din rezultatul selecţiei, a înregistrărilor care conţin duplicate. Listă_selecţie cuprinde cîmpurile ce vor apărea în tabelul cu rezultatele interogării. Clauza FROM specifică numele tabelului sau al tabelelor pe care se face cererea de interogare. Pentru mai multe tabele, numele acestora se separă prin virgulă. Clauza WHERE este opţională şi specifică doar înregistrările care îndeplinesc criteriul de selecţie. Criteriul de selecţie este o expresie care conţine obligatoriu şi un operator adecvat tipului de dată al cîmpului respectiv. Clauza ORDER BY (de asemenea este opţională) cere ordonarea rezultatelor interogării. Ordonarea se poate face după unul sau mai multe cîmpuri_criteriu. Clauza HAVING conţine criteriul care va fi aplicat cîmpului argument al funcţiei agregat. Spre deosebire de WHERE, care acţionează înainte de gruparea înregistrărilor, HAVING acţionează după definirea acesteia.

Page 130: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 131 -

● Interogările de acţiune tip INSERT sînt folosite pentru adăugarea de înregistrări dintr-un tabel în altul. Există două forme ale instrucţiunii şi anume: a) INSERT ... VALUES În acest caz se adaugă o singură înregistrare într-un tabel, menţionînd cîmpurile şi valorile acestora. Se utilizează pentru operaţii simple, care presupun lucrul cu un număr redus de înregistrări.

INSERT INTO nume_tabel (cîmp1, cîmp2...) VALUES (valoare1, valoare2...);

b) INSERT ... SELECT În acest caz, este posibil să se copieze mai multe înregistrări dintr-un tabel în unul sau mai multe tabele.

INSERT INTO tabel_destinaţie (cîmp1, cîmp2...) SELECT [domeniu] cîmp1, cîmp2... FROM tabel_sursă WHERE criteriu_de_adăugare;

● Interogările de acţiune tip DELETE şterg parţial sau total

înregistrările dintr-un tabel. Nu se foloseşte pentru ştergerea de valori din cîmpuri individuale, ci acţionează asupra înregistrării în totalitatea ei.

DELETE FROM nume_tabel [WHERE criteriu_de_ştergere];

Ca şi instrucţiunea INSERT, operaţia de ştergere a înregistrărilor unui tabel poate duce la probleme de integritate referenţială în alte tabele. Exemplu: DELETE * FROM Vînzări DELETE * FROM Angajaţi WHERE Vîrsta>60

● Interogările de acţiune tip UPDATE pot introduce înregistrări noi şi pot modifica valorile cîmpurilor din înregistrări existente. UPDATE nume_tabel

SET nume_cîmp1=valoare1 [,nume_cîmp2=valoare2]... [WHERE criteriu_de_actualizare];

Exemplu: UPDATE Comunicaţii SET Reţea=”Orange” WHERE Reţea=”Dialog” AND Data>#12.12.2001;

Page 131: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 132 -

4.2. Clasa TQuery

Componenta Query poate fi utilizată atît în lucru cu BD locale, cît şi cu BD îndepărtate.

Unele proprietăţi ale clasei TQuery § DatabaseName indică numele pseudonimului BD. § Params reprezinta o serie de copii ale unui obiect TParam şi determină caracteristicile tuturor parametrilor de interogare. § SQL (de tip TStrings) conţine textul de interogare SQL, care va fi executat la invocarea metodelor Open sau ExecSQL. § Text conţine textul interogării. § DataSource reprezintă sursa. Unele metode ale clasei TQuery § ExecSQL() execută interogarea conţinută în cadrul proprietăţii SQL. § Open() execută cererea. § Prepare() asigură resursele necesare ca cererea să poată fi realizată. Exemplu rezolvat Să elaborăm o aplicaţie care va permite efectuarea următoarelor interogări pentru tabelul Muncitori (creat un exemplele precedente):

- Afişarea muncitorilor cu salariu mai mare decît 300 (de unităţi convenţionale);

- Afişarea muncitorilor cu salariu mai mic decît 300; - Afişarea muncitorilor angajaţi pînă în 1990; - Afişarea muncitorilor angajaţi după 1990; - Afişarea tuturor muncitorilor.

Realizare: 1. Considerăm aliasul şi tabelul Muncitori create, iar componentele Table1 şi DataSourse1 plasate pe formă (vezi § 1 şi exemplul rezolvat din § 2), precum şi setate proprietatea DataSet a componentei DataSourse1 şi proprietatea Active a componentei Table1.

Page 132: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 133 -

2. Plasăm pe suprafaţa formei componentele Query1 (pentru efectuarea interogării), DBGrid1 (pentru vizualizarea datelor), DataSource (pentru crearea legăturii dintre Query1 şi DBGrid1), RadioGroup1 (pentru alegerea interogării). 3. Efectuăm conexiunea controalelor Query1 (setăm proprietăţile DatabaseNamei şi DataSource) şi DBGrid1 (setăm sursa). 4. Scriem conţinutul interogărilor în vectorul s (vezi fişierul Unit1.cpp). 5. Prelucrăm evenimentul RadioGroup1Click. 6. Salvăm şi lansăm aplicaţia la execuţie.

Conţinutul fişierului Unit1.cpp: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; AnsiString s[6]; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){ s[1]="select nume, prenume, sal_primit from muncitori where

Page 133: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 134 -

sal_primit > 300 order by sal_primit"; s[2]="select nume, prenume, sal_primit from muncitori where sal_primit < 300 order by sal_primit"; s[3]="select nume, prenume, anul_ang from muncitori where anul_ang < 1990"; s[4]="select nume, prenume, anul_ang from muncitori where anul_ang > 1990"; s[5]="select nume, prenume, anul_ang, sal_primit from muncitori order by sal_primit"; } void __fastcall TForm1::RadioGroup1Click(TObject *Sender){ int nr=RadioGroup1->ItemIndex; switch(nr){ case 0 : Query1->SQL->Text=s[nr+1]; break; case 1 : Query1->SQL->Text=s[nr+1]; break; case 2 : Query1->SQL->Text=s[nr+1]; break; case 3 : Query1->SQL->Text=s[nr+1]; break; case 4 : Query1->SQL->Text=s[nr+1]; break; } Query1->Open(); }

§ 5. Rapoarte Un raport reprezintă o modalitate de extragere a unei informaţii din BD

cu scopul ca ulterior aceasta să fie tipărită. Prin sursa unui raport vom înţelege un tabel sau o interogare. Pentru crearea rapoartelor BCB oferă paleta de componente QReport. Vom examina unele componente ale acestei palete.

5.1. Clasa TQuickRep Componenta QuickRep (de tip TQuickRep) reprezintă o pagină, pe

suprafaţa căreia se va afişa informaţia extrasă din sursa raportului.

Unele proprietăţi ale clasei TQuickRep § Bands (de tip logic) permite afişarea benzilor. O pagină QuickRep poate conţine următoarele tipuri de benzi:

− HasColumnHeader afişează antetul fiecărei coloane.

Page 134: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 135 -

− HasDetail afişează numărul fiecărei înregistrări din tabel. − HasPageFooter stabileşte antet pentru fiecare pagină. − HasPageHeader stabileşte o notă de subsol pentru fiecare pagină. − HasSummary formează şi extrage subtotalurile. − HasTitle permite afişarea unui titlu pentru raport.

§ DataSet stabileşte legătura dintre raport şi înregistrări (valoarea acestei proprietăţi poate fi de tipul TQuery şi TTable). § Description păstrează comentarii. § Options este o proprietate compusă, avînd următoarelor proprietăţi:

− FirstPageHeadear stabileşte dacă va fi afişat sau nu antetul pe prima pagină.

− LastPageHeadear stabileşte dacă va fi afişată sau nu nota de subsol pe ultima pagină.

− Compression indică dacă se va păstra sau nu raportul în memorie în momentul proiectării.

§ Page este o proprietatea compusă şi stabileşte parametrii paginii. § PrinterSettings indică modul de tipărire a raportului. § ReportTitle specifică titlul raportului.

5.2. Clasa TQRBand Componenta QRBand (de tip TQRBand) este un container pentru plasarea diferitor tipuri de obiecte (antet, subsol etc.), prin intermediul cărora se va extrage informaţia. Unele proprietăţi ale clasei TQRBand § BandType indică modul de repezentare a informaţiei (asemenea proprietăţilor Bands a controlului QuickRep). § ForceNewColummn (de tip logic) specifică dacă fiecare înregistrare va începe din rînd nou (pentru valoarea true) sau nu. § ForceNewPage (de tip logic) specifică dacă fiecare înregistrare va începe (pentru valoarea true) pe o pagină nouă sau nu.

5.3. Clasa TQRDBText Componenta QRDBText (de tip TQRDBText) se utilizează pentru extragerea datelor. Fiecare cîmp care urmează a fi afişat va avea propria

Page 135: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 136 -

componentă QRDBText, care poate fi configurată prin intermediul proprietăţilor DataSet şi DataField. Exemplu rezolvat

Vom crea un raport pe baza tabelului Muncitori (utilizat mai sus). Realizare: 1. Considerăm aliasul şi tabelul Muncitori create, iar componentele Table1 şi DataSourse1 plasate pe formă (vezi § 1 şi exemplul rezolvat din § 2), precum şi setate proprietatea DataSet a componentei DataSourse1 şi proprietatea Active a componentei Table1. 2. Plasăm pe formă cîte un control de tip TButton (pentru viualizarea prealabilă a raportului) şi TQuickRep. 3. Atribuim proprietăţii DataSet a controlului QuickRep valoarea Table1. 4. Plasăm 4 componente de tip TQRLabel şi 4 componente de tip TQRDBText. Setăm proprietăţile DataSet şi DataField a fiecărei dintre componentele QRDBText (vezi imaginea), precum şi proprietatea Caption a fiecărei dinte componentele QRLabel.

5. Plasăm pe suprafaţa raportului trei controale de tip TQRBand cu proprietatea BandType setată respectiv rbPageHeader, rbTitle, rbDetail.

Page 136: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 137 -

6. Pe componenta QRBand1 (cu BandType setată rbPageHeader) plasăm un control de tip QRLabel şi scriem proprietatea Caption a acestuia numele raportului (Lista angajatilor). 7. Pe componenta QRBand2 (cu BandType setată rbTitle) plasăm 4 controale de tip QRLabel, care vor indica denumirle celor 4 cîmpuri. 8. Pe componenta QRBand2 (cu BandType setată rbDetail) plasăm 4 controale de tip QRDBText pentru extragerea textului pe suprafaţa raportului. Pentru fiecare din aceste 4 controale, atribuim proprietăţii DatSet valoarea Table1, iar proprietăţii DataField – numele cîmpului respectiv. 9. Pentru vizualizarea informaţiei din raport din meniul contextual al componentei QuickRep1 alegem Preview sau în program putem folosi o instrucţiune de forma QuickRep1->Preview(). 10. Prelucrăm evenimentul OnClick al butonului de comandă, în a cărui procedură scriem instrucţiunea QuickRep1->Preview(). 11. Salvăm şi lansăm aplicaţia la execuţie.

Page 137: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 138 -

§ 6. Tehnologia ADO

Microsoft ADO (ActiveX Data Objects) asigură acces aplicaţiilor client la date. Pentru implementarea modelului ADO Borland C++ Builder oferă paleta de componente ADO, cu ajutorul căreia se poate realiza conectarea la sursele de date suportate de ADO. Să examinăm componentele acestei palete.

Componenta ADOConnection (de tip TADOConnection) se utilizează pentru conectarea la baza de date. Mai multe seturi de date pot folosi în comun această conexiune pentru extragerea datelor şi pentru executarea comenzilor.

Componenta ADOCommand (de tip TADOCommand) execută comenzi SQL care nu generează date. Poate fi folosită cu o altă componentă ADO de tip TDataSet.

Componenta ADODataSet (de tip TADODataSet) se foloseşte pentru extragerea şi operarea datelor din una sau mai multe tabele. Conexiunea se poate face direct cu sursa de date sau printr-o componentă de tip TADOConnection.

Componenta ADOTable (de tip TADOTable) reprezintă un set de date sub formă de tabel folosit pentru extragerea şi operarea unui set de înregistrări produs de o singură tabelă din BD. Poate fi conectată direct cu sursa de date sau poate folosi o conexiune existentă.

Componenta ADOQuery (de tip TADOQuery) este un set de date de tip interogare care poate extrage un set de înregistrări bazat pe o comandă validă SQL. Conexiunea se poate face direct cu sursa de date sau printr-o componentă de tip TADOConnection..

Componenta ADOStoredProc (de tip TADOStoredProc) se foloseşte pentru execuţia funcţiilor stocate care pot sau nu să genereze date.

Page 138: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 139 -

6.1. Conectarea la o sursă de date Unul sau mai multe componente pot folosi împreuna o singură conexiune la o sursă de date utilizînd (în timpul proiectării aplicaţiei) proprietatea Connection a componentei ADOConnection.

Înainte de a se putea folosi conexiunea trebuie identificată sursa de date la care se doreşte conectarea. De regulă, se foloseşte proprietatea ConnectonString (de tip şir de caractere) a aceleiaşi componente. Simbolul ; se foloseşte pentru a delimita parametrii conexiunii.

Parametri posibili:

§ Provider specifică numele unui ADO provider utilizat cu conexiunea respectivă. § File name reprezintă numele unui fişier, care conţine informaţiile despre conexiune. § Remote Provider este numele unui ADO provider care există pe o altă staţie. § Remote Server este numele serverului, în cazul în care se foloseşte o altă staţie.

6.2. Conectarea la o bază de date de tip MS Access

Pentru efectuarea conexiunii cu o bază de date MS Access:

1. Executăm un click pe butonul a proprietăţii ConnectionString.

Apare următoare fereastră de dialog:

Page 139: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 140 -

2. Alegem opţiunea Use Connection String şi apăsăm butonul Build.

Apare fereastra de dialog Data Link Properties.

3. Alegem Microsoft OLE DB Provider for ODBC Drivers şi apăsăm

butonul Next.

4. Apare pagina Connection a aceleiaşi ferestre. Selectăm Use connection

String, apoi apăsăm butonul Build.

Page 140: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 141 -

5. În fereastra apărută Select Data Source apăsăm pe butonul New.

Page 141: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 142 -

6. Apare fereastra Create New Data Source în care alegem opţiunea

Microsoft Acces Driver (*.mdb) şi efectuăm un click pe butonul Next.

7. Cu ajutorul butonului Browse indicăm adresa, la care va fi salvat

fişierul de tip .dsn.

Page 142: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 143 -

8. Executăm un click pe butonul Next.

9. În fereastra apărută sînt afişate adresa fişierului creat şi tipul bazei de

date. Executăm un click pe butonul Finish.

Page 143: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 144 -

10. Apare fereastra ODBC Microsoft Access Setup. Apăsăm butonul Select.

11. Apare fereastra Select Database.

12. Alegem baza de date şi efectuăm un click pe butonul OK. Din acest

moment conexiunea cu baza de date este creată.

După stabilirea conexiunii pot fi utilizate componentele pentru

prelucrarea informaţiei din baza de date.

Page 144: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 145 -

Exemplu rezolvat Considerăm tabelul Autori al bazei de date Biblioteca, creată cu MS Access. Să creăm o aplicaţie care va afişa datele dintru-un tabel MS Access. Realizare: 1. Plasăm pe formă cîte o componentă de tip TADOConnection, TADOTable (de pe paleta ADO), TDataSource (de pe paleta Data Acess), TDBGrid (de pe paleta Data Controls). 2. Atribuim proprietăţilor Connection şi TableName ale componentei ADOTable1 respectiv valorile ADOConection1 şi Autori. 3. Atribuim valoarea ADOTable1 proprietăţii DataSet a componentei DataSource1. 4. Atribuim proprietăţii DataSource a controlului DBGrid1 valoarea DataSource1. 5. Stabilim proprietăţii Active a componentei ADOTable1 valoarea true. 6. În DBGrid1 vor apărea datele din tabelul Autori.

7. Compilăm proiectul, apoi lansăm la execuţie fişierul executabil (din dosarul proiectului).

Page 145: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 146 -

6.3. Conectarea la o bază de date de tip MySql Spre deosebire de pachetul MS Office (în care este inclus MS Access),

interfaţa ODBC (Open DataBase Connectivity) nu conţine drivere pentru accesul la bazele de date de tip MySql. Aceste drivere pot fi descărcate gratuit de pe serverul MySql (http://www.mysql.com). După instalarea lor se poate efectua conexiunea dintre componentele BCB şi baza de date (MySql). În linii generale modalitatatea de conectare este similară conexiunii Access.

Pentru efectuarea conexiunii cu o bază de date MS Access:

1. Efectuăm un click pe butonul în dreapta proprietăţii ConnectionString a controlului ADOConection. 2. Alegem opţiunea Use Connection String şi apăsăm butonul Build. Apare fereastra de dialog Data Link Properties. 3. Alegem Microsoft OLE DB Provider for ODBC Drivers şi apăsăm butonul

Next.

4. Apare pagina Connection a aceleiaşi ferestre. Selectăm Use connection

String, apoi apăsăm butonul Build.

5. În fereastra apărută Select Data Source apăsăm pe butonul New.

6. Apare freastra Create New Data Source în care alegem opţiunea MySQL

ODBC 5.1 Driver (driverele recent instalate sau poati fi şi altă versiune), apoi

executăm un click pe butonul Next.

7. Cu ajutorul butonului Browse indicăm adresa, la care va fi salvat fişierul de tip .dsn.

Page 146: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 147 -

8. Executăm un click pe butonul Next. În fereastra apărută apare adresa

fişierului creat şi tipul bazei de date. Executăm un click pe butonul Finish.

9. Apare următoarea fereastră:

10. Indroducem datele despre adresa bazei de date. În caseta Server scriem numele serverului pe care se află baza de date (localhost – serverul local). 11. În caseta User indicăm numele user-ului pe care lucrăm (nu este un account al bazei de date). 12. În cazul în care user-ul este protejat cu parolă, aceasta se indică în caseta Password. 13. Dacă datele au fost introduse corect, atunci în lista derulantă Database apar numele bazelor de date existente (în imagine, information_schema, mysql). După selecrarea numelui bazei de date se efectuează un click pe butonul Ok. 14. Se confirmă numele conexiunii în fereastra Select Data Source. Din acest moment conexiunea este efectuată. 15. Pentru prelucrarea bazei de date urmează a fi plasate şi configurate componentele necesare.

Page 147: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 148 -

Capitolul III Programarea Orientată

pe Obiecte cu C++

§ 1. Preliminarii

Orice limbaj de programare se bazează pe o anumită ideee dominantă, care determină structura programelor create cu acest limbaj.

Din punct de vedere istoric iniţial a dominat idea structurării procedurale a programelor. Programatorul decidea ce proceduri va utiliza în program, apoi alegea cel mai potrivit algoritm pentru realizarea acestor proceduri. De exemplu, limbajul Fortran este un limbaj de programare procedurală. Acest tip de programare a dus la crearea bibliotecilor mari de proceduri.

Pe parcursul dezvoltării informaticii accentul s-a deplasat de la proceduri spre organizarea datelor. S-a ajuns la concluzia că pentru elaborarea programelor eficace era nevoie de utilizarea corectă a datelor. Ca o consecinţă logică a noii tendinţe, a apărut ideea structurării programelor cu ajutorul modulelelor (adică a unităţilor de program). În ele erau stocate nu doar subprograme, dar şi date. De exemplu, limbajul Pascal este un limbaj de programare modulară.

Ideea dominantă a programării moderne, numită Programare Orientată pe Obiecte (POO), presupune unirea datelor cu subprogramele care prelucrează aceste date într-un tot întreg, numit obiect. Această acţiune (de unire) se numeşte incapsulare, iar subprogramele unui obiect – metode. La incapsulare se ia în considerare legătura logică dintre date şi metode.

De fapt, concepţia de obiect a intervenit pentru crearea unor noi tipuri de date, care nu sînt predefinite (de exemplu, tipurile de date număr complex şi graf nu sînt definite în majoritatea limbajelor dfe programare). Aşa cum un tip de date este definit nu doar de mulţimea valorilor tipului (adică de datele propriu zis), dar şi de operatorii aplicabili asupra acestor valori, a apărut ideea incapsulării datelor şi metodelor. Pe parcursul timpului, sensul atribuit

Page 148: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 149 -

conceptului obiect a revenit conceptului clasă. Deci, o clasă defineşte un tip abstract de date, iar un obiect este o dată a acestui tip. Se mai spune că obiectul este un exemplar sau o instanţiere a clasei respective.

O caracteristică importantă a POO este ierarhizarea claselor. Sugerată de istoria dezvoltării ştiinţelor, ideea de ierarhizare presupune organizarea ierarhiilor de clase, între care există proprietăţi comune. În vîrful ierarhiei se află clasa (numită clasă de bază) care are „trăsături” comune tuturor celorlalte clase ale ierarhiei. În acelaş timp, clasele aflate pe următorul nivel al ierarhiei (numite clase derivate) pot avea „trăsături” suplimentare. În acest caz se spune că clasa de bază este clasă-părinte a acestor clase derivate. La rîndul său, fiecare clasă derivată poate fi clasă-părinte a unor clase de pe nivelul ierarhic imediat următor (de asemenea, numite clase derivate). Deci, clasele derivate “moştenesc” datele şi metodele clasei-părinte.

De exemplu, putem crea o ierarhie de clase referitoare la patrulatere, clasa de bază fiind patrulaterul convex, urmînd clasele derivate paralelogram, patrulater convex arbitrar şi clasele derivate din clasa paralelogram: romb, trapez etc.

Altă caracteristică importantă a POO, numită polimorfism, oferă posibilitatea definirii unei interfeţe comune pentru mai multe metode cu diferite funcţionalităţi. De exemplu, în cazul ierarhiei de poligoane se pot crea metode cu acelaş nume Aria (deci, aceiaş interfaţă, însă diferite funcţionalităţi).

Menţionăm că priorităţile POO se manifestă la elaborarea programelor mari.

§ 2. Clase Aşa cum clasa este un tip abstract de date, rezultă că ea este formată din

două părţi: a) partea care defineşte datele, componentele ei fiind numite date

membru; b) partea care defineşte operaţiile asupra datelor, formată din

subprograme, numite funcţii membru. Clasele de bază se declară cu ajutorul cuvîntului-cheie class, conform

următoarei diagrame de sintaxă:

Page 149: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 150 -

Definirea completă a funcţiilor membru se face mai jos, în textul programului (vezi exemplul rezolvat).

Exemple: 1. Definirea clasei complex class complex{ double Im, Re; // Im şi Re sînt datele membru double Modulul(); // metoda Modulul este funcţie membru }; 2. Definirea clasei vector class vector{ int v[100]; int maxim(); void citire(); void afisare(); };

Pentru a controla mai bine operaţiile asupra datelor clasei se foloseşte mecanismul de protejare a datelor şi a funcţiilor membru ale clasei. Cu acest scop se utilizează modificatorii de protecţie (se mai numesc specificatori de acces): private, public şi protected. Aceste atribute de protecţie au următoarea semnificaţie: § Membrii din domeniul de acţiune al modificatorului public nu sînt “protejaţi”, fiind accesibili oricărei funcţii în tot programul unde ei sînt „vizibili”. § Membrii domeniului private sînt accesibili doar funcţiilor membru. În mod implicit membrii unei clase se consideră declaraţi în domeniul private. § Membrii domeniului protected sînt accesibili doar funcţiilor membru şi funcţiilor claselor derivate din clasa în care au fost declarate aceşti membri.

Operatorul de rezoluţie :: este utilizat pentru definirea completă a

funcţiilor membru (în afara clasei). Sintaxa de definire completă a unei funcţii membru (adică a unei metode) este:

Page 150: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 151 -

Dacă funcţia nu returnează o valoare, în locul tipului se scrie cuvîntul cheie void.

Accesul la datele şi metodele unui obiect se poate face: a) utilizînd operatorul . ( atunci cînd se cunoaşte obiectul) sau b) operatorul -> (dacă se cunoaşte pointerul la clasă).

Exemplu rezolvat

Să creăm clasa vector cu metodele citire(), afisare(), suma(), max().

Conţinutul programului:

#include<iostream.h> #include<iomanip.h> #define N 100 class vector{ public: int vect[N]; void citire(); void afis(); int suma(); int max(); }; void vector::citire(){for(int i=0;i<N;i++) cin>>vect[i];} void vector::afis(){for(int i=0;i<N;i++) cout<<setw(5)<<vect[i];cout<<endl;} int vector::suma(){ int i,s=0; for(i=0;i<N;s+=vect[i],i++); return s; } int vector::max(){int m,i;m=vect[0]; for(i=1;i<N;i++) if(m<vect[i]) m=vect[i]; return m; } main(){ vector v; cout<<"Introdu elementele vectorului"<<endl; v.citire(); cout<<"Elementele vectorului :"<<endl; v.afis(); cout<<"suma elementelor : "<<v.suma()<<endl; cout<<"elemental maxim : "<<v.max()<<endl; }

Page 151: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 152 -

§ 3. Pointerul *this

Orice metodă apelată a unui obiect are definit implicit pointerul this, a cărui valoare este adresa obiectului. El nu poate fi declarat explicit, nu poate fi modificat, dar poate fi utilizat explicit.

Exemplu: class complex { public: double re,im; void init(double x,double y); }; void complex::init(double x,double y) { this->re = x; this->im = y; }

§ 4. Funcţii inline La compilare operaţiile suplimentare de apel a unei funcţii inline şi de revenire din ea sînt eliminate. O metodă definită (nu doar declarată) în interiorul clasei este implicit metodă inline.

O metodă definită în fara clasei se consideră metodă inline doar dacă în locul unde ea este definită antetul metodei este prefixat de cuvîntul cheie “inline”.

De exemplu, metoda citire() a clasei vector poate fi definită metodă inline astfel: inline void vector::citire(){for(int i=0;i<N;i++) cin>>vect[i];} Observaţii 1. Este interzisă folosirea în cadrul funcţiilor inline a structurilor repetitive (“for”, “while”, “do while”), şi a funcţiilor recursive. 2. De regulă, o metodă inline conţine în definirea ei pînă la 4–5 instrucţiuni. 3. De regulă, metodele inline nu conţin în definirea lor operaţii aritmetice.

Page 152: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 153 -

§ 5. Constructor Constructorul este o funcţie-membru specială care are ca scop principal

iniţializarea obiectelor. Se pot defini cîţiva constructori pentru aceeaşi clasă. Ei vor fi funcţii supraîncărcate (vom examina supraîncărcarea mai tîrziu) şi se vor deosebi prin numărul şi/sau tipurile parametrilor. Constructorii respectă următoarele reguli: 1. Au acelaşi nume ca şi clasa pentru care sînt definiţi. 2. Constructorii nu returnează nimic. 3. Constructorii pot fi supraîncărcaţi. 4. Constructorii se apelează automat la crearea unui obiect al clasei (se mai

spune la instanţierea obiectului).

De regulă, constructorii sînt apelaţi: a) la declararea de obiecte sau la crearea dinamică de obiecte în care se

prevăd iniţializări cu variabile sau obiecte de tipul/clasa parametrilor constructorului;

b) la convertirea unor constante sau variabile de alt tip la tipul clasei respective. Exemplu: class complex { public: double re,im; complex(double a, double b){re=a;im=b;} // def. constructorului }; main(){ complex X(2.4,5.8); // instantierea obiectului X }

• Dacă programatorul nu declara un constructor pentru o clasă, iar clasa respectiva nu conţine date membru constante sau referinţă, atunci compilatorul creează un constructor implicit, care este funcţie inline, nu iniţializează datele membru şi invocă constructorii claselor de baza. Dacă programatorul defineşte cel puţin un constructor, atunci compilatorul nu mai generează constructorul implicit.

Constructorul implicit este invocat în următoarele situaţii: a) la crearea fără parametri a unui obiect; b) la declararea unui tablou de obiecte; c) la crearea dinamică fără parametri a unui obiect, cu operatorul new.

Page 153: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 154 -

Exemplu de constructor fără parametri class complex { public: double re,im; complex(){re=im=0;} }; main(){ complex x; }

• Pentru ca un constructor să fie considerat constructor de copiere, primul său parametru trebuie să fie o referinţă la un obiect din clasa respectivă.

În cazul în care un astfel de constructor nu este definit explicit de către programator, compilatorul generează automat un constructor de copiere care va realiza copierea "membru cu membru" a "vechiului" obiect în cel nou creat. Constructorul de copiere se descrie astfel:

Nume_clasa(Nume_clasa &ob_sursa){ membru_1=ob_sursa.membru_1; membru_2=ob_sursa.membru_2; // ... membru_n=ob_sursa.membru_n; } unde membru_i sînt date membru ale clasei Nume_clasa. La crearea constructorului de copiere trebuie utilizate toate datele obiectului, deoarece compilatorul nu mai generează nici un constructor de copiere şi transferul datelor de la un obiect la altul trebuie să fie complet. Exemplu: class complex { public: double re,im; complex(complex &a){a.re=re; a.im=im;} }; main(){ complex x(2.4,5.8), a(x); }

În cazul instrucţiunii a=x nu este invocat constructorul de copiere, el

este invocat numai la declaraţiile de tipul: Nume_clasa nume_obiect(obiectul_de_la_care_se_transferă_datele);

Page 154: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 155 -

§ 6. Destructor Destructorul este o funcţie-membru specială care are ca scop principal

distrugerea obiectului (deci eliberarea memoriei ocupată de acest obiect). Un obiect se distruge în una din următoarele trei situaţii:

• cînd este părăsit blocul în care a fost creat (cazul obiectelor locale); • la terminarea programului (cazul obiectelor globale); • cînd se aplică operatorul delete (obiecte create dinamic cu new).

În cazul în care nu este definit explicit un destructor, compilatorul generează automat unul cu corpul de instrucţiuni vid. Destructorul nu are parametri şi nu returnează nimic. O clasă are un unic destructor, care nu poate fi supraîncărcat (deoarece nu are parametri). Numele destructorului se formează din numele clasei precedat de simbolul "~" (tilda). Destructorul se apelează automat la distrugerea unui obiect al clasei. Exemplu rezolvat 1. Să creăm clasa student cu datele membru nume, nr_de_identificare, cursul, media şi metodele tipareste_student(), bursa(). Vom descrie toate tipurile de constructori pentru această clasă. Realizare: #include <conio.h> #include <string.h> #include <iostream.h> class student{ public: char * nume,* nr_de_identificare; int anul, cursul; double media; /******* Constructori *****/ student(); //Constructor implicit student(char * , int , char * ,double ); //Constr. de init1 student(char * , char * ,double );//Constr. de init2 student(student& ); //Constructor de copiere ~student(){}; // Destructor /****** Metode *******/ void tipareste_student(); void bursa(); }; //sfirsitul declararii clasei student::student(){ nume = "Nedefinit";

Page 155: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 156 -

cursul = 0; media = 0; nr_de_identificare = "Nedefinit"; cout<<endl<<"Constructor implicit "<<endl; } student::student(char * a, int c, char * n, double med){ nume=a; cursul=c; nr_de_identificare=n; media=med; cout<<endl<<"Constructor de initializare1 "<<endl; } student::student(char * a1, char * n1, double med){ nume=a1; cursul=0; nr_de_identificare=n1; media=med; cout<<endl<<"Constructor de initializare2 "<<endl; } student::student(student&C){ nume= C.nume; cursul= C.cursul; nr_de_identificare= C.nr_de_identificare; media= C.media; cout<<endl<<"Constructor de copiere "<<endl; } void student::tipareste_student(){ cout<<"Metoda de afisare "<<endl; cout<<"Nume: "<<nume<<endl<<"Cursul: "<<cursul<<endl; cout<<"Numarul de identificare: "<<nr_de_identificare<<endl; cout<<"Media: "<<media<<endl; } void student::bursa(){ cout<<"Metoda BURSA "<<endl; if(media>7) cout<<"Studentul are bursa!"<<endl; else if(media>5)cout<<"Studentul nu are bursa!"<<endl; else cout<<"Studentul este restantier"<<endl; } void main(){ student st1("Lupei Rodica",2,"AR985I",9.81); // apelarea constr. de init.1 st1.tipareste_student(); st1.bursa(); student st2("Popa Ion","RD726K",6.89); // apelarea constr. de init.2 st2.tipareste_student(); st2.bursa(); student st3("Chistruga Alexandru",2,"AD564L",4.99); st3.tipareste_student(); st3.bursa(); student st4(st1); st4.tipareste_student(); student st; // apelarea constructorului implicit st.tipareste_student(); }

Page 156: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 157 -

2. Să creăm clasa vector cu metode de citire şi de afişare a elementelor vectorului. Realizare:

#include<iostream.h> #include<stdlib.h> #include<iomanip.h> class vector{ public: int * vect,N; vector(); // Constructorul implicit al clasei vector vector(int a); // Constructor definit, a – numarul de elemente void citire(); void afis(); ~vector(); // Declaram destructorul clasei vector }; // sfirsitul declararii clasei vector vector::vector(){ // definim constructorul implicit cout<<”Introdu nr. de elemente ale vectorului”<<endl; cin>>N; vect=new int[N]; } vector::vector(int a){ N=a; vect=new int[N];} vector::~vector(){ delete []vect;}//Definim destructorul void vector::citire(){for(int i=0;i<N;i++) vect[i]=random(100);} void vector::afis(){for(int i=0;i<N;i++) cout<<setw(5)<<vect[i];cout<<endl;} main(){ randomize(); vector v1;//num. de elemente ale vectorului se citeşte de la tastatură vector v2(5);// numarul de elemente ale vectorului este 5 v1.citire(); cout<<”elementele primului vector”<<endl; v1.afisare(); v2.citire(); cout<<”elementele vectorului doi”<<endl; v2.afisare(); }

Page 157: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 158 -

§ 7. Funcţii prietene Datele şi metodele unei clase nu pot fi prelucrate în exteriorul clasei,

dacă ele sînt protejate cu modificatorii de protecţie private sau protected. Totuşi, uneori apare necesitatea prelucrării acestor date în afara clasei lor. Acest fapt este posibil prin intermediul aţa numitor funcţii prietene (friend functions). Declararea unei funcţii prietene f() clasei X se realizează astfel:

class X{ //…… friend tip_returnat f(parametru_de_tip_clasă,lista_de_parametri); }; tip_returnat f(parametru_de_tip_clasă, lista_de_parametri){ // corpul functiei } Accesul la datele clasei se face prin intermediul parametrului de tip clasă (nu prin numele obiectului clasei ca în cazul metodelor clasei). Deci parametru_de_tip_clasă este obligatoriu (spre deosebire de funcţiile membru, in cazul funcţiilor prietene nu mai este definit pointerul implicit this), iar lista_de_parametri poate şi să lipsească. Exemplu rezolvat

1. Să creăm o funcţie prietenă cu clasa vector, care va apela datele şi metodele acestei clase (protejate la nivel private).

Realizare: #include<iostream.h> #include<stdlib.h> #include<iomanip.h> #include<conio.h> class vector{ int vect[10]; void citire(); void afis(); friend void prieten(vector c); }; void vector::citire(){ for(int i=0;i<10;i++) vect[i]=random(100); } void vector::afis(){ for(int i=0;i<10;i++) cout<<setw(5)<<vect[i]; cout<<endl;

Page 158: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 159 -

} void prieten(vector c){ c.citire(); c.afis(); } main(){ randomize(); vector Q; prieten(Q); getch(); }

Se creează obiectul Q, a cărui metodele nu pot fi apelate decît în cadrul

funcţiei prieten. Apelarea metodelor în afara acestei funcţii va genera o eroare, în care se va indica că nu exista acces la metodele obiectului Q.

§ 8. Alocarea dinamică a obiectelor

8.1. Pointeri către membrii unei clase

Variabilele pointer păstrează adrese ale zonelor de memorie, în care pot fi stocate date sau funcţii.

Un pointer către un membru al clasei păstrează locaţia de memorie din interiorul clasei. De fapt, el conţine doar deplasarea datei în cadrul oricărui exemplar (adică obiect) al clasei.

Pentru prelucrarea adresei unui membru al clasei se foloseşte sintaxa: pointer_membru=&clasa::membru.

Pentru accesul la un membru cînd se cunoaşte adresa lui se foloseşte sintaxa: obiect.*pointer (daca se specifica un obiect al clasei) sau pointer_obiect->*pointer_membru (daca se specifica un pointer de obiect).

8.2. Operatorii new şi delete

Ca şi celelalte structuri de date, obiectele pot fi alocate dinamic (adică

pot fi create în timpul execuţiei programului). Pentru date obişnuite se folosesc funcţiile predefinite calloc(), malloc(), realloc() şi free() (ale fişierului alloc.h). Cele mai utilizate sînt malloc() şi free(). Echivalentul acestor două funcţii în cazul obiectelor sînt operatori new şi delete.

Page 159: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 160 -

• Operatorul new se utilizează astfel:

tip_data *p; p= new tip_data [(initializare)]; unde tip_data reprezintă tipul definit, adică numele clasei, p este numele pointerului de tip obiect, iar initializare (care poate să lipsească) este o expresie care depinde de tipul datei şi permite iniţializarea zonei de memorie alocate. Dacă alocarea nu este posibilă, pointerul returnat este NULL. Operatorul new poate produce apelul unui constructor.

• Operatorul delete eliberează o zonă de memorie din heap alocată

anterior cu new. De regulă, el se utilizează în interiorul destructorilor şi poate fi apelat în una din următoarele forme:

a) delete P – se utilizează pentru eliberarea unei zone de memorie ocupată de o singură dată (obiect), nu de un vector. Pointerul P trebuie să fie un pointer la o zonă de memorie alocată anterior printr-un operator new. Folosirea operatorului delete cu un pointer care nu este valid este o opera ţie cu rezultat nedefinit, cel mai adesea producînd erori de execuţie;

b) delete [] P – se foloseşte pentru eliberarea unei zone de memorie ocupată de un vector de date. De exemplu, avînd alocarea int *V = new int[10], instrucţiunea delete V va elibera zona de memorie alocată elementului V[0], iar instrucţiunea delete[] V va elibera spaţiul de memorie alocat întregului tablou V. Exemple de alocări şi eliberări pentru obiecte ale claselor Complex şi student (declarate în exemplele anterioare):

Complex *pc0 = new Complex; // apelarea constructorului implicit Complex *pc1 = new Complex(2);// apelarea constructorului cu un parametru Complex *pc2 = new Complex(3.5,2.9); //apelarea constr. cu 2 parametri delete pc0; // apelarea destructorului delete pc1; delete pc2; elev *p = new elev(”Munteanu”,”Anatol”,8.88); p->afisare(); delete p; Complex *pv1 = new Complex[4]; // crearea dynamica a vectorului pv1 delete []pv1; // eliberarea memoriei rezervate vectorului pv1

Page 160: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 161 -

Observaţie. La declararea unui pointer de tip obiect nu este apelat

constructorul, el este apelat la alocarea memoriei, adică la apelarea operatorului new. Exemplu rezolvat

Să creăm un tablou de poiteri de tip student (care este o clasă cu datele

membru: nume, prenume, anul, media şi funcţia membru afis(), utilizată pentru afişarea acestor date).

Realizare:

#include <stdlib.h> #include <string.h> #include <conio.h> #include <iostream.h> class student{ char *nume,*prenume; int anul; double media; public: student(); student(char *p1,char *p2); student(char *p1,char *p2,int p3,double p4); void afis(); ~student(); }; student::student(){ char s[20]; cout<<"Constructor implicit"<<endl; cout<<"Dati numele studentului";cin>>s; nume=new char[strlen(s)+1];strcpy(nume,s); cout<<"Dati prenumele studentului";cin>>s; prenume=new char[strlen(s)+1];strcpy(prenume,s); cout<<"Dati anul nasterii";cin>>anul; cout<<"Dati media :";cin>>media; } student::student(char *p1,char*p2){ nume= p1;prenume= p2; anul=0; media=0; } student::student(char *p1,char *p2,int p3,double p4){ nume= p1;prenume= p2;anul=p3;media=p4; }

Page 161: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 162 -

void student::afis(){ cout<<nume<<" "<<prenume<<" "<<anul<<" "<<media<<endl; } student::~student(){delete nume;delete prenume;} void main(){ student *s[3]; int i; s[0]=new student; s[1]=new student("Moraru","Ion"); s[2]=new student("Ciobanu","Vasile",1990,8.75); cout<<endl<<"Lista studentilor"<<endl<<endl; for(i=0;i<3;i++) s[i]->afis(); getch(); for(i=0;i<3;i++) delete s[i]; }

§ 9. Supraîncărcarea operatorilor

9.1. Modalităţi şi forme de supraîncărcare

În C++ se pot defini operaţii cu obiectele claselor folosind simbolurile

operatorilor standard. În acest caz se spune că operatorii standard sînt supraîncărcaţi. O funcţie care defineşte pentru o clasă o operaţie echivalentă operaţiei efectuate de un operator asupra unui tip predefinit este numită funcţie operator. Majoritatea operatorilor limbajului C++ pot fi supraîncărcaţi, cu excepţia operatorilor “.”, “*”, “::”, “?:”.

Procedeul de supraîncărcare constă în definirea unei funcţii cu numele operator S, unde operator este cuvînt-cheie, iar S – simbolul unui operator din C++.

Procesul de supraîncărcare a unui operator poate fi realizat prin intermediul:

a) unei funcţii membru; b) unei funcţii prietene clasei pentru care urmează a fi supraîncărcat

operatorul.

a) Forma generală de supraîncărcare a unui operator S prin intermediul unei funcţii membru:

Page 162: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 163 -

class nume_clasa { // datele şi metodele clasei tip operator S(lista_de_parametri); };// sfirsitul declaratiei clasei tip nume_clasa::operator(lista_de_parametri){ // descrierea procesului de supraîncărcare }

unde S este operatorul supraîncărcat, tip – tipul rezultatului operaţiei S, iar lista_de_parametri reprezintă operanzii care participă la operaţia S. b) Forma generală de supraîncărcare este a unui operator S prin intermediul unei funcţii prietene:

nume_clasa { // datele şi metodele clasei friend tip operator S(lista_de_parametri); }; // sfirsitul declaratiei clasei tip operator S (lista_de_parametri){ // descrierea procesului de supraîncărcare }

unde S este operatorul supraîncărcat, tip – tipul rezultatului operaţiei S, iar lista_de_parametri reprezintă operanzii care participă la operaţia S. Observaţie 1. În cazul supraîncărcării prin funcţii membru lista_de_parametri va conţine cu un parametru mai puţin (din cauza că prin intermediul funcţiilor membru este acces la obiectul curent). 2. Dacă supraîncărcarea este realizată printr-o funcţie prieten, atunci primul operant va reprezenta obiectului curent.

9.2. Restricţii la supraîncărcarea operatorilor

Supraîncărcarea operatorilor este supusă următoarelor restricţii:

1. Se pot supraîncărca doar operatorii existenţi în C++; nu se pot crea noi operatori.

2. Nu se poate modifica numărul (paritatea) operanzilor operatorilor standard.

3. Nu se poate modifica precedenţa şi asociativitatea operatorilor.

Page 163: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 164 -

4. Deşi operatorii supraîncărcaţi păstrează paritatea şi precedenţa operatorilor predefiniţi, ei nu moştenesc şi comutativitatea acestora.

Observaţii:

1. Dacă operatorul = nu este supraîncărcat, el are o semnificaţie implicită. 2. Funcţia operator trebuie să aibă cel puţin un argument (implicit sau

explicit) de tipul clasei pentru care s-a supraîncărcat operatorul. 3. Unui operator i se poate atribui orice semnificaţie, însă se recomandă ca

aceasta să fie cît mai apropiată de semnificaţia naturală.

Exemple rezolvate

1. Supraîncărcarea operatorului +

Să creăm un exemplu în care vom supraîncărca operatorul + pentru clasa complex. Deoarece adunarea numerelor complexe este comutativă, vom examina cazurile:

1. complex + complex 2. double + complex 3. complex + double

În primul şi al treilea caz supraîncărcarea poate fi efectuată prin intermediul funcţiilor membru, însă în cazul doi supraîncărcarea este posibilă numai prin intermediul unei funcţiei prieten, deoarece primul parametru al unei funcţii membru operator este implicit de tipul clasei şi nu poate fi de alt tip.

Rezolvare: #include<iostream.h> class complex{ public: double x,y;//complex=x+yi void citire(); void afisare(); complex operator +(complex); friend complex operator +(double, complex); complex operator+(double); }; void complex::citire(){ cout<<”partea reala”;cin>>x; cout<<”partea imaginara”;cin>>y; } void complex::afisare(){cout<<x<<”+”<<y<<”i”<<endl;}

Page 164: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 165 -

complex complex::operator+(complex b){ complex c; c.x=x+b.x; c.y=y+b.y; return c; } complex complex::operator+(double b){ complex c; c.x=x+b; c.y=y; return c; } complex operator+(double a, complex b){ complex c; c.x=a+b.x; c.y=b.y; return c; } main(){ complex x,y,z; double a; cout<<"Introdu valoarea numarului complex"<<endl; x.citire(); cout<<"Mai introdu inca una"<<endl; y.citire(); cout<<"Introdu un numar real"<<endl; cin>>a; cout<<"Valorile introduse"<<endl; cout<<"x="l; x.afisare(); cout<<"y=" ; y.afisare(); cout<<"a="<<a<<endl; cout<<"*********Operatorul + *********"<<endl; cout<<"***complex complex***"<<endl; z=x+y; z.afisare() ; cout<<"***complex double***"<<endl; z=x+a; z.afisare(); cout<<"***double complex***"<<endl; z=a+x; z.afisare(); }

2. Supraîncărcarea operatorului =

În cazul în care operatorul de atribuire nu este supraîncărcat explicit, compilatorul generează unul implicit şi copie valorile datelor membri ale operandului drept direct în datele membri ale operandului stîng.

Operatorul de atribuire implicit este nesatisfăcător în situaţiile în care

Page 165: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 166 -

obiectele clasei au date membri de tip pointer, sau în situaţiile în care memoria este alocată în mod dinamic.

Să creăm două exemple în care vom supraîncărca explicit operatorul = pentru clasa complex prin intermediul unei funcţii membru şi respectiv cu ajutorul unei funcţii friend.

Realizare: a) Supraîncărcarea operatorului = pentru clasa complex prin intermediul unei funcţii membru.

class complex{ public: double x,y; complex operator = (complex ); }; complex complex::operator = (complex z){ x=z.x; y=z.y; return *this; //this este pointer către obiectul curent, a în main } void main(){ complex a, b; a = b; } b) Supraîncărcarea operatorului = pentru clasa complex prin intermediul unei funcţii friend. class complex{ public: double x,y; friend complex operator=(complex,complex); }; complex operator = (complex z1, complex z2){ z1.x=z2.x; z1.y=z2.y; return z1;} void main(){ complex a, b; a = b; }

Page 166: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 167 -

3. Supraîncărcarea operatorilor de comparaţie

Aşa cum limbajul de programare C++ nu are implementat tipul de date logic, vom considera valoarea 1 echivalenta valorii true, iar valoare 0 echivalenta valorii false. În acest context tipul rezultatului unei operaţii de comparare a două valori numerice poate fi int, avînd valorile posibile 1 sau 0. Supraîncărcarea operatorilor de comparaţie poate fi efectuată atît prin intermediul funcţiilor membru cît şi prin intermediul funcţiilor friend. În general, supraîncărcarea unui operator de comparaţie (printr-o funcţie friend) va avea următoarea sintaxă generală:

class nume_clasa{ //Date şi metode; friend int operator@( nume_clasa, nume_clasa); }; //unde @ este un operator de comparaţie //descrierea supraîncărcării : int operator@( nume_clasa ob1, nume_clasa ob2){ if(condiţia de comparare) return 1; else return 0; } În următoarea secvenţă de program vom supraîncărca (cu ajutorul unei funcţii prieten) operatorul = = pentru clasa complex: class complex{ double x,y; public: friend int operator== (complex,complex); }; int operator == (complex ob1, complex ob2){ if(ob1.x==ob2.x && ob1.y==ob2.y) return 1; else return 0;} void main(){ complex a, b; if(a==b) cout<<”Numere egale”; else cout<<”Numere diferite”; }

Observaţie. Procesul de supraîncărcare a celorlalţi operatori de comparaţie este similar cu supraîncărcarea operatorului = =. Deosebirea constă în dificultatea comparării datelor obiectului.

Page 167: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 168 -

4. Supraîncărcarea operatorilor << şi >>

Operaţiile de intrare/ieşire din C++ se efectuează folosind operatorul de inserţie << şi respectiv operatorul de extragere >> din streamuri. Aceste funcţii operator sînt definite în clasele ostream şi istream. Spre deosebire de alţi operatori, operatorii de intrare/ieşire pot fi supraîncărcaţi doar prin intermediul funcţiilor friend.

Supraîncărcarea operatorilor de intrare/ieşire se poate face respectînd sintaxa:

class nume_clasa { friend ostream& operator<<(ostream& os,nume_clasa nume); friend istream& operator>>(istream& is,nume_clasa &nume); }; ostream& operator<<(ostream& os,tip_clasa nume){ // corpul functiei return os; } istream& operator>>(istream& is,tip_clasa &nume){ // corpul functiei return is; } Să creăm un exemplu în care vom supraîncărca operatorii <<, >> pentru clasa complex. Realizare: #include<iostream.h> class complex { public: double x, y; friend ostrem& operator << (ostrem& os, complex z); friend istream& operator >>(istream& is,complex& z); }; ostream& operator<<(ostream& os, complex z){ os <<z.x; if(z.y==0) os<<endl; if(z.y<0) os<<”-”<<z.y<<”i”<<endl; if(z.y>0) os<<”+”<<z.y<<”i”<<endl; return os; } istream& operator>>(istream& is, complex& z){ cout<<”Dati partea reala ”; is >> z.x; cout<<”Dati parteaimaginara”; >> z.y; return is; }

Page 168: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 169 -

main(){ complex x,y; cout<<”Introdu primul nr complex”; cin>>x; cout<<”Introdu a-l doilea nr complex”; cin>>y; cout<<x<<y; }

§ 10. Moştenirea obiectelor La începutul acestui capitol am menţionat despre mecanismul de

moştenire, prin care o clasă (numită clasă derivată) moşteneşte (copie) datele şi metodele clasei părinte (se mai spune clasă de bază).

În C++ deosebim moşteniri simple şi moşteniri multiple. Moştenirea simplă se caracterizează prin faptul că o clasă poate avea

una sau mai multe clase derivate şi cel mult un părinte. De exemplu, considerînd clasa Angajat părinte a clasei Administrator,

obţinem o relaţie de moştenire simplă, în care clasa Admimistrator păstrează datele şi metodele clasei Angajat. Evient, clasa de derivate poate conţine şi alte date sau fucţii decît cele ale părintelui.

Moştenirea multiplă se caracterizează prin faptul că o clasă este

derivată cel puţin două clase. O clasă derivată se declară conform următoarei diagrame de sintaxă

(considerînd declarată clasa părinte):

Page 169: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 170 -

În calitate de modificator de protecţie poate fi unul din cuvintele-cheie:

public, private, protected. Domeniul de vizibilitate al datelor şi metodelor într-o relaţie de

moştenire este dat de urătorul tabel:

Modificatorul de protecţie Accesul la datele şi metodele clasei de bază în

al datei sau al metodei clasei

de bază

din declararea clasei derivate (din diagramă)

clasa derivată există la nivel

exteriorul clasei derivate

private public private nu există protected public protected nu există public public public există private protected private nu există protected protected protected nu există public protected protected nu există private private private nu există protected private private nu există public private private nu există

Exemplu rezolvat

Să creăm un program în care vom descrie personalul unei instituţii, format din două tipuri de angajaţi: Angajat şi Administrator. Clasă Angajat este de bază şi conţine date şi metode referitoare la orice angajat. Clasa Administator este derivată din clasa Angajat şi mai conţine suplimentar cîmpul sectie, care specifică numărul secţiei de care este responsabil administratorul. Realizare:

#include<iostream.h> #include<string.h> class Angajat{ protected:

Page 170: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 171 -

char *nume; double salariu; public: void set_ang(char *n, double sal); void afis_ang(); }; void Angajat::set_ang(char *n, double sal){ int size = strlen(n); nume = new char[size+1]; strcpy(nume, n); salariu = sal; } void Angajat::afis_ang(){ cout << "Nume: " << nume<< " Salariu: " << salariu << endl ; } class Administrator : public Angajat { int sectie; public: void set_admin(char *n, double sal, int sec); void afis_admin(); }; void Administrator::set_admin(char *n,double sal, int sec){ int size = strlen(n); nume = new char[size+1]; strcpy(nume, n); salariu = sal; sectie=sec; } void Administrator::afis_admin(){ afis_ang(); cout << "Sectia : " << sectie << endl; } void main(){ Angajat a1; cout<<"Datele despre Angajat "; a1.set_ang("Manole", 2000); a1.afis_ang(); Administrator m1; m1.set_admin("Frunza", 3000, 1); cout<<"Datele despre Administrator "; m1.afis_admin(); } În urma execuţiei acestui program la consolă vor fi afişate următoarele mesaje: Datele despre Angajat Nume: Manole Salariu: 2000 Datele despre Administrator Nume: Frunza Salariu: 3000 Sectia : 1 Observaţie. Moştenirea multiplă va fi examinată în paragraful 13.

Page 171: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 172 -

§ 11. Constructori şi destructori în clasele derivate

11.1. Generalităţi

Constructorii şi destructorii sînt funcţii membre care nu se moştenesc.

La crearea unui obiect a unei clase derivate se apelează implicit mai întîi constructorii claselor de bază, apoi constructorul clasei derivate. Ordinea în care sînt apelaţi constructorii claselor de bază corespunde ordinii claselor de bază din declaraţia clasei derivate.

Dacă clasa de bază (adică clasa părinte) nu are constructor implicit sau se doreşte ca un constructor supraîncărcat să fie apelat atunci cînd un nou obiect al unei clase derivate este creat, atunci se poate specifica acest lucru în definiţia constructorului clasei derivate:

Numele_clasei_derivate (lista_de_parametri): Numele_clasei_de_bază (lista_de_parametri) {}

Ordinea de execuţie a destructorilor este inversă ordinii apelării constructorilor respectivi. Deci, mai întîi este apelat destructorul clasei derivate, apoi destructorul clasei de bază.

În cazul utilizării constructorilor cu parametri, este necesar ca constructorul clasei derivate să transfere parametri constructorului clasei de bază.

Dacă transferul de parametri nu este realizat, atunci la compilarea programului va apărea o eroare, care va genera un mesaj ce va informa că nu poate fi iniţializat constructorul clasei de bază. O asemenea eroare este generată de următorul exemplu:

#include<iostream.h> class baza{ public: int i; baza(int x){i=x;cout<<"construeste baza"<<endl;} }; class derivat:public baza {

Page 172: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 173 -

public: int j; derivat(int x,int y){j=x;i=y;cout<<"construeste derivat"<<endl;} void arata(){cout<<i<<" "<<j<<endl;} }; main(){ derivat ob(3,4); ob.arata(); }

La compilarea acestui program se va afişa mesajul: Cannot fiind default

constructor initialize base class baza (constructorul clasei de bază nu poate fi iniţializat).

Pentru efectuarea transferului a k parametri ai constructorului clasei derivate Derivat către constructorului clasei de bază Baza, se va utiliza următorul model:

class Baza{ Baza(tip_1 par_1,…,tip_k par_k); // construct. clasei de baza }; class Derivat:public Baza { Derivat(tip_1 par_1, …,tip_k par_k,…,tip_n par_n); // constr. clasei derivate }; Derivat::Derivat(tip_1 par_1, …,tip_k par_k, ….…,tip_n par_n): Baza(par_1, par_2, ……,par_k){ /* iniţializare date membre clasa derivata */ } Exemplu rezolvat În acest program se ilustrează modul de utilizare a constructorului cu parametri într-o relaţie de moştenire Bază – Derivat. #include<iostream.h> class baza{ public: int i; baza(){}; baza(int x){i=x; cout<<"construeste baza"<<endl;} }; class derivat:public baza { public: int j;

Page 173: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 174 -

derivat(){}; derivat(int x,int y): baza(y){ j=x; cout<<"construeste derivat"; } void arata(){cout<<i<<" "<<j<<endl;} }; main(){ derivat ob(3,4); ob.arata(); } În acest program în momentul în care este apelat constructorul clasei derivate ob(3, 4) pentru iniţializarea datei i se apeleză costructorul clasei de bază, astfel încît i = 4 şi j = 3.

11.2. Pointeri către clase derivate Mecanismul de moştenire oferă posibilitatea de a declara obiecte de tip

pointer la clasa de bază, ca mai apoi pentru aceşti pointeri să fie apelaţi constructorii claselor derivate.

De exemplu, în secţiunea de program class Baza{/*date si metode*/ }; class Derivat:public Baza {/*date si metode*/ }; main(){ Baza *a; a = new Derivat; } instrucţiunea a = new Derivat implică mai întîi iniţializarea constructorului clasei de bază, apoi a constructorului clasei derivate. Cu toate că a fost iniţializat constructorul clasei derivate, nu va fi posibil de apelat metodele clasei derivate. Exemplu rezolvat

Să elaborăm un program care va prelucra ierarhia de clase Student – Bugetar. Clasa Bugetar este derivata clasei Student.

Page 174: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 175 -

Realizare: #include <string.h> #include <iostream.h> #include<conio.h> class student{ // descriem clasa student protected: char *nume,*prenume; int anul; double media; public: student(); student(char *p1,char *p2,int p3,double p4); void afis(); }; student::student(){ //definim constructorul clasei de baza char s[20]; cout<<"Numele studentului";cin>>s; nume=new char[strlen(s)+1]; strcpy(nume,s); cout<<"Prenumele studentului"; cin>>s; prenume=new char[strlen(s)+1]; strcpy(prenume,s); cout<<"Anul nasterii"; cin>>anul; cout<<"Media :"; cin>>media; } student::student(char *p1,char *p2,int p3,double p4){ nume= p1; prenume=p2; anul=p3; media=p4; } void student::afis(){ cout<<nume<<" "<<prenume<<" "<<anul<<" "<<media<<endl; } class bugetar:public student{ //descriem clasa bugetar public: bugetar(){}; bugetar(char *p1,char *p2,int p3,double p4):student(p1,p2,p3,p4){}; int bursa(){if(media>8) return 200;else return 0;} void afis(){student::afis();cout<<"Bursa "<<bursa()<<endl; } }; void main(){ student *s1,*s2;

Page 175: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 176 -

int i; bugetar *a,*b; cout<<"lucru cu pointeri de tip student"<<endl; s1=new student("Ciobanu","Vasile",1990,7.75); s2=new bugetar("Ciubotaru","Vlad",1989,8.75); cout<<endl<<"studentii din lista"<<endl<<endl; s1->afis(); s2->afis(); cout<<endl<<"lucru cu pointeri de tip bugetar"<<endl; b=new bugetar("Moraru","Ion",1989, 9.2); b->student::afis(); b->afis(); delete s1; delete s2; delete b; getch(); } § 12. Funcţii virtuale, clase abstracte şi polimorfism

Funcţiile virtuale se folosesc (de regulă) atunci, cînd se redefinesc metodele părinţilor şi nu se ştie din timp care metodă cu acelaşi nume (proprie sau a unuia dintre părinţi) va trebui folosită. Metodele virtuale îşi creează automat propria ierarhie. La declararea părintelui-generator al unei astfel de ierarhii, după antetul metodei se scrie directiva virtual. Deci, sintaxa pentru declararea unei funcţii virtuale este:

virtual tip_returnat nume_metodă(lista_parametrii_formali);

Observaţii.

1. Dacă o metodă este declarată ca funcţie virtuală în clasa de bază, ea va fi virtuală pentru toate clasele derivate.

2. O metodă virtuală este declarată cu scopul de a o utiliza şi în alte clase (nu numai în clasa de bază).

3. Redefinirea unei funcţii virtuale într-o clasă derivată domină definiţia funcţiei în clasa de bază.

Exemple rezolvate

Page 176: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 177 -

1. În clasa de bază Baza sînt definite metodele citire şi afişare, dintre care metoda citire este virtuală. Ambele metode sînt redefinite în clasa derivată Derivat.

#include <iostream.h> class Baza{ public: void afisare(){cout<<"afisare Baza"<<endl;} virtual void citire(){cout<<"citire Baza"<<endl;} }; class Derivat: public Baza{ public: void afisare(){cout<<"afisare Derivat"<<endl;} void citire(){cout<<"citire Derivat"<<endl;} }; main(){ clrscr(); Derivat a; a.citire(); a.afisare(); Baza *b; b=new Derivat; b->citire(); b->afisare(); }

În urma execuţiei programului la ecran se vor afişa următoarele mesaje:

citire Derivat afisare Derivat citire Derivat afisare Baza

2. Să creăm un program în care vom defini clasa de bază patrat cu

metodele afisare şi arie (virtuală), precum şi clasa derivată cub, în care vom redefini metodele clasei de bază. Pentru fiecare clasă vom crea cîte un constructor cu parametri. Realizare: #include <stdlib.h> #include <iostream.h> class patrat{ protected: double l; public:

Page 177: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 178 -

patrat(double a){l=a;} void afisare(){cout<<"patrat l= "<<l<<endl;} virtual double arie(){return l*l;} }; class cub : public patrat{ public: cub(double w):patrat(w){}; void afisare(){cout<<"cub l="<<l<<endl;} double arie(){return patrat::arie()*l;} }; void main(){ patrat *s[10]; s[0]=new patrat(5); s[1]=new cub(12); cout<<"metodele nevirtuale"<<endl; s[0]->afisare(); s[1]->afisare(); cout<<"metodele virtuale"<<endl; cout<<"patrat "<<s[0]->arie()<<endl; cout<<"cub "<<s[1]->arie()<<endl; delete s[0]; delete s[1]; }

La consolă se va afişa:

metodele nevirtuale patrat l= 5 patrat l= 12 metodele virtuale patrat 25 cub 1728

12.1. Funcţii virtuale pure şi clase abstracte

Deseori o funcţie declarată de tip virtual în clasa de bază nu defineşte o

acţiune semnificativă (fiind o metodă abstractă) şi este neapărat necesar ca ea să fie redefinită în fiecare din clasele derivate. O funcţie virtuală pură este o funcţie care nu are definiţie în clasa de bază, iar declaraţia ei are următoarea formă: class nume_baza{ //... virtual tip_returnat nume_metoda() {}; ... };

Page 178: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 179 -

tip_returnat nume_baza:: nume_metoda(){/*definirea metodei*/}

Dacă o clasă conţine cel puţin o funcţie virtuală pură, atunci ea se numeşte clasă abstractă. Evident, pentru o astfel de clasă nu pot fi create obiecte, însă pot fi creaţi pointeri şi referinţe la ele.

În acelaşi timp, dacă în clasa derivată dintr-o clasă abstractă nu se redefinesc toate funcţiile virtuale pure moştenite, atunci aceasta, de asemenea, va fi o clasă abstractă.

12.2. Polimorfism

În preliminariile acestui capitol am menţionat că polimorfismul dă

posibilitatea ca atît clasa derivată, cît şi clasa de bază să poată utiliza metode cu acelaşi nume, dar cu diferite funcţionalităţi.

De cele mai dese ori polimorfismul se realizează prin intermediul funcţiilor virtuale. Declarate în clasa de bază, se presupune că acestea vor fi implementate în clasele derivate.

În cazul funcţiilor normale (pentru care sînt cunoscute adresele de apel) se spune că “legarea” dintre obiect şi funcţie este timpurie, în sensul că această legare are loc în timpul compilării programului. Apelurile soluţionate în timpul compilării au o viteză ridicată.

Legarea tîrzie se refera la evenimente din timpul execuţiei programului, adică la cazul cînd adresa funcţiei care urmează sa fie apelata nu este cunoscută în timpul compilării, doar în momentul execuţiei programului.

Adresa de apel a funcţiilor virtuale nu este cunoscută în timpul compilării. Accesul la ele se face prin pointerii la clasa de bază. Chiar dacă legarea tîrzie conduce la un timp de execuţie mai mare al programelor, aceasta simplifică programele, conferindu-le eleganţă şi flexibilitate.

Exemplu rezolvat Să creăm un program în care vom defini clasa de bază triunghi (corespunzătoare triunghiului echilateral) şi clasele derivate piramida şi prisma (corespunzătoare piramidei triunghiulare regulate şi prismei triunghiulare regulate). Programul va citi datele despre n astfel de figuri şi corpuri geometrice, apoi va afişa denumirile celor cu aria maximă, respectiv cu volumul maximal. Numărul n de figuri/corpuri geometrice, de asemenea, se va citi de la tastatură.

Page 179: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 180 -

Realizare: Metodele afis şi volum sînt metode abstracte, adică pentru clasa triunghi ele nu efectuează nimic, dar vom avea nevoie de aceste metode în clasele derivate. #include<math.h> #include<conio.h> #include<stdlib.h> #include<iostream.h> class triunghi{ protected: double lat; // public: virtual void citire(); virtual double arie(); virtual void afis(){}; virtual double volum(){return 0;} }; void triunghi::citire(){ cout<<"Introdu lungimea laturii (bazei): ";cin>>lat; } double triunghi::arie(){return lat*lat*sqrt(3)/4;} class piramida:public triunghi{ protected: double a,h; public: void citire(); double arie(); double volum(); void afis(); }; void piramida ::citire() { // redefineste metoda parintelui cout<<"Introdu masurile piramidei"<<endl; triunghi::citire(); // apeleaza metoda parintelui cout<<"Introdu lungimea apotemei :";cin>>a; cout<<"Introdu inaltimea piramidei:";cin>>h; } double piramida ::arie(){ double s; s=triunghi::arie(); // aria bazei s=s+triunghi::lat*a/2*3; return s; } double piramida ::volum(){return triunghi::arie()*h/3;} void piramida ::afis(){ cout<<"Piramida Aria "<<arie()<<" Volumul "; cout<<volum()<<endl; }

Page 180: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 181 -

class prisma:public triunghi{ protected: double H; public: void citire(); double arie(); double volum(); void afis(); }; void prisma::citire(){ cout<<"Introdu masurile prismei "<<endl; triunghi::citire(); cout<<"Introdu inaltimea:";cin>>H; } double prisma::arie(){ double s; s=2*triunghi::arie(); // ariile bazelor s=s+triunghi::lat*H; return s; } double prisma::volum(){ double s; s=triunghi::arie(); s=s*H;return s; } void prisma::afis(){ cout<<" prisma Aria "<<arie(); cout<<" Volumul "<<volum()<<endl;} main(){ triunghi *fig[10]; int n,i,k,arie,volum; double amax,vmax; cout<<"Introdu numarul figurilor ";cin>>n; amax=vmax=0.0; for(i=0;i<n;i++){ clrscr(); cout<<" Tastati"<<endl<<"1 Piramida"<<endl<< "2 prisma "<<endl; cin>>k; if(k==1) fig[i]=new piramida; else fig[i]=new prisma ; fig[i]->citire(); if(amax<fig[i]->arie()) {amax=fig[i]->arie(); arie=i;} if(vmax<fig[i]->volum()) {vmax=fig[i]->volum();volum=i;} } cout<<"In depozit sînt urmatoarele figuri"<<endl; for(i=0;i<n;i++) fig[i]->afis(); cout<<"Figura cu aria maxima"<<endl; fig[arie]->afis();

Page 181: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 182 -

cout<<"Figura cu volumul maxim"<<endl; fig[volum]->afis(); for(i=0;i<n;i++) delete fig[i]; getch(); }

§ 13. Moştenirea multiplă

13.1. Generalităţi

Conceptul de moştenire multiplă permite crearea de clase noi care moştenesc datele şi metodele mai multor clase de bază. Moştenirea multiplă aduce mai multă flexibilitate în construirea claselor, rezultatul fiind obţinerea unor structuri de clase complexe. Astfel, sintaxa generală pentru declararea unei clase este:

Principiile prezentate la derivarea simplă şi la crearea ierarhiilor simple de clase sînt valabile şi în cazul derivării multiple. Exemplu rezolvat Să creăm un program în care vom implementa clasa cuplu, derivată a claselor barbat şi femeie. Realizare: #include <iostream.h> #include <conio.h> class barbat{ public: char *prenume; int anul; barbat(){};

Page 182: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 183 -

barbat(char *a, int b){prenume=a;anul=b;} void citire(); void afisare(); }; class femeie{ public: char *prenume; int anul; femeie(){}; femeie(char *a, int b){prenume=a;anul=b;} void citire(); void afisare(); }; class cuplu : public barbat,public femeie{ public: cuplu(){}; cuplu(char *a,int b,char *c, int d):barbat(a,b),femeie(c,d){}; void citire(); void afisare(); }; void barbat::citire(){ cout<<"Dati datele despre barbat"<<endl; cout<<"Prenumele :"; cin>>prenume; cout<<"Anul :";cin>>anul; } void barbat::afisare(){ cout<<" Barbatul : "<<prenume<<" Virsta "<<2009-anul<<endl; } void femeie::citire(){ cout<<"Dati datele despre femeie"<<endl; cout<<"Prenumele :"; cin>>prenume; cout<<"Anul :";cin>>anul; } void femeie::afisare(){ cout<<" Femeia : "<<prenume<<" Virsta "<<2009-anul<<endl; } void cuplu::citire(){ barbat::citire(); femeie::citire(); } void cuplu::afisare(){ cout<<"Cuplul este format din:"<<endl; barbat::afisare(); femeie::afisare(); } main(){ cuplu a,b("Ion",1976,"Maria",1980); a.citire(); cout<<"Cuplurile existente "<<endl; a.afisare();

Page 183: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 184 -

B C

D

A

b.afisare(); }

În urma execuţiei acestui program la consolă vor fi afişate următoarele messaje: Dati datele despre barbat Prenumele :Anton Anul :1980 Dati datele despre femeie Prenumele :Ioana Anul :1990 Cuplurile existente Cuplul este format din: Barbatul : Ioana Virsta 29 Femeia : Virsta 19 Cuplul este format din: Barbatul : Ion Virsta 33 Femeia : Maria Virsta 29

13.3. Clase virtuale Într-o moştenire multiplă este posibil ca o clasă să fie moştenită indirect

de mai multe ori, prin intermediul unor clase care moştenesc, fiecare în parte, clasa de bază. De exemplu:

class A { public: int x;}; class B : public A { /* */}; class C : public A { /* */}; class D : public B, public C {/**/};

Un obiect din clasa D va conţine

membrii clasei A de două ori, o dată prin clasa B şi o dată prin clasa C. În această situaţie, accesul la un membru al unui obiect de tip D moştenit din clasa A (de exemplu, D ob; ob.x = 2) este interzis (este semnalat ca eroare la compilare). O soluţie pentru eliminarea ambiguităţilor în moştenirile multiple este de a impune crearea unei singure copii a clasei de bază în clasa derivată. Pentru aceasta este necesar ca acea clasă care ar putea produce copii multiple prin

Page 184: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 185 -

moştenire indirectă să fie declarată clasă de bază de tip virtual. O clasă de bază virtuală este moştenită o singură dată şi creează o

singură copie în clasa derivată. Prin urmare, declaraţiile de mai sus pot fi modificate astfel: class A { public: int x; }; class B : virtual public A { /* */ }; class C : virtual public A { /* */ }; class D : public B, public C { /* */ };

Exemplu rezolvat Pornind de la clasa de bază punct vom construi clasele cerc şi patrat,

care la rîndul lor vor deriva clasa figura.

Realizare:

#include<iostream.h> #include<math.h> #include<conio.h> #include<graphics.h> class punct{ protected: int x,y,cul; public: virtual void citire(); virtual void des(); }; class patrat:virtual public punct{ protected: int l; public: void citire(); void des(); }; class cerc:virtual public punct{ protected: int raza; public: void citire(); void des(); }; class figura:public patrat, public cerc { public: void citire(); void des();

Page 185: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 186 -

}; void punct::citire(){ clrscr(); cout<<"introdu x:";cin>>x; cout<<"introdu y:";cin>>y; cout<<"introdu culoare:";cin>>cul; } void patrat::citire(){ punct::citire(); cout<<"introdu latura patrarului:";cin>>l; } void punct::des(){putpixel(x,y,cul);} void patrat::des(){ setcolor(cul); bar(x-int(l/2),y-int(l/2),x+int(l/2),y+int(l/2)); } void cerc::citire(){ punct::citire(); cout<<"Introduceti raza cercului:"; cin>>raza; } void cerc::des(){ setcolor(cul); circle(x,y,raza); } void figura::citire(){ punct::citire(); cout<<"Introduceti latura patratului:"; cin>>l; cout<<"Introduceti raza cercului:"; cin>>raza; } void figura::des(){ if(l*l>M_PI*raza*raza) {patrat::des(); cerc::des(); } else{ cerc::des(); patrat::des();} punct::des(); } void main(){ punct *masiv[10]; int i,g,m,n; char c; cout<<"Introdu numarul figurilor"; cin>>n; for(i=0;i<n;i++){ cout<<"Tastati"<<endl<<"1-PUNCT"<<endl<<"2-PATRAT"; cout<<endl<<"3-CERC"<<endl<<"4-FIGURA"<<endl; c=getch(); clrscr(); switch(c) { case '1': masiv[i]=new punct;break; case '2': masiv[i]=new patrat;break; case '3': masiv[i]=new cerc;break; case '4': masiv[i]=new figura; break; }

Page 186: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 187 -

masiv[i]->citire(); } g=DETECT; initgraph(&g,&m,"d:\\Tc\\bgi"); for(i=0;i<n;i++) { cleardevice(); masiv[i]->des(); getch(); } closegraph(); delete []masiv; }

§ 14. Programarea generică Programarea generică este o metodă de programare în care funcţiile şi clasele au parametri formali cu tip nedefinit.

În C++ programarea generică poate fi realizată prin mecanismul template.

Template-ul (sau clasa parametrizată) implementează conceptul de tip parametrizat. Parametrizarea datelor permite definirea unor clase care conţin tipuri de date nespecificate complet. O clasă parametrizată reprezintă un şablon (sau container) ce defineşte o mulţime de clase. Deci, un container este o colecţie de obiecte, în care poate fi accesat un singur obiect înt-un anumit moment. Obiectivul principal al containerelor este instanţierea tipului de date al obiectelor componente. De exemplu, fie clasa vector care defineşte un vector. Pentru a lucra cu un vector de numere complexe va trebui creată o clasă (de exemplu vector_complex), care va fi derivată din clasa vector şi din clasa complex (care defineşte numerele complexe). Deci, un container defineşte operaţiile ce se pot efectua asupra unor elemente componente, fără să fie precizat tipul acestora.

Pentru a defini o clasă parametrizată se utilizează sintaxa: template < Lista_de_parametri > Declaratie

unde Lista_de_parametri sînt tipuri de date (specificate de cuvîntul cheie class sau typename), iar Declaratie reprezintă declararea sau definirea unei clase sau funcţii.

Page 187: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 188 -

14.1. Funcţii template În cazul cînd se utilizează acelaşi algoritm pentru direrite tipuri de date, deseori se crează o funcţie template, care are un parametru de tip formal, ce urmează să precizeze tipul ei. Declararea unei funcţii template se realizaeză conform sintaxei: template < class T > T nume_functie (lista parametric formali) unde T reprezintă parametrul de tip formal, adică tipul funcţiei. Exemple rezolvate

1. Să creăm un program care va conţine o funcţie template care va determina valoarea maximală dintre două valori. Realizare: #include<iostream.h> template <class T> T maxim(T a,T b){ if(a>b) return a; else return b;} main(){ cout<<"int : "<<maxim<int>(4,7)<<endl; cout<<"double : "<<maxim<double>(4.7,2.3)<<endl; cout<<"char : "<<maxim<char>('c','h')<<endl; }

În urma execuţiei acestui program la consolă vor fi afişate următoarele mesaje: int : 7 double : 4.7 char : h

2. Să elaborăm un program care va sorta elementele a trei vectori cu elemente de diferite tipuri.

Page 188: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 189 -

#include<iostream.h> template<class T> void sort(T* vect, int n){ int i,j; T x; for(i=1; i<n; i++){ x = *(vect + i); j = i - 1; while((j >= 0) && (x < *(vect + j))){ *(vect + j + 1) = *(vect + j); j--; } *(vect + j + 1) = x; } } main(){ int i; double dv[] = {4.7, 0.66, 7.0, 1,8, 3.0, 12.9}; int iv[] = {10, 9, 5, 3, -2, 4}; char cv[] = {'f', '4', 'h', 'i', 'a', 'c'}; sort(dv,6); sort(iv,6); sort(cv,6); cout<<"Tipul double"<<endl; for (i=0; i<6; i++) cout << dv[i] << " "; cout<<endl<<"Tipul int"<<endl; for (i=0; i<6; i++) cout << iv[i] << " "; cout<<endl<<"Tipul char"<<endl; for (i=0; i<6; i++) cout << cv[i] << " "; } În urma execuţiei acestui program la consolă vor fi afişate următoarele mesaje: Tipul double 0.66 1 3 4.7 7 8 Tipul int -2 3 4 5 9 10 Tipul char 4 a c f h i Compilatorul creează cîte o funcţie de sortare pentru fiecare tip de dată folosit ca argument de apel.

14.2. Clase template O clasă template specifică modul în care pot fi construite clase

Page 189: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 190 -

individuale, diferite prin tipul sau tipurile de date asupra cărore se operează. Prefixul template <class T> specifică declararea unui template cu un argument T. După această introducere, T este folosit exact la fel ca orice tip de date, în tot domeniul clasei template declarate. Numele unei clase template urmat de numele tipurilor de date folosite ca argumente, încadrate între parantezele < şi > este numele unei clase (definite aşa cum specifică template-ul) şi poate fi folosită la fel ca oricare altă clasă. Utilizarea template-urilor implică generarea de către compilator a fiecarei clase care corespunde tipului (sau tipurilor) de date folosit la declararea unui obiect. Exemplu rezolvat Să elaborăm un program care va prelucra elementele unui vector de orice tip ordinal. #include<iostream.h> template <class T> class vector{ public: T *v,x; int n; vector(int c){n=c; v=new T[n];} void citire(); void afisare(); void sortare(); ~vector(){delete []v;} }; template <class T> void vector<T>::citire(){ for(int i=0;i<n;i++) { cout<<"Introdu elementul "<<i<<” “; cin>>v[i]; } } template <class T> void vector<T>::afisare(){ for(int i=0;i<n;i++) cout<<v[i]<<" "; cout<<endl; } template <class T> void vector<T>::sortare(){ int i,j; for(i=1; i<n; i++) { x = v[i]; j = i - 1; while((j >= 0) && (x < v[j])) { v[j+1] = v[j]; j--; } v[j+1] = x; }} main(){ vector<int> v1(5);

Page 190: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 191 -

vector<double> v2(5); vector<char> v3(5); cout<<" 5 valori int "<<endl; v1.citire(); cout<<" 5 valori double "<<endl; v2.citire(); cout<<" 5 valori char "<<endl; v3.citire(); cout<<"valori citite"<<endl; v1.afisare(); v2.afisare(); v3.afisare(); cout<<"vectorii sortati"<<endl; v1.sortare(); v1.afisare(); v2.sortare(); v2.afisare(); v3.sortare(); v3.afisare(); } În urma execuţiei acestui program la consolă vor fi afişate următoarele mesaje: 5 valori int Introdu elementul 0 2 Introdu elementul 1 3 Introdu elementul 2 4 Introdu elementul 3 5 Introdu elementul 4 6 5 valori double Introdu elementul 0 6.7 Introdu elementul 1 8.3 Introdu elementul 2 2.3 Introdu elementul 3 6.9 Introdu elementul 4 0.34 5 valori char Introdu elementul 0 w Introdu elementul 1 4 Introdu elementul 2 f Introdu elementul 3 g Introdu elementul 4 y valori citite 2 3 4 5 6 6.7 8.3 2.3 6.9 0.34 w 4 f g y vectorii sortati 2 3 4 5 6 0.34 2.3 6.7 6.9 8.3 4 f g w y

Page 191: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 192 -

Am decis ca în varianta electronică să includ o parte din materialul publicat în: Gîncu S., Utilizarea şabloanelor în limbajul C++, În: Didactica Pro, Nr. 6 (64) decembrie 2010, p.12-15, [disponibil online] http://www.prodidactica.md/revista/Revista_64.pdf

Ierarhizarea şabloanelor

Prin intermediul şabloanelor clasele pot fi ierarhizate. Ierarhizarea se

poate efectua prin două direcţii:

ü Prin moştenire. „Atunci când o clasă transmite parametri sau

funcţionalitatea altei clase, care la rândul său, se consideră clasă de bază pentru

o altă ierarhie de moştenire”.

ü Prin agregare. „Agregarea este relaţia între două obiecte în care unul

dintre obiecte aparţine celuilalt obiect. Agregarea redă aparenţa unui obiect la

un alt obiect. Semantic, agregarea indică o relaţie de tip "part of" ("parte

din")”.

Moştenirea şabloanelor

Clasele template ca şi clasele obişnuite susţin mecanismul de moştenire. Toate principiile de bază ale moştenire rămân neschimbate. Astfel se oferă posibilitatea de a construi modele ierarhice de clase. Fie dată ierarhia:

Problema 3

Se consideră drept bază clasa dreptunghi, iar în calitate de derivată clasa prismă. Pentru această ierarhie va fi realizat polimorfismul pentru metodele citire, afisare, suprafata şi volum. Se va descrie şi constructorii ambelor clase.

Page 192: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 193 -

#include<iostream.h> template <class T> class drept { public: T a,b; drept(){}; drept(T,T); virtual void citire(); virtual void afisare(); virtual T suprafata(); virtual T volum(){return 0;}//metodă virtuala pura }; template <class T> drept<T>::drept(T x, T y){a=x;b=y;} template <class T> void drept<T>::citire(){ cout<<"a=";cin>>a; cout<<"b=";cin>>b; } template <class T> void drept<T>::afisare(){ cout<<"Dreptunghi lungimile laturilor: "<<a<<" "<<b<<endl; cout<<"Suprafata: "<<suprafata()<<endl; } template <class T> T drept<T>::suprafata(){return a*b;} template <class T> class prisma : public drept< T> { public: T h; prisma(){}; prisma(T,T,T); void citire(); void afisare(); T suprafata(); T volum(); }; template <class T> prisma<T>:: prisma(T x,T y,T z):drept<T>(x,y){h=z;} template <class T> void prisma<T>::citire(){ drept<T>::citire(); cout<<"h=";cin>>h; } template <class T> void prisma<T>::afisare(){ cout<<"Prisma lungimile laturilor bazei: "; cout<<a<<" "<<b<<"Inaltimea: "<<h<<endl; cout<<"Suprafata: "<<suprafata()<<" Volumul: "<<volum()<<endl; } template <class T> T prisma<T>::suprafata(){ return 2*(a*b+a*h+b*h);} template <class T> T prisma<T>::volum(){ return drept<T>::suprafata()*h;} int main(){ int i; double st,vt; drept<int> *p[4]; p[0]=new drept<int>(2,3);

Page 193: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 194 -

p[1]=new prisma<int>(4,2,7); p[2]=new drept<int>; p[2]->citire(); p[3]=new prisma<int>;p[3]->citire(); cout<<"Datele introduse de tipul int"<<endl; for(i=0;i<4;i++) p[i]->afisare(); drept<double> *t[4]; t[0]=new drept<double>(2.5,3); t[1]=new prisma<double>(4.3,2,7.4); t[2]=new drept<double>; t[2]->citire(); t[3]=new prisma<double>;t[3]->citire(); cout<<"Datele introduse de tipul double"<<endl; for(i=0;i<4;i++) t[i]->afisare(); prisma<double> b[3]; cout<<"Dati datele a 3 prisme"<<endl; for(i=0;i<3;i++) b[i].citire(); vt=st=0.0; cout<<"Datele introduse"<<endl; for(i=0;i<3;i++){ b[i].afisare(); vt+=b[i].volum(); st+=b[i].suprafata(); } cout<<"Volumul total:="<<vt<<endl; cout<<"Suprafata totala:="<<st<<endl; return 0; }

Ierarhizarea şabloanelor prin agregare

Un alt mecanism pentru crearea ierarhiilor de clase, este agregarea. Aceasta presupune că un obiect este inclus în totalitate într-un alt obiect. Exemple de astfel de ierarhii: lista, coada, arbori, etc. Problema 4 este un program prin intermediul căruia este creată o stivă. Problema 4 #include <conio.h> #include <iostream.h> #include <iomanip.h> template <class T> class celula{ public: T elem; celula *next; celula(){next=NULL;} void citire(); void afisare(); }; template <class T> void celula<T>::citire(){cin>>elem;}

Page 194: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 195 -

template <class T> void celula<T>::afisare(){ cout<<setw(6)<<elem;} template <class T> class stiva{ public: celula<T> *curent; stiva(){curent=NULL;} void creare(); void parcurge(); void inserare(); void exclude(); ~stiva(); }; template <class T> stiva<T>::~stiva(){ while(curent!=NULL) exclude();} template <class T> void stiva<T>::creare(){ int c; cout<<"Introdu numarul de elemente din stiva"<<endl;cin>>c; for(int i=0;i<c;i++) { if(curent==NULL) { curent=new celula<T>; curent->citire(); }else inserare(); } } template <class T> void stiva<T>::parcurge(){ celula<T> *p; p=curent; while(p!=NULL) { p->afisare(); p=p->next; }cout<<endl; } template <class T> void stiva<T>::inserare(){ celula<T> *q; q=new celula<T>; q->citire(); q->next=curent; curent=q; } template <class T> void stiva<T>::exclude(){ celula<T> *q; q=curent; curent=curent->next; delete q; } template <class T> void meniu( stiva<T> a){ char c; a.creare(); clrscr(); do{ cout<<"Alegeti una dintre optiuni:"<<endl; cout<<"1-Parcurge"<<endl;

Page 195: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 196 -

cout<<"2-Inserare"<<endl; cout<<"3-Exclude"<<endl; cout<<"0-iesire"<<endl; c=getch();clrscr(); switch(c){ case '1':a.parcurge();getch();break; case '2':a.inserare();break; case '3':a.exclude();break; }clrscr(); }while(c!='0'); } int main(){ clrscr(); cout<<"Stiva de numere intregi"<<endl; stiva<int> sn; meniu(sn); cout<<"Stiva de caractere"<<endl; stiva<char> sc; meniu(sc); return 0; }

Page 196: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 197 -

Cuprins Prefaţă..................................................................................................

3

Capitolul I. Platforma BCB

§ 1. Mediul de dezvoltare integrat BCB............................................... 4 § 2. Structura unei aplicaţii BCB.......................................................... 12 § 3. Aplicaţii de consolă....................................................................... 15 § 4. Generalităţi.................................................................................... 18 § 5. Clasa TForm............................... .................................................. 20 § 6. Clasa TButton............................... ................................................ 27 § 7. Clasa TEdit............................... .................................................... 27 § 8. Clasa AnsiString............................................................................ 29 § 9. Clasa TLabel.................................................................................. 31 § 10. Ferestre pentru afişarea mesajelor............................................... 39 § 11. Ferestre pentru citirea datelor...................................................... 41 § 12. Aplicaţii multiforme. Ferestre modale......................................... 42 § 13. Butoane şi cutii de grupare.......................................................... 47 § 14. Clasa TMemo.............................................................................. 51 § 15. Gestiunea meniurilor................................................................... 55 § 16. Elemente de grafică..................................................................... 64 § 17. Cutii de dialog............................................................................. 75 § 18. Liste de opţiuni şi casete combinate............................................ 82 § 19. Clasa TStringGrid.................................................................... .... 87 § 20. Prelucrarea datei calendaristice................................................... 90

Page 197: Borland C Builder. Ghid de Initiere

Copie autorizata pentru studenții CFBC

- 198 -

§ 21. Prelucrarea fişierelor şi cataloagelor........................................... 97 § 22. Crearea obiectelor în timpul execuţiei aplicaţiei......................... 104 Capitolul II. Prelucrarea bazelor de date

§ 1. Noţiuni generale............................................................................ 110 § 2. Realizarea accesului la date........................................................... 116 § 3. Alte componente ale paletei Data Controls................................... 123 § 4. Interogări....................................................................................... 130 § 5. Rapoarte......................................................................................... 134 § 6. Tehnologia ADO........................................................................... 138

Capitolul III. Programarea Orientată spre Obiecte cu C++

§ 1. Preliminarii.................................................................................... 148 § 2. Clase.............................................................................................. 149 § 3. Pointerul *this............................................... ................................. 152 § 4. Funcţii inline.................................................................................. 152 § 5. Constructor.................................................................................... 153 § 6. Destructor...................................................................................... 155 § 7. Funcţii prietene.............................................................................. 158 § 8. Alocarea dinamică a obiectelor..................................................... 159 § 9. Supraîncărcarea operatorilor.......................................................... 162 § 10. Moştenirea obiectelor.................................................................. 169 § 11. Constructori şi destructori în clasele derivate.............................. 172 § 12. Funcţii virtuale, clase abstracte şi polimorfism........................... 176 § 13. Moştenirea multiplă..................................................................... 182 § 14. Programarea generică................................................................. 187