Lucrarea 5

Elemente de programare orienta pe obiecte în Visual dBase.

1. Concepte de programare orientata pe obiecte în Visual dBase

2. Clase standard

Clasele pentru crearea interfetei sunt: CLASS BROWSE, CLASS CHECKBOX, CLASS COMBOBOX, CLASS DDELINK, CLASS DDETOPIC, CLASS EDITOR, CLASS ENTRYFIELD, CLASS FORM, CLASS IMAGE, CLASS LINE, CLASS LISTBOX, CLASS MENUBAR, CLASS MENU, CLASS OLEAUTOCLIENT, CLASS OLE, CLASS PAINTBOX, CLASS POPUP, CLASS PUSHBUTTON, CLASS RADIOBUTTON, CLASS RECTANGLE, CLASS SCROLLBAR, CLASS SHAPE, CLASS SPINBOX, CLASS TABBOX, CLASS TEXT.

Clasele de uz general sunt: CLASS ARRAY, CLASS ASSOCARRAY, CLASS OBJECT.

Exemplu:
*** Fisierul L51.PRG ***
*** Afiseaza ordonat toate numele din stud.dbf care incep cu o litera specificata

SET TALK OFF
USE stud
aPers = NEW ARRAY(1)
DO
  WAIT 'Litera de afisat:' TO cL
UNTIL ISALPHA(cL)
cL=UPPER(cL)
GO TOP
i=1
DO WHILE .NOT. EOF()
  IF UPPER(LEFT(LTRIM(nume),1))=cL
    aPers[i]=nume
    aPers.Add(1)
    i=i+1
  ENDIF
  SKIP
ENDDO
nNrP = i-1
USE
IF nNrP = 0
  ? 'Nu exista nume care incep cu '+cL
ELSE
  aPers.Resize(nNrP)
  aPers.Sort()
  ? 'Numele care incep cu litera '+cL
  FOR i=1 TO nNrP
    ? aPers[i]
  NEXT
ENDIF
RELEASE aPers
WAIT 'Terminat'
RETURN

Exemplu:
*** Fisierul L52.PRG defineste si apeleaza un formular de afisare studenti
**************************************************************************

SET TALK OFF
fFormStud = new FORM()

fFormStud.View = "stud.dbf"
fFormStud.Text = "Formular studenti"
fFormStud.Left = 59
fFormStud.Height = 17
fFormStud.Width = 50
fFormStud.Top = 10

DEFINE PUSHBUTTON buOK OF fFormStud;
  PROPERTY;
  Text "OK",;
  OnClick {;FORM.Close() },;
  Left 4, Height 5, Width 12, Top 10
DEFINE TEXT etiCods OF fFormStud;
  PROPERTY;
  Text "&Cods",;
  Left 1, Height 1, Width 15, Top 3
DEFINE ENTRYFIELD campCods OF fFormStud;
  PROPERTY;
  DataLink "STUD->CODS",;
  Left 17, Height 1, Width 8, Top 3
DEFINE TEXT etiNume OF fFormStud;
  PROPERTY;
  Text "&Nume",;
  Left 1, Height 1, Width 15, Top 4
DEFINE ENTRYFIELD campNume OF fFormStud;
  PROPERTY;
  DataLink "STUD->NUME",;
  Left 17, Height 1, Width 29, Top 4
DEFINE TEXT etiBursa OF fFormStud;
  PROPERTY;
  Text "&Bursa",;
  Left 1, Height 1, Width 15, Top 5
DEFINE SPINBOX campBursa OF fFormStud;
  PROPERTY;
  DataLink "STUD->BURSA",;
  Left 17, Height 1, Width 14, Top 5
DEFINE LISTBOX listaCampuri OF fFormStud;
  PROPERTY;
  DataSource "STRUCTURE",;
  Left 22, Height 7, Width 24, Top 8

*** se deschide nemodal formularul
fFormStud.OPEN()
RETURN

 3. Clase utilizator

Sintaxa de definire a unei clase este urmatoarea:

CLASS nume_clasa [(lista_parametrii)]
  [OF nume_superclasa [(lista_parametrii)] [FROM nume_fisier] ]
  [PROTECT lista_proprietati_protejate]
  * Corp constructor
  * Definitii de metode
ENDCLASS

Exemplu:
*** Fisierul L53.PRG - exemplu de definire si utilizare clasa utilizator
************************************************************************

SET TALK OFF
an1 = NEW Student('stud.dbf')
an1.Tipareste()
ACCEPT 'nume' TO cNume
nBursa = an1.CautaBursaDupaNume(cNume)
IF nBursa<>-1
  ? cNume+' are bursa '+str(nBursa)
ELSE
  ? cNume+' nu exista'
ENDIF
an1.Inchide()
RETURN

*** Definirea clasa Student pentru gestionarea studentilor
CLASS Student(fisier_date)
*** constructor
this.fis = fisier_date
aux=this.fis && este necesara pentru a putea face substituirea
USE &aux IN 1 ALIAS stud
this.deschis = .T.
this.rec = 1
this.eof = EOF() .OR. BOF()
this.nume = ""
this.cods = ""
this.bursa = ""
this.Citeste()

*** metode ale clasei student
PROCEDURE Inchide
USE IN 1
this.deschis = .F.
this.rec = 0
this.eof = .T.
this.nume = ""
this.cods = ""
this.bursa = ""
RETURN

PROCEDURE Citeste
GO this.rec
this.eof = EOF() .OR. BOF()
IF .NOT. this.eof
this.nume=nume
this.cods=cods
this.bursa=bursa
ELSE
this.nume = ""
this.cods = ""
this.bursa = ""
MsgBox('Afara din tabela')
ENDIF
RETURN

PROCEDURE Urmator
SKIP
IF .NOT. EOF()
this.rec = this.rec + 1
ENDIF
this.Citeste()
RETURN

PROCEDURE Tipareste
LIST cods, nume, bursa
this.Citeste()
RETURN

FUNCTION CautaBursaDupaNume(numeCautat)
GO TOP
SET EXACT ON
DO WHILE .NOT. EOF()
IF numeCautat = nume
aux=bursa
this.Citeste()
RETURN aux
ENDIF
SKIP
ENDDO
this.Citeste()
RETURN -1
ENDCLASS
***************************

Exemplu:
*** Fisierul Navigare.prg contine o biblioteca de clase pentru butoane de navigare
**********************************************************************************
* Clasa buton generic derivata din clasa standard PUSHBUTTON. Rezolva
* pozitionarea în pagina. Celelalte clase o vor mosteni pe aceasta.

CLASS Buton(f,x,y) OF PUSHBUTTON(f)
this.left = x
this.top = y
ENDCLASS

* Clasa pentru buton de OK care închide formularul
CLASS ButonOK(f,x,y) OF Buton(f,x,y)
this.text = "OK"
this.OnClick = {;FORM.Close() }
ENDCLASS

* Clasa pentru buton de salt pe prima înregistrare
CLASS ButonTOP(f,x,y) OF Buton(f,x,y)
this.text = "Inceput"
this.OnClick = {;GO TOP }
ENDCLASS

* Clasa pentru buton de salt pe ultima înregistrare
CLASS ButonBOTTOM(f,x,y) OF Buton(f,x,y)
this.text = "Sfarsit"
this.OnClick = {;GO BOTTOM }
ENDCLASS

* Clasa pentru buton de salt pe urmatoarea înregistrare
CLASS ButonNEXT(f,x,y) OF Buton(f,x,y)
this.text = "Inainte"
this.OnClick = CLASS::MoveNext
PROCEDURE MoveNext
SKIP
IF EOF()
  MsgBox('Nu mai sunt inregistrari')
SKIP -1
ENDIF
RETURN
ENDCLASS

* Clasa pentru buton de salt pe precedenta înregistrare
CLASS ButonPREV(f,x,y) OF Buton(f,x,y)
this.text = "Inapoi"
this.OnClick = CLASS::MovePrev
PROCEDURE MovePrev
SKIP -1
IF BOF()
  MsgBox('Nu mai sunt inregistrari')
ENDIF
RETURN
ENDCLASS

**********************************************************************
*** Fisierul L54.PRG exemplifica utilizarea claselor definite anterior
**********************************************************************
SET TALK OFF
SET PROCEDURE TO 'navigare.prg' ADDITIVE

formStud = new FORM()

formStud.View = "stud.dbf"
formStud.Text = "Formular studenti"
formStud.Left = 59
formStud.Height = 17
formStud.Width = 50
formStud.Top = 10
formStud.buOk = NEW ButonOK(formStud,16,12)
formStud.buTop = NEW ButonTOP(formStud,6,8)
formStud.buPrev = NEW ButonPREV(formStud,6,10)
formStud.buNext = NEW ButonNEXT(formStud,24,10)
formStud.buBottom = NEW ButonBOTTOM(formStud,24,8)

DEFINE TEXT etiCods OF formStud;
  PROPERTY;
  Text "&Cods",;
  Left 1, Height 1, Width 15, Top 3
DEFINE ENTRYFIELD campCods OF formStud;
  PROPERTY;
  DataLink "STUD->CODS",;
  Left 17, Height 1, Width 8, Top 3
DEFINE TEXT etiNume OF formStud;
  PROPERTY;
  Text "&Nume",;
  Left 1, Height 1, Width 15, Top 4
DEFINE ENTRYFIELD campNume OF formStud;
  PROPERTY;
  DataLink "STUD->NUME",;
  Left 17, Height 1, Width 29, Top 4

formStud.Open()
RETURN
*********************************

4. Probleme propuse
P1. Rulati exemplele prezentate în acest capitol.

P2. Adaugati la biblioteca din fisierul Navigare.prg un buton care face cautarea dupa nume a unor persoane. Se presupune ca exista o tabela deschisa care are un câmp nume. Butonul va deschide o fereastra de dialog in genul ferestrelor MsgBox (sunt prezentate în HELP) cu butoane de OK si CANCEL la care se va adauga un camp de editare în care va citi numele care se doreste a fi cautat. Daca s-a apasat pe butonul OK se va face cautarea si se va pozitiona înregistrarea curenta pe elementul gasit. Daca nu este gasita nici o persoana cu nume respectiv se va da un mesaj corespunzator si se va reveni pe înregistrarea de dinaintea cautarii (care a fost salvata la înainte de a se începe cautarea).

P3. Modificati exemplul anterior astfel încât sa depuna într-un tablou toate persoanele ale caror nume încep cu cuvântul de cautare. Tabloul va fi afisat cu ajutorul unui element de tip LISTBOX într-un formular separat deschis dupa efectuarea cautarii. Acesta va contine doar lista si un buton de OK.


s.l. dr. ing. Dan Pescaru '2004