Programare

75
CAPITOLUL 1 Introducere în Programarea Orientată- Obiect Programarea orientată – obiect (POO) revoluţionează aproape orice aspect al dezvoltării aplicaţiilor cu Visual FoxPro, de la faza de analiză şi proiectare până la faza de scriere a codului de program şi testarea aplicaţiilor şi a componentelor aplicaţiilor. De asemenea, Visual FoxPro, ca şi Visual C++ de altfel, este un limbaj hibrid, adică dezvoltatorii de programe pot alege între metodele POO şi programarea modulară. POO sre o altfel de abordare decât programarea modulară, în faptul că POO lucrează cu entităţi de genul obiectelor. Dacă se doreşte adaptarea unei aplicaţii într-o nouă formă, având în vedere că există o formă modificată a unei aplicaţii mai vechi, se realizează modificările pe baza unui procedeu numit subclasare, şi anume preluarea vechilor obiecte ale aplicaţiei şi modificarea acestora după noile proprietăţi. Comportamentul şi 1

description

Programare orientata

Transcript of Programare

Page 1: Programare

CAPITOLUL 1

Introducere în Programarea Orientată-Obiect

Programarea orientată – obiect (POO) revoluţionează aproape

orice aspect al dezvoltării aplicaţiilor cu Visual FoxPro, de la faza de

analiză şi proiectare până la faza de scriere a codului de program şi

testarea aplicaţiilor şi a componentelor aplicaţiilor. De asemenea,

Visual FoxPro, ca şi Visual C++ de altfel, este un limbaj hibrid, adică

dezvoltatorii de programe pot alege între metodele POO şi

programarea modulară. POO sre o altfel de abordare decât

programarea modulară, în faptul că POO lucrează cu entităţi de genul

obiectelor.

Dacă se doreşte adaptarea unei aplicaţii într-o nouă formă,

având în vedere că există o formă modificată a unei aplicaţii mai

vechi, se realizează modificările pe baza unui procedeu numit

subclasare, şi anume preluarea vechilor obiecte ale aplicaţiei şi

modificarea acestora după noile proprietăţi. Comportamentul şi

atributele obiectelor originale sunt automat aduse şi la noile obiecte

modificate, acest lucru numindu-se moştenire. În schimb dacă se

modifică cumva obiectele originale, schimbările făcute sunt aduse

imediat şi asupra obiectelor noi, realizate cu ajutorul subclasării, prin

modificarea obiectelor originale.

POO utilizează nişte termeni, pentru a explica expres

conceptele POO, şi anume: moştenire, încapsulare şi polimorfism.

Primul şi cel mai important concept cheie al POO este

obiectul. Un obiect este un pachet de informaţii şi acţiuni. Un obiect

se conţine pe sine. Toate cunoştiinţele şi comportamentele unui obiect

1

Page 2: Programare

sunt conţinute în acesta. Acest concept este cunoscut sub numnele de

încapsulare. Orice obiect este caracterizat de propiretăţi şi evenimente.

Proprietăţi

Datele dintr+un obiect sunt denumite proprietăţi. O proprietate

(în termenii Visual FoxPro) este foarte simplu o variabilă de memorie

care este ataşată la obiect şi care are un anumit scop. Utilizarea valorii

proprietăţii şi modificarea ei se face utilizând numele obiectului urmat

de punct (.) şi apoi de numele proprietăţii. Propreităţile pot conţine

orice tipuri de date care sunt valide pentru variabilele de memorie

Visual FoxPro. De exemplu, dacă avem o proprietate numită lEsteNou

care este ataşată la un obiect numit oTest, se poate interoga valoarea

proprietăţii în felul următor:

oTest.lEsteNou

Metode

Pe lângă faptul că obiectele au date ataşate, ele pot executa

anumite acţiuni. Aceste acţiuni sunt reprezentate de fapt de codul de

program care este scris în procedurile care sunt ataşate la obiect.

Aceste proceduri sunt denumite de fapt metode. Apelarea unei metode

se face în mod asemănător cu a unei proprietăţi, şi anume numele

obiectului, urmat de punct (.) şi de numele metodei, după cum

urmează:

oTest.Print()

Tehnic, parantezele care apar la sfârşitul numelui metodei sunt

necesare numai dacă se aşteaptă returnarea unei valori sau dacă cumva

se transmit parametrii metodei. Sugestia noastră este de a se utiliza 2

Page 3: Programare

întotdeauna paranteze pentru siguranţă, în acest caz fiind şi siguri că

se apelează o metodă. În cazul apelării unei metode după care se

aşteaptă returnarea unei valori, se poate salva valoarea returnată în

modul următor:

lValoareReturnată = oTest.Print()

Evenimente

Evenimentele sunt acţiuni care se întâmplă. De exemplu,

făcând click pe butonul stânga al mouse-ului se declanşează un

eveniment. Evenimentele pot fi cauzate de acţiunea utilizatorului (ca

în cazul de mai sus) sau de către sistem însuşi (ca în cazul în care

apare o eroare). Dacă creezi o clasă de tipul unui buton de comandă în

Visual FoxPro, poţi ataşa cod (ca o metodă) la evenimente. Dacă se

declanşează evenimentul (de exemplu, utilizatorul face click stânga cu

mouse-ul deasupra butonului de comandă), metoda asociată (care este

metoda click) este apelată automat. În Visual FoxPro, se pot ataşa

metode la tot felul de evenimente: dacă se dă click pe mouse, dacă se

ia mâna de pe mouse, se poate apela o metodă în momentul în care un

obiect este creat (evenimentul Init) sau invers în momentul în care

obiectul este şters (evenimentul Destroy). Apelarea evenimentelor se

face în acelaşi mod ca şi apelarea metodelor.

Clase

Până la acest punct, toate discuţiile din acest capitol au fost

centrate în jurul obiectelor. În programarea orientată-obiect, obiectele

nu sunt niciodată programate, ci mai degrabă obiectele de bază

(numite clase) pot fi programate. Toate obiectele sunt instanţiate

(adică, create) pornind de la clase. De aceea, toate programele se fac

3

Page 4: Programare

la nivelul clasei. Odată un obiect instanţiat pe baza unie clase, tot ceea

ce trebuie să faci este să interacţionezi cu el. Nu se adaugă sau se

modifică metode existente într-un obiect, ci mai degrabă se adaugă şi

se modifică metode în clase pe baza cărora se instanţiază obiectele.

Un exemplu de clasă:

DEFINE CLASS Clasă AS Custom

cNume = ""

cTip = ""

lEsteNou = .F.

PROCEDURE AratăValoare

? this.cNume

? this.cTip

IF this.lEsteNou

? "Sunt Nou"

ELSE

? "Sunt Vechi"

ENDIF

ENDPROC

ENDDEFINE

Define Class Clasă as Custom

Această linie de program spune Visual FoxPro că utilizatorul

defineşte o nouă clasă numită Clasă bazată pe o clasă de bază Custom.

cNume = ""

cTip = ""

4

Page 5: Programare

lEsteNou = .F.

Liniile anterioare sunt cunoscute ca declaraţii de cod. În aceată

parte a definiţiei clasei, se enumeră variabilele (proprietăţile)

obiectului şi valorile lor iniţiale.

PROCEDURE AratăValoare

? this.cNume

? this.cTip

IF this.lEsteNou

? "Sunt Nou"

ELSE

? "Sunt Vechi"

ENDIF

ENDPROC

Aceasta este o definiţie a unei metode. Apelarea unei metode

va executa toate liniile de cod dintre linia PROCEDURE până la linia

ENDPROC.

Instanţierea Obiectelor

Un obiect este instanţiat cu ajutorul funcţiei

CREATEOBJECT(). Sintaxa pentru crearea unei instanţe a clasei

Clasă:

oClasă = CREATEOBJECT("Clasă")

oClasă este o variabilă de memorie simplă de tipul Object.

5

Page 6: Programare

Pentru a accesa membrii clasei Clasă, se pot utiliza următoarele

comenzi:

? oClasă.cNume && Iniţial gol

oClasă.cNume = "Popescu Ion"

? oClasă.cNume && Acum arată "Popescu Ion"

oClasă.AratăValoare() && Execută metoda

AratăValoare

Cuvântul cheie THIS înseamnă că se accesează metodele şi

variabilele membre ale obiectului însuşi.

Subclasarea-Bazarea unei Clase pe altă Clasă

Să presupunem că vom defini o clasă numită Formular şi care

defineşte de fapt un formular cu anumite proprietăţi ale sale.

DEFINE CLASS Formular AS form

Width=100

Height=150

PROCEDURE Init

Caption = “Formular1”

ENDPROC

ENDDEFINE

Putem crea o subclasă a clasei create anterior şi pe care o

vom denumi Formular1, subclasă care va moşteni toate proprietăţile

clasei părinte, adică clasa Formular, dar în plus va avea proprietăţi în

plus faţă de clasa părinte.

DEFINE CLASS Formular1 AS Formular

6

Page 7: Programare

Name=”Formular”

PROCEDURE Click

Caption = “Formular cu click”

ENDPROC

ENDDEFINE

O însuşire foarte interesantă a moştenirii poate accepta ceea

ce îţi convine de la clasa părinte şi poate rescrie restul după cum

doreşti. Acest lucru se poate realiza prin rescrie proprietăţii sau a

metodei respective în subclasa respectivă. De exemplu în clasa

Formular, clasa părinte a subclasei Formular1, avem un eveniment

Init, în care dîm titlul formularului ca fiind Formular1, putem rescrie

acest lucru în subclasă prin rescrierea procedurii respective.

DEFINE CLASS Formular1 AS Formular

Name=”Formular”

PROCEDURE Init

Caption = “Formular2”

ENDPROC

ENDDEFINE

În acest caz am redenumit evenimentul din clasa părinte

rescriind aceiaşi procedură în subclasa Formular1.

De asemenea, să presupunem că este posibil să doriţi să lansaţi

în execuţie metoda din clasa părinte întâi şi apoi să adăugaţi ceva cod

de program în plus în metoda din subclasă, ca în exemplul următor:

DEFINE CLASS Formular2 AS Formular

Name=”Formular”

PROCEDURE Init7

Page 8: Programare

Formular1::Init()

Caption = “Formular2”

WAIT WINDOW “Exemplu de apelare a unei

metode din clasa părinte”

ENDPROC

ENDDEFINE

Operatorul (::) este utilizat pentru a apela metodele din clasele

superioare în ierarhia claselor.

Metode şi Proprietăţi Protejate

La crearea unui obiect trebuie să decideţi dacă doriţi să fie

public, adică să poată să fie utilizat şi de alte clase sau numai în cadrul

clasei respective. Soluţia în acest caz este să creaţi metode şi

proprietăţi protejate, care nu pot fi accesibile din afara clasei în care s-

au definit respectivele metode şi proprietăţi. Acest lucru se realizează

scriind:

PROTECTED numeproprietate în secţiunea în care declaraţi

definiţiile de cod, sau PROTECTED în faţa liniei PROCEDURE.

DEFINE CLASS Clasă AS Custom

PROTECTED cNume

cNume = ""

cTip = ""

lEsteNou = .F.

PROTECTED PROCEDURE AratăValori

? this.cNume

? this.cTip

8

Page 9: Programare

IF this.lEsteNou

? "ESTE NOU"

ELSE

? "ESTE VECHI"

ENDIF

ENDPROC

ENDDEFINE

În acest exemplu ambele proprietăţi cNume şi cTip sunt

protejate, ca şi metoda AratăValori care este şi ea protejată. Încercările

de a le accesa din afara clasei vor produce erori ca şi cum aceste

proprietăţi şi metode nu ar exista.

Polimorfism

Polimorfismul este un alt concept care trebuie dezbătut dacă se

vorbeşte despre programarea orientată-obiect. Polimorfismul este

capacitatea de a da metodelor şi proprietăţilor din diferite clase acelaşi

nume, chiar dacă acele metode şi proprietăţi fac lucruri cu totul

diferite de la o clasă la alta. De exemplu următoarele linii de comandă:

oObiect1 = CREATEOBJECT("Formular1")

oObiect2 = CREATEOBJECT("Telefon")

oObiect1.Execută() &&Lansează în execuţie metoda

Execută a Obiect1

oObiect2.Execută() &&Lansează în execuţie metoda

Execută a Obiect2

9

Page 10: Programare

Crearea Obiectelor

oFact = CREATEOBJECT("Factura")

această linie de cod de program transmite un mesaj clasei Factura

spunându-i să creeze un obiect numit oFact bazat pe această clasă.

Atribuirea unei valori unei proprietăţi

lnValoare = oFact.nValoare

Această linie de cod de program transmite un mesaj obiectului oFact

şi îi spune să ia valoarea proprietăţii nValoare şi să o returneze la

lnValoare.

Apelarea unei metode

oFact.Afişare && Afişează obiectul oFact

Se transmite un mesaj obiectului oFact spunându-i să execute

metoda Afişare.

Analiză şi Proiectare cu POO

Programarea orientată-obiect nu începe cu scrierea codului de

program, cu toate că până acum am discutat numai despre

implementarea fazei de scriere a obiectelor, iar acest pas este totuşi

ultimul în crearea programelor orientate-obiect.

Primul pas ce trebuie făcut este de a analiza domeniul

problemei şi de a proiecta ierarhia claselor. Este destul de simplu de

realizat dacă se respectă o anumită disciplină. Analiştii au apreciat că

în realizarea unei aplicaţii 70% din timp se pierde cu analiza orientată-10

Page 11: Programare

obiect (AOO) şi proiectarea orientată-obiect (POO). Există mai multe

tipuri de metodologii create de nume populare în domeniul bazelor de

date Grady Booch, Ivar Jacobsen şi Rebecca Wirfs-Brock.

Crearea şi utilizarea claselor cu Visual FoxPro

Definirea claselor se face utilizând constructorul DEFINE

CLASS / ENDDEFINE, după cum urmează:

DEFINE CLASS <numeclasă> AS <clasădebază>

*-- Aici se face declararea codului

PROTECTED <listă variabile membru>

PROCEDURE <metodăproc> (param1, param2 ....)

LOCAL <listă de variabile locale>

*-- Aici se scrie codul procedurii

ENDPROC

FUNCTION <metodăfunc> (param1, param2 ....)

LOCAL <listă de variabile locale>

*-- Aici se scrie codul funcţiei

RETURN <valoarereturnată>

ENDFUNC

ENDDEFINE

DEFINE CLASS <numeclasă> AS <superclasă>

Această linie de cod comunică Visual FoxPro că se crează o

nouă clasă. Toate liniile de cod de program dintre DEFINE şi

ENDDEFINE ţin de definiţia clasei respective. <numeclasă> este

11

Page 12: Programare

numele clasei nou create şi <superclasă> este numele clasei pe baza

căreia se crează clasa cea nouă.

Termenul superclasă mai poate fi întâlnit în terminologia de

specialitate şi ca o clasă părinte. Prin definiţie orice clasă creată în

Visual FoxPro este o subclasă a altei clase. La cel mai înalt nivel

clasele create în Visual FoxPro sunt subclase a ccea ce Microsoft

numeşte clase de bază, clase care apar în tabelul următor.

Visual FoxPro 6.0 Clase de Bază

Nume Clasă Descriere

ActiveDoc Obiectul document active care poate fi găzduit într-un browser de tipul Internet Explorer.

CheckBox O casetă de validare standard, control similar cu o casetă de validare din FoxPro 2.x.

Column O coloană într-un control grid.

ComboBox O casetă combinată (combo box) similar cu un control pop-up în FoxPro 2.x.

CommandButton Echivalent cu un pushbutton în FoxPro 2.x.

CommandGroup Un grup de butoane de comandă care operează împreună. Sunt echivalente cu un grup de pushbutton din FoxPro 2.x controlate de o variabilă

Container Un obiect generic proiectat pentru a putea conţine alte obiecte în el. Este utilizat în cazul creării unei clase care conţine mai multe obiecte în ea.

Control Acelaşi lucru ca şi clasa container , însă de data aceasta referirea nu se mai face

12

Page 13: Programare

Nume Clasă Descriere

la clasa container ci la clasa control.

Cursor Definiţia unui cursor într-un mediu de date.

Custom În mod primar se foloseşte pentru obiecte care nu sunt vizuale, dar care pot conţine obiecte vizuale ca membrii.

Data O colecţie de medii de date cursori şi relaţii pentru a putea fi deschise şi închise ca o unitate.

EditBox O regiune de editare echivalentă cu FoxPro 2.6.

Form Un singur "screen", format pentru introducerea de date. Este obiect container care poate conţine şi alte obiecte în el.

FormSet Un obiect tip container care are ca membrii mai multe formulare (forms).

Grid Un obiect de tip container care permite afişarea şi editarea informaţiilor în formatul tabel.

Header Antetul unei coloane a unui tabel.

Hyperlink Object Furnizează butoane, imagini sau etichete care la un click pot lansa pagini WEB.

Image O imagine.

Label O etichetă a unui obiect.

Line O linie desenată.

ListBox O listă derulantă.

OleControl Un control bazat pe un obiect OLE.

OptionButton Un singur obiect radio-tip obiect.

OptionGroup Mai multe butoane radio care operează ca un singur control. Este echivalentul

13

Page 14: Programare

Nume Clasă Descriere

unui obiect radio button din FoxPro 2.x.

Page O singură pagină din cadrul unui formular pagină.

PageFrame Un control de tip pagină. Fiecare pagină din cadrul unui control de tip pagină este o pagină separată. Formularul pagină este un control tip container deoarece el poate conţine mai multe obiecte.

ProjectHook Creează instanţe ale proiectului deschis care permit acces la nivel program către evenimentele proiectului.

Relation O definiţie a unei relaţii între două cursoare într-un mediu de date.

Separator Obiect care pune spaţii albe între controale pe un toolbar.

Shape O formă (un cerc sau un dreptunghi).

Spinner Echivalentul unui spinner control din FoxPro 2.x.

TextBox Echivalentul unui GET control din FoxPro 2.x.

Timer Un obiect vizual care nu apare pe formă. Acest control este proiectat pentru a permite acţiuni la intervale de timp fixe.

ToolBar O bară de instrumente, care este un grup de obiecte care pot fi lipite în partea de sus, jos, sau lateral ecranului. Când nu este lipită, o bară de instrumente arată asemănător unei forme.

Clase

14

Page 15: Programare

Clasele pot fi caracterizate în două tipuri şi anume clase

vizuale şi clase nonvizuale.

Clase Vizuale

O clasă vizuală este o clasă proiectată pentru scopul de a putea

fi afişată. De exemplu, un formular este o clasă vizuală. Principalul

scop al claselor vizuale este însă crearea interfeţei (deseori numită şi

GUI - Graphical User Interface sau interfaţa grafică a utilizatorului).

În această categorie de clase se pot proiecta clase în

următoarele subcategorii:

- controale singure

- combinaţii de controale

- containere

- formulare

- toolbar-uri.

Butonul de comandă OK este un bun exemplu de control

singular, care la execuţia unui click părăseşte formularul. Pentru a

realiza acest lucru se crează o clasă de tipul CommandButton în care

se definesc câteva proprietăţi ale butonului OK şi bineînţeles

evnimentul Click cu ajutorul căruia părăseşte formularul.

*-- Class: butonok

*-- ParentClass: CommandButton

*-- BaseClass: CommandButton

*

DEFINE CLASS butonok AS CommandButton

AutoSize = .F.

Height = 29

Width = 41

15

Page 16: Programare

Caption = "OK"

Default = .T.

Name = "butonok"

PROCEDURE Click

RELEASE thisform

ENDPROC

ENDDEFINE

Acest buton poate fi plasat în orice formular. Metoda

utilizată de acest buton este RELEASE THISFORM în evenimentul

Click al butonului. În figura nr.1 puteţi vedea un buton OK creat cu

ajutorul codului de program anterior.

Fig.1 Un formular cu un buton care părăseşte formularul

Subclasa unei clase a unui control singular Tehnic, toate

clasele din Visual FoxPro sunt subclase ale unor clase de bază. Să

presupunem că dorim o versiune a butonului creat mai sus, dar cu un

text ajutător (tooltip – text care apare dacă lăsaţi mouse-ul puţin timp

deasupra controlului respectiv).

*-- Class: butonokcuajutor

16

Page 17: Programare

*-- ParentClass: butonok

*-- BaseClass: CommandButton

*-- Subclasă a butonOK – adaugă un ajutor (ToolTip)

.

DEFINE CLASS butonokcuajutor AS okbutton

Height = 29

Width = 41

ToolTipText = "Părăseşte formularul"

Name = "butonokcuajutor"

ENDDEFINE

Observaţi că evenimentul Click de data aceasta nu este

prezent, deoarece este moştenit din clasa părinte. Se adaugă în plus la

această subclasă proprietatea ToolTipText.

De ce subclasă? Se apelează la subclase şi nu se face direct

modificarea în clasa părinte, deoarece ar însemna în caz contrar că

orice modificare în clasa părinte va fi moştenită de toate subclasele

sau instanţele obiectului respectiv.

O clasă container - Navigator Un container de

CommandButtons utilizat pentru navigarea într-o tabelă dintr-un

formular. Pentru a realiza un astfel de container de butoane de

navigarese defineşte în primă fayă clasa container în care se adaugă

instanţele claselor butoanelor de navigare definite ulterior. Adăugarea

la clasa container se face cu ajutorul instrucţiunii ADD OBJECT.

17

Page 18: Programare

Prog. 1 Un Container - Bazat pe un set de butoane de navigare

*-- Class: navigator

*-- ParentClass: container

*-- BaseClass: container

DEFINE CLASS navigator AS container

Width = 350

Height = 32

BackStyle = 0

BorderWidth = 0

Name = "navigator"

ADD OBJECT cmdUrmatoarea AS cmdUrmatoarea

WITH ;

Top = 0, ;

Left = 0, ;

Height = 31, ;

Width = 60, ;

Caption = "Urmatoarea", ;

Name = "cmdUrmatoarea"

ADD OBJECT cmdAnterioara AS cmdAnterioara

WITH ;

Top = 0, ;

Left = 72, ;

Height = 31, ;

Width = 60, ;

Caption = "Anterioara", ;

Name = "cmdAnterioara"

18

Page 19: Programare

ADD OBJECT cmdPrima AS cmdPrima WITH ;

Top = 0, ;

Left = 144, ;

Height = 31, ;

Width = 60, ;

Caption = "Prima", ;

Name = "cmdPrima"

ADD OBJECT cmdUltima AS cmdUltima WITH ;

Top = 0, ;

Left = 216, ;

Height = 31, ;

Width = 60, ;

Caption = "Ultima", ;

Name = "cmdUltima"

ADD OBJECT cmdok AS butonokcuajutor WITH ;

Top = 0, ;

Left = 288, ;

Height = 31, ;

Width = 60, ;

Name = "cmdOK"

ENDDEFINE

DEFINE cmdUrmatoarea AS CommandButton

PROCEDURE Click

SKIP 1

IF EOF()

=Messagebox("Sfârşit de fişier!", 16)

19

Page 20: Programare

GO BOTTOM

ENDIF

thisform.refresh()

ENDPROC

ENDDEFINE

DEFINE CLASS cmdAnterioara AS CommandButton

PROCEDURE Click

SKIP -1

IF BOF()

=Messagebox("Început de fişier!", 16)

GO TOP

ENDIF

thisform.refresh()

ENDPROC

ENDDEFINE

DEFINE CLASS cmdPrima AS CommandButton

PROCEDURE Click

GO TOP

thisform.refresh()

ENDPROC

ENDDEFINE

DEFINE CLASS cmdUltima AS CommandButton

PROCEDURE Click

GO BOTTOM

thisform.refresh()

ENDPROC

ENDDEFINE

20

Page 21: Programare

DEFINE CLASS butonokcuajutor AS okbutton

Height = 29

Width = 41

ToolTipText = "Părăseşte formularul"

Name = "butonokcuajutor"

ENDDEFINE

Fig. 2 Formular cu butoane de navigare

Pornind de la programul anterior în care am definit o clasă

container de butoane de navigare, vom realiza un alt program, care va

avea în plus faţă de cel anterior un buton Nou (acesta va crea o nouă

înregistrare în tabelul test.dbf). Se crează clasa container care va

conţine pe lângă butoanele de navigare şi 2 casete text legate cu

ajutorul proprietăţii ControlSource la tabelul test care se consideră că

este deja adăugat la mediul de date al formularului. Aceste 2 casete

text vor fi legate la 2 câmpuri ale tabelului test şi anume cnume şi ctip.

*-- Form: form1

21

Page 22: Programare

*-- ParentClass: form

*-- BaseClass: form

DEFINE CLASS form1 AS form

Top = 0

Left = 0

Height = 182

Width = 463

DoCreate = .T.

BackColor = RGB(192,192,192)

BorderStyle = 2

Caption = "Form1"

Name = "Form1"

ADD OBJECT text1 AS textbox WITH ;

BackColor = RGB(192,192,192), ;

ControlSource = "test.cnume", ;

Height = 24, ;

Left = 48, ;

Top = 24, ;

Width = 113, ;

Name = "Text1"

ADD OBJECT text2 AS textbox WITH ;

BackColor = RGB(192,192,192), ;

ControlSource = "test.ctip", ;

Height = 24, ;

Left = 48, ;

Top = 60, ;

Width = 113, ;

22

Page 23: Programare

Name = "Text2"

ADD OBJECT navigator1 AS navigator WITH ;

Top = 120, ;

Left = 12, ;

Width = 421, ;

Height = 32, ;

Name = "Navigator1", ;

cmdUrmatoarea.Name = "cmdUrmatoarea", ;

cmdAnterioara.Name = "cmdAnterioara", ;

cmdPrima.Name = "cmdPrima", ;

cmdUltima.Name = "cmdUltima", ;

cmdOK.Top = 0, ;

cmdOK.Left = 360, ;

cmdOK.Height = 31, ;

cmdOK.Width = 61, ;

cmdOK.Name = "cmdOK"

ADD OBJECT form1.navigator1.cmdNou AS

commandbutton WITH ;

Top = 0, ;

Left = 288, ;

Height = 31, ;

Width = 61, ;

Caption = "Nou", ;

Name = "cmdNou"

PROCEDURE cmdNou.Click

APPEND BLANK

thisform.refresh()

ENDPROC

23

Page 24: Programare

ENDDEFINE

Adăugarea butonului Nou la container se face cu ajutorul comenzii

ADD OBJECT sau al metodei AddObject()

Fig.3 Formular cu casete de text

Formularul

În programarea structurată pentru a lansa un formular se

foloseşte comanda DO FORM nume, în schimb în programarea

orientată obiect se crează o instanţă a obiectului părinte cu ajutorul

metodei CreateObject(), iar apoi se apelează metoda Show() a

obiectului respectiv, metodă care îl va afişa..

TIP

În Visual FoxPro 6, puteţi utiliza funcţia NewObject()

pentru a crea obiecte din clase.

oForm = CreateObject("Form")

oForm.Show(1)

sau

24

Page 25: Programare

oForm = NewObject("Form")

oForm.Show(1)

Citirea evenimentelor sistemului

SET CLASS TO junkme

oForm = CreateObject("Form")

oForm.Show()

În programul anterior se creează un formular pe baza unei

instanţieri a clasei de bază Form, apoi se apelează metoda Show().

Problema se pune în felul următor: la apelarea metodei Show()

formularul va apărea şi apoi va dispărea de pe ecran. De aceea este

necesar să se transmită cumva sistemului să citească din nou

evenimentele. Acest lucru se poate realiza cu ajutorul comenzii READ

EVENTS.

Prog.2 Un buton de comandă care lansează un formular

*-- Class: lansarea în execuţie a unui formular

*-- ParentClass: CommandButton

*-- BaseClass: CommandButton

DEFINE CLASS lansareformular AS CommandButton

Height = 29

Width = 94

Caption = "LansareFormular"

oform = .NULL.

Name = " LansareFormular "

PROCEDURE Click

this.oForm = CreateObject("Form")

this.oForm.Show()25

Page 26: Programare

ENDPROC

ENDDEFINE

Mediul de date sau Data Environment Una dintre cele mai

mari diferenţe dintre crearea formularului .SCX şi crearea unei clase

de tip formular se află în zona mediului de date. Folosirea mediului de

date se face pentru a specifica ce tabele, vederi sau relaţii sunt utilizate

în formular. La crearea unui formular nu se poate salva mediul de date

împreună cu el, dacă se salvează un formular ca o clasă care are un

mediu de date ataşat, mediul de date este pierdut. De aceea se creează

acest mediu de date cu ajutorul codului de program. De obicei

plasarea codului de program referitor la deschiderea mediului de date

se face în evenimentul Load, sau într-o procedură numită Load.

Astfel se crează clasa container (formularul) care va conţine casetele

de text, legate la tabela Client cu ajutorul proprietăţii ControlSource,

şi bineînţeles etichetele corespunzătoare fiecărei casete de text. În

evenimentul Load al formularului deschidem baza de date test

specificând calea unde se află memorată în calculator, iar apoi

deschidem tabela Client.

Prog.3 Un formular care deschide o tabelă de date pentru editare

*-- Class: formularcudateclient

*-- ParentClass: form

*-- BaseClass: form

DEFINE CLASS formularcudateclient AS form

DataSession = 2

Height = 238

26

Page 27: Programare

Width = 356

DoCreate = .T.

AutoCenter = .T.

BackColor = RGB(192,192,192)

Caption = "Exemplu de Date Client"

Name = "formularcudate"

ADD OBJECT txtcodcl AS TextBox WITH ;

ControlSource = "client.codcl", ;

Enabled = .F., ;

Height = 24, ;

Left = 120, ;

Top = 24, ;

Width = 205, ;

Name = "txtCodcl"

ADD OBJECT txtcompanie AS TextBox WITH ;

ControlSource = "client.companie", ;

Height = 24, ;

Left = 120, ;

Top = 72, ;

Width = 205, ;

Name = "txtCompanie"

ADD OBJECT txtcontact AS TextBox WITH ;

ControlSource = "client.contact", ;

Height = 24, ;

Left = 120, ;

Top = 120, ;

Width = 205, ;

27

Page 28: Programare

Name = "txtContact"

ADD OBJECT txttitlu AS TextBox WITH ;

ControlSource = "client.titlu", ;

Height = 24, ;

Left = 120, ;

Top = 168, ;

Width = 205, ;

Name = "txtTitlu"

ADD OBJECT label1 AS label WITH ;

AutoSize = .T., ;

BackStyle = 0, ;

Caption = "Cod Client:", ;

Height = 18, ;

Left = 12, ;

Top = 24, ;

Width = 80, ;

Name = "Label1"

ADD OBJECT label2 AS label WITH ;

AutoSize = .T., ;

BackStyle = 0, ;

Caption = "Companie:", ;

Height = 18, ;

Left = 12, ;

Top = 72, ;

Width = 64, ;

Name = "Label2"

28

Page 29: Programare

ADD OBJECT label3 AS label WITH ;

AutoSize = .T., ;

BackStyle = 0, ;

Caption = "Contact:", ;

Height = 18, ;

Left = 12, ;

Top = 120, ;

Width = 52, ;

Name = "Label3"

ADD OBJECT label4 AS label WITH ;

AutoSize = .T., ;

BackStyle = 0, ;

Caption = "Titlu:", ;

Height = 18, ;

Left = 12, ;

Top = 168, ;

Width = 32, ;

Name = "Label4"

PROCEDURE Load

OPEN DATA _SAMPLES+" \test.dbc"

USE client

ENDPROC

ENDDEFINE

TIP

Visual FoxPro 6 are o nouă variabilă de sistem numită

29

Page 30: Programare

_SAMPLES. Aceasta reţine calea unde sunt memorate

exemplele de coduri de program din directorul părinte

Visual Studio 6, aceste exemple toate fiind memorate în

acelaşi director.

Fig. 4 Formular cu casete de text legat la un tabel

Prog. 4 Formularul de date precedent cu butoanele de navigare

adăugate

*-- Class: formularcudateclientcunavigator

*-- ParentClass: formularcudateclient

*-- BaseClass: form

DEFINE CLASS formularcudateclientcunavigator AS

formularcudateclient

Height = 283

Width = 370

DoCreate = .T.

Name = " formularcudateclientcunavigator "

30

Page 31: Programare

txtCodcl.Name = "txtCodcl"

txtCompanie.Name = "txtCompanie"

txtContact.Name = "txtContact"

txtTitlu.Name = "txtTitlu"

Label1.Name = "Label1"

Label2.Name = "Label2"

Label3.Name = "Label3"

Label4.Name = "Label4"

ADD OBJECT navigator1 AS navigator WITH ;

Top = 240, ;

Left = 12, ;

Width = 350, ;

Height = 32, ;

Name = "Navigator1", ;

cmdUrmatoarea.Name = "cmdUrmatoarea", ;

cmdAnterioara.Name = "cmdAnterioara", ;

cmdPrima.Name = "cmdPrima", ;

cmdUltima.Name = "cmdUltima", ;

cmdOK.Name = "cmdOK"

ENDDEFINE

Construirea formularelor cu ajutorul claselor sau utilizarea

Proiectantului de Formulare?

Utilizarea proiectantului de formulare versus formularele create

sub forma claselor este o întrebare la care se răspunde greu.

Ambele metode merg bine în aplicaţii.

Mixarea şi schimbarea diferitelor feluri de abordare nu face decât

31

Page 32: Programare

să îngreuneze menţinerea aplicaţiilor respective peste timp.

Proiectantul de Formulare poate fi folosit pentru crearea de seturi

de formulare, care conţin mai mult de un formular. Astfel se

poate controla care dintre formulare este vizibil la un moment

dat.

Clasele mediului de date (data environment)

La crearea unui formular cu Proiectantul de formulare din

Visual FoxPro, trebuiesc specificate tabelele cu care lucrează

formularul respectiv prin crearea unui mediu de date pentru formular.

După cum apare şi în figura următoare un mediu de date este alcătuit

din cursori şi relaţii. Vă puteţi gândi la un mediu de date ca la un

pachet (de fapt un container), care conţine informaţiile necesare pentru

configurarea mediului de date.

32

Page 33: Programare

Fig. 5 Mediul de date al unui formular

Există o limitare a mediului de date, cursorii şi clasele nu pot fi

create vizual, ci pot fi create numai prin cod de program.

Clasa Cursor

Clasa Cursor defineşte conţinutul zonei de lucru, se vor detalia

proprietăţile, evenimentele şi metodele acestei clase.

Proprietăţile Clasei Cursor

Proprietăţi Descriere

Alias Configurează aliasul zonei de lucru când se

deschide

33

Page 34: Programare

BufferModeOverride Specifică modul de buffering pentru cursor:

0     Nimic (fără buffering)

1     Este configurat la nivel de

formular

2     Pessimistic row buffering

3     Optimistic row buffering

4     Pessimistic table buffering

5     Optimistic table buffering

dacă clasa mediului de date nu este utilizată într-

un formular se foloseşte orice valoare în afară de

1.

CursorSource Specifică sursa pentru datele cursorului. Poate fi

o tabelă, o bază de date, o vedere sau o tabelă

liberă.

Database Specifică baza de date care conţine sursa

cursorului, trebuie menţionată calea completă.

Exclusive Specifică dacă sursa cursorului este deschisă în

mod exclusiv şi acceptă valori logice.

Filter Specifică şirul de caractere după care se face

filtrarea

NoDataOnLoad Dacă această proprietate este setată pe .T.,

deschide cursorul şi crează structura, dar nici o

dată nu va fi descărcată în cursor. Acest lucru se

va realiza cu ajutorul lui Requery().

Order Specifică ordinea de afişare a datelor. Trebuie

specificat un tag de index.

ReadOnly Dacă această proprietate este setată pe .T., atunci

datele nu vor putea fi modificate.

34

Page 35: Programare

Evenimente şi Metode:  Clasa Cursor suportă numai

evenimentele Init, Destroy şi Error.

Clasa Relaţii

Clasa Relaţii specifică informaţiile necesare pentru a configura

o relaţiile între doi cursori dintr-un mediu de date.

Proprietăţi

SELECT Factura

SET ORDER TO cCodCl

SELECT Client

SET RELATION TO cCodCl INTO Factura

Proprietăţile Clasei Relaţii

Proprietăţi Descrierea

ChildAlias Aliasul tabelei copil. Ex. Factura.

ChildOrder Specifică ordinea din tabelul copil. Ex. cCodCl.

OneToMany Specifică dacă este relaţie una-la-mai-multe.

ParentAlias Aliasul tabelei părinte. Ex. Client

RelationalExpr Expresia după care se face relaţia. Ex. cCodCl.

Evenimente şi Metode  Clasa relaţie suportă numai

evenimentele Init, Destroy şi Error.

Clasa Mediu de date (DataEnvironment)

Clasa DataEnvironment este un container pentru cursori şi

relaţii, care luate împreună formează un mediu de date.

35

Page 36: Programare

Proprietăţile Clasei DataEnvironment

Proprietăţi Descrierea

AutoCloseTables Specifică dacă tabelele ar trebui închise automat în

cazul în care obiectul este părăsit.

AutoOpenTables Specifică dacă tabelele ar trebui deschise automat

în cazul în care obiectul este instanţiat.

InitialSelectedAlias Specifică care alias ar trebui selectat iniţial.

Metode Adiţionale ale Clasei DataEnvironment

Metodă Descrierea

CloseTables() Această metodă închide toate tabelele şi cursorii din

clasa mediului de date.

OpenTables() Această metodă deschide toate tabelele şi cursorii din

clasa mediului de date.

Evenimentele Clasei DataEnvironment

Eveniment Descrierea

BeforeOpenTables() Acest eveniment se execută înainte ca tabelele să

fie deschise

AfterCloseTables() Acest eveniment se execută după ce tabelele sunt

închise.

Prog. 5 Un exemplu de clasă Data Environment

DEFINE CLASS client AS cursor

alias = "CLIENT"

cursorsource = "CLIENT"

36

Page 37: Programare

database = HOME()+"TEST.DBC"

ENDDEFINE

DEFINE CLASS comenzi AS cursor

alias = "COMENZI"

cursorsource = "COMENZI"

database = HOME()+"TESTDATA.DBC"

ENDDEFINE

DEFINE CLASS articolcomand AS cursor

alias = "ARTICOLCOMAND"

cursorsource = "ARTICOLCOMAND"

database = HOME()+"tESTDATA.DBC"

ENDDEFINE

DEFINE CLASS Client_La_Comenzi AS relation

childalias = "Comenzi"

parentalias = "Client"

childorder = "cCodCl"

RelationalExpr = "cCodCl"

ENDDEFINE

DEFINE CLASS Comenzi_La_ArticolComand AS

relation

childalias = "ArticolComand"

parentalias = "Comenzi"

childorder = "cCodComanda"

RelationalExpr = "cCodComanda"

ENDDEFINE

37

Page 38: Programare

DEFINE CLASS DE AS DataEnvironment

ADD OBJECT oClient AS Client

ADD OBJECT oComenzi AS Comenzi

ADD OBJECT oArticolComand AS ArticolComand

ADD OBJECT o Client_La_Comenzi AS

Client_La_Comenzi

ADD OBJECT o Comenzi_La_ArticolComand AS

Comenzi_La_ArticolComand

PROCEDURE Init

this.OpenTables()

ENDPROC

PROCEDURE Destroy

this.CloseTables()

ENDPROC

ENDDEFINE

Evenimentul Init apelează metoda OpenTables în aşa fel încât

toate tabelele sunt automat deschise când obiectul este instanţiat şi

metoda CloseTables() este apelată când obiectul este părăsit.

Recuperarea definiţiilor din DBC ar putea fi o problemă, mai

ales dacă în timpul dezvoltării aplicaţiei mai faceţi şi ceva schimbări

în DBC. În acest caz trebuie imediat actualizat şi mediul de date.

Acest aspect se poate realiza relativ simplu cu ajutorul funcţiilor de

tipul ADBObjects, astfel încât să vă generaţi programul automat din

DBC.

Clasa: DUMPDBC38

Page 39: Programare

DumpDbc este o subclasă a clasei Custom.

Proprietăţile subclasei DumpDbc

Proprietăţi Descrierea

PROTECTED aRelations Este o listă de obiecte relaţie din fişierul DBC.

PROTECTED aTables Este o listă de obiecte tabel din fişierul DBC.

PROTECTED aViews Este o listă de obiecte vedere din fişierul DBC.

CDBCName Este numele fişierului DBC care se exportă.

CPRGName Este numele programului PRG care se creează.

PROTECTED cPath Este calea completă unde se află baza de date.

PROTECTED nRelations Este numărul de obiecte relaţie din fişierul

DBC.

PROTECTED nTables Este numărul de obiecte tabel din fişierul DBC.

PROTECTED nViews Este numărul de obiecte vedere din fişierul

DBC.

Evenimente şi Metode 

Metoda Executa Această metodă iniţiază scrierea

programului, fiind singura metodă publică. De fapt ea verifică

dacă s-au completat proprietăţile cDBCName şi cPRGName,

în caz contrar apare o casetă de dialog de tipul Getfile() sau

Putfile().

Metoda clasecursor  Această metodă PROTECTED merge

prin toate tabele şi vederile bazei de date şi generează clasele

cursor pentru ele, apelând metoda WriteCursorClass.

39

Page 40: Programare

Metoda citestedbc  Această metodă PROTECTED citeşte

definiţiile relaţiilor, tabelelor şi vederilor DBC utilizând

ADBObjects şi le plasează în aRelations, aTables şi aViews ca

membrii ai unui tabel.

Metoda claserelatie  Această metodă PROTECTED

generează toate clasele relaţie pentru fişierul DBC şi le scrie

în fişierul program de ieşire.

Metoda scrieclase()  Această metodă PROTECTED lansează

procesul de scriere al tuturor claselor. Este apelată de metoda

Executa după ce metoda CitesteDbc îşi termină treaba.

Metoda Scrieclase apelează metodele ClaseCursor şi

ClaseRelatie pentru a scrie clasele individuale în fişierul de

ieşire. Un ultim lucru pe care îl face această metodă este să

apeleze metoda ScrieClaseImplicite, care scrie o clasă mediu

de date implicit care are toţi cursorii şi relaţiile în ea.

Metoda scrieclasecursor (tcClassName)  Metoda

PROTECTED scrie o singură clasă cursor în program, având

acelaşi nume cu cel al vederii sau cursorului.

Metoda scrieclaseimplicite  PROTECTED scrie o clasă

mediu de date implicit numit Default_de, care are toate clasele

cursor şi relaţii din fişierul DBC.

Prog. 6  Cod pentru crearea clasei DumpDBC şi crează şi un

program de ieşire

*-- Class: dumpdbc

*-- ParentClass: custom

*-- BaseClass: custom

40

Page 41: Programare

*-- Crează clase CURSOR şi clase RELATION pentru

un .DBC.

DEFINE CLASS dumpdbc AS custom

*-- Numărul de obiecte relaţie din .DBC

PROTECTED nrelations

nrelations = 0

*-- Numărul de obiecte tabel din .DBC

PROTECTED ntables

ntables = 0

*-- Numărul de obiecte vedere din .DBC

PROTECTED nviews

nviews = 0

*-- Numele .DBC

cdbcname = ""

*-- Numele fişierului program care va fi creat

cprgname = ""

Name = "dumpdbc"

*-- Calea unde se află baza de date

PROTECTED cpath

*-- Lista obiectelor relaţie din .DBC

PROTECTED arelations[1]

*-- Lista obiectelor vedere din .DBC

PROTECTED aviews[1]

*-- Lista obiectelor tabel din .DBC

PROTECTED atables[1]

PROTECTED init

*-- Citeşte .DBC-ul într-un array (tablou) .

PROTECTED PROCEDURE citestedbc

41

Page 42: Programare

IF !dbused(this.cDbcName)

OPEN DATABASE (this.cDbcName)

ENDIF

*-- Citeşte .DBC

this.nTables = aDBObjects(this.aTables,

"Table")

this.nViews = aDBObjects(this.aViews,

"View")

this.nRelations = aDBObjects(this.aRelations,

"Relation")

ENDPROC

*-- Scrie toate clasele.

PROTECTED PROCEDURE scrieclase

SET TEXTMERGE TO (this.cPRGNAME)

NOSHOW

IF this.nTables > 0 OR this.nViews > 0

this.ClaseCursor()

ENDIF

IF this.nRelations > 0

this.ClaseRelatie()

ENDIF

this.ScrieClaseImplicite()

SET TEXTMERGE OFF

SET TEXTMERGE TO

ENDPROC

*-- Procesează toate clasele cursor în .DBC.

PROTECTED PROCEDURE ClaseCursor

LOCAL lnCounter

42

Page 43: Programare

SET TEXTMERGE ON

FOR lnCounter = 1 TO this.nTables

this.ScrieClaseCursor(this.aTables[lnCounter])

ENDFOR

FOR lnCounter = 1 TO this.nViews

this.ScrieClaseCursor(this.aViews[lnCounter])

ENDFOR

SET TEXTMERGE OFF

ENDPROC

*-- Scrie o clasă cursor în fişierul program de ieşire.

PROTECTED PROCEDURE scrieclasecursor

LPARAMETERS tcClassName

\DEFINE CLASS <<STRTRAN(tcClassName, chr(32),

"_")>> AS cursor

\ alias = "<<tcClassName>>"

\ cursorsource = "<<tcClassName>>"

\ database = DATABASEPATH +

"<<this.cDbcName>>"

\ENDDEFINE

\

ENDPROC

*-- Procesează şi scrie toate clasele relaţie.

PROTECTED PROCEDURE claserelatie

LOCAL lnCounter, ;

lcClassName, ;

lcChildAlias, ;

lcParentAlias, ;

lcChildOrder, ;

43

Page 44: Programare

lcRelationalExpr

SET TEXTMERGE ON

FOR lnCounter = 1 TO this.nRelations

lcClassName = "RELATION"-

Alltrim(Str(lnCounter))

lcChildAlias = this.aRelations[lnCounter,1]

lcParentAlias = this.aRelations[lnCounter,2]

lcChildOrder = this.aRelations[lnCounter,3]

lcRelationalExpr = this.aRelations[lnCounter,4]

\DEFINE CLASS <<lcClassName>> AS

relation

\ childalias = "<<lcChildAlias>>"

\ parentalias = "<<lcParentAlias>>"

\ childorder = "<<lcChildOrder>>"

\ RelationalExpr = "<<lcRelationalExpr>>"

\ENDDEFINE

\

ENDFOR

SET TEXTMERGE OFF

ENDPROC

*-- Scrie clasa mediului de date implicit (Data

Environment) în program

PROTECTED PROCEDURE scrieclaseimplicite

LOCAL laClasses[this.nTables + this.nViews +

this.nRelations]

44

Page 45: Programare

FOR lnCounter = 1 TO this.nTables

laClasses[lnCounter] = this.aTables[lnCounter]

ENDFOR

FOR lnCounter = 1 TO this.nViews

laClasses[lnCounter+this.nTables] =

this.aViews[lnCounter]

ENDFOR

FOR lnCounter = 1 TO this.nRelations

laClasses[lnCounter+this.nTables+this.nViews]

= ;

"Relation" + ALLTRIM(STR(lnCounter))

ENDFOR

SET TEXTMERGE ON

\DEFINE CLASS de_implicit AS

DataEnvironment

FOR lnCounter = 1 TO ALEN(laClasses,1)

lcObjectName = 'o'+laClasses[lnCounter]

lcClassName = laClasses[lnCounter]

\ ADD OBJECT <<lcObjectName>> AS

<<lcClassName>>

ENDFOR

\ENDDEFINE

\

SET TEXTMERGE OFF

45

Page 46: Programare

ENDPROC

PROCEDURE executa

*-- Dacă nici un nume dbc nu este specificat, întreabă de

unul.

IF EMPTY(this.cDBCName)

this.cDBCName = GETFILE("DBC", "Selectati

va rugam DBC pentru clasa dump:")

IF !FILE(this.cDBCName)

=MESSAGEBOX("Nu este selectat nici un DBC!

Anulam!",16)

RETURN .F.

ENDIF

ENDIF

*-- Acelaşi lucru şi cu .PRG

IF EMPTY(this.cPRGName)

this.cPRGName = PUTFILE("PRG pentru a fi

creat:","","PRG")

IF EMPTY(this.cPRGName)

=Messagebox("Operatie anulata!", 16)

RETURN

ENDIF

ENDIF

IF SET("safety") = "ON" AND ;

FILE(this.cPRGName) AND ;

MessageBox("Rescriere existenta " + ;

ALLTRIM(this.cPRGName) + "?", 36)

# 6

=Messagebox("Operatie anulata!", 16)

46

Page 47: Programare

RETURN

ENDIF

*-- salvează configurările SAFETY

LOCAL lcOldSafety

lcOldSafety = SET("safety")

SET SAFETY OFF

this.citestedbc()

this.scrieclases()

SET SAFETY &lcOldSafety

ENDPROC

ENDDEFINE

Prog. 7  Program care ilustrează utilizarea clasei Dumpdbc

Set ClassLib to Chap17

Set ClassLib to FoxTool ADDITIVE

oDbcGen = CREATEOBJECT("dumpdbc")

oDbcGen.cDBCName = "testdata"

oDbcGen.cPRGName = "deleteme.prg"

oDbcGen.xecuta()

Prog. 8  Programul de ieşire DELETEME.PRG

* Program...........: deleteme.prg

* DBC...............: TESTDATA.DBC

47

Page 48: Programare

* Generated.........: August 28, 1998 - 10:16:23

#DEFINE databasepath HOME()+"\TEST\"

DEFINE CLASS CLIENT AS cursor

alias = "CLIENT"

cursorsource = "CLIENT"

database = DATABASEPATH +

"TESTDATA.DBC"

ENDDEFINE

DEFINE CLASS PRODUSE AS cursor

alias = "PRODUSE"

cursorsource = "PRODUSE"

database = DATABASEPATH +

"TESTDATA.DBC"

ENDDEFINE

DEFINE CLASS ARTICOLCOMAND AS cursor

alias = "ARTICOLCOMAND"

cursorsource = "ARTICOLCOMAND"

database = DATABASEPATH +

"TESTDATA.DBC"

ENDDEFINE

DEFINE CLASS COMENZI AS cursor

alias = "COMENZI"

cursorsource = "COMENZI"

database = DATABASEPATH +

"TESTDATA.DBC"

ENDDEFINE

48

Page 49: Programare

DEFINE CLASS ANGAJATI AS cursor

alias = "ANGAJATI"

cursorsource = "ANGAJATI"

database = DATABASEPATH +

"TESTDATA.DBC"

ENDDEFINE

DEFINE CLASS RELATIE1 AS relation

childalias = "COMENZI"

parentalias = "CLIENTI"

childorder = "CODCL"

RelationalExpr = "CODCL"

ENDDEFINE

DEFINE CLASS RELATIE2 AS relation

childalias = "COMENZI"

parentalias = "ANGAJATI"

childorder = "CODANG"

RelationalExpr = "CODANG"

ENDDEFINE

DEFINE CLASS RELATIE3 AS relation

childalias = "ARTICOLCOMAND"

parentalias = "COMENZI"

childorder = "CODCOMANDA"

RelationalExpr = "CODCOMANDA"

ENDDEFINE

DEFINE CLASS RELATIE4 AS relation

49

Page 50: Programare

childalias = "ARTICOLCOMAND"

parentalias = "PRODUSE"

childorder = "CODPRODUS"

RelationalExpr = "CODPRODUS"

ENDDEFINE

DEFINE CLASS de_implicit AS DataEnvironment

ADD OBJECT oClient AS Client

ADD OBJECT oProduse AS Produse

ADD OBJECT oArticolcomand AS Articolcomand

ADD OBJECT oComenzi AS Comenzi

ADD OBJECT oAngajati AS Angajati

ADD OBJECT oRelatie1 AS Relatie1

ADD OBJECT oRelatie2 AS Relatie2

ADD OBJECT oRelatie3 AS Relatie3

ADD OBJECT oRelatie4 AS Relatie4

ENDDEFINE

Mai este necesar să apelaţi metoda OpenTables() pentru a avea

tabelele deschise şi deasemenea să apelaţi metoda CloseTables()

pentru a închide tabelele.

DEFINE CLASS DE2 AS DataEnvironment

PROCEDURE Init

this.OpenTables()

ENDPROC

PROCEDURE Destroy

this.CloseTables()

ENDPROC50

Page 51: Programare

ENDDEFINE

Creşterea puterii mediului de date cu ajutorul sesiunilor de

date (DataSessions)

Puteţi să realizaţi aplicaţii mult mai flexibile, lucrând cu mai

multe sesiuni de date. Acest lucru se întâmplă pentru a nu mai

deschide toate fişierelor la început, ci numai funcţie de sesiunea de

date corespunzătoare. De asemena, numai formularele pot crea sesiuni

de date independente.

Clasa care este creată ulterior nu se va putea adăuga la un

formular cu ajutorul lui ADD OBJECT sau AddObject(), ci va trebui

să fie instanţiat un obiect de acest tip cu ajutorul lui CreateObject().

Prog. 9  Codul pentru clasa Sesiunededatenoua

*-- Class: Sesiunededatenoua

*-- ParentClass: form

*-- BaseClass: form

DEFINE CLASS sesiunededatenoua AS form

DataSession = 2

Top = 0

Left = 0

Height = 35

Width = 162

DoCreate = .T.

Caption = "Form"

Visible = .F.

Name = "sesiunededatenoua"

PROTECTED show

PROTECTED visible

ENDDEFINE

51

Page 52: Programare

Clasa de mai sus a creat un formular care nu va pute a fi afişat,

deoarece proprietatea Visible a fost configurată pe .F. şi metoda

SHOW a fost protejată de asemenea.

Clasele nonvizuale sunt clasele care nu sunt proiectate în

primul rând pentru a fi afişate în vreun fel. De exemplu

CommandButton este o clasă creată pentru a fi afişată într-un

formular.

Clasele nonvizuale în Visual FoxPro sunt tipic descendente ale

claselor Custom şi deseori nu conţin componente care să poată fi

afişate. Cu toate acestea o clasă nonvizuală poate avea componente

vizuale ataşate la ea. De asemenea, clasele vizuale pot fi baza pentru

clasele nonvizuale.

52