Newsgroup: it.comp.lang.delphi
Titolo: Creazione runtime di oggetti

Salve.
Sono alle prese con la programmazione ad oggetti, nuova per

Sono alle prese con la programmazione ad oggetti, nuova per
...Siiii ???
:D
-- 
Morde. 
(
mo...@despammed.com
)
M-List di icld: 
http://it.groups.yahoo.com/group/icld/

 :D
Deve essere caduta la linea; ad ogni modo, considerando l'oggetto della 
discussione e ipotizzando il contesto della domanda (stroncata per 
"digito interruptus"), suggerisco all'autore originario del thread di 
fare una ricerca con Google:
http://makeashorterlink.com/?S54744D7A
Se nelle discussioni riportate non è possibile trovare la soluzione al 
problema, allora è il caso di scrivere il resto della domanda. ;-)
-- 
Marco «Alka» Breveglieri
  (marco [@] abls [.] it)
  ABLS Team S.n.c. - Software & Web
  42019 Scandiano (Reggio Emilia)
 
http://www.abls.it

Ops!! Scusate mi si era incasinato qualcosa.
Dicevo:
Sono alle prese con la programmazione ad oggetti, al quanto nuova per me,
almeno fatta in questo modo poichè ancora studente (Sino ad ora abbiamo
preso componenti anche DB e li abbiamo messi sui vari form ed è stato bello,
ma soprattutto semplice).
Ma ora ho un progettino da realizzare in Delphi che dovrebbe fare alcune,
penso (...spero) semplici, operazioni:(...la cosa mi puzza un po')
«Si vuole automatizzare la gestione di entrata ed uscita dei testi della
bibblioteca scolastica, quindi data una base di dati di cui sono già note le
strutture, sviluppare un'applicazione che realizzi le interfacce utente
utili all'inserimento, modifica e cancellazione delle schede:
- degli studenti che prelevano i testi,
- dei testi prelevati e quindi ancora in loro possesso.»
il database è firebird ed ha due tabelle (Studenti, Libri) ed aggiungo che
il tutto deve essere realizzato creando da zero le classi/oggetti.
Bene,
ho creato un form contenente una stringgrid e qualche bottone che in seguito
farà le operazioni richieste (Select, insert ecc.). Alla creazione del form
creo un oggetto di tipo TDBManager, una mia classe che dovrebbe collegarsi
al database attraverso gli oggetti utili alla connessione. Dico dovrebbe
perchè già quì sorgono i primi intoppi:
Nella classe TDBManager = TObject ho inserito un Create nel quale creo il
TIBDatabase e tutto il resto assegnando le varie proprietà, ma Delphi dice
che ha bisogno di un owner per l'oggetto TIBDatabase... Cioè? Però se gli
oggetti li metto su di un form, nessuno si lamenta.
Che faccio?
Spero di non aver scritto cavolate. Se volete posso postare il codice, anche
se in verità contiene veramente ancora molto molto poco.
Ciao.

 Che faccio?
Passa *nil* come "owner" nella chiamata al metodo /Create/, ma ricordati 
di gestire la distruzione di tale componente all'interno del metodo 
/Destroy/ implementato nella tua classe TDBManager; la distruzione e il 
rilascio della memoria allocata avviene chiamando il metodo /Free/ del 
componente.
Nessuno si lamenta quando appoggi componenti sul form a designtime 
poichè è il Form Designer che si occupa di specificare il valido 
"owner", che viene ripristinato al caricamento del form in base al 
contenuto del file DFM.
Ciao! :-)


 ha scritto nel messaggio 
news:37gm8eF...@individual.net...


Ringrazio già per l'attenzione che mi è stata concessa e approfitto...
scusandomi per la lunghezza del messaggio.
Riporto il codice prodotto, eliminando cosette al momento superflue per non
allungarmi troppo.
Ho fatto in questo modo usando i componenti Zeos:
unit ClassiUnit;
interface
uses
  Classes, Contnrs, SysUtils,
  DB, ZAbstractRODataset, ZAbstractDataset, ZDataset, ZConnection
type
//Mi serve per poterla utilizzare nella dichiarazione dei
//parametri delle funzioni/procedure
  TLibro = Class;
  // Il TDBManager sostituirebbe, grosso modo, il ModuloDati
  // poichè fornirebbe gli oggetti di connessione al DB fisico
  TDBManager = class (TObject)
  Private
    Function Load(Id: String): Boolean; virtual; abstract;
    procedure Update(Libro : TLibro); virtual; abstract;
    procedure Insert(Libro : TLibro); virtual; abstract;
    procedure Delete(Libro : TLibro); virtual; abstract;
  public
    ConnessioneDB : TZConnection;
    Tabella       : TZQuery;
    constructor Create;
    destructor Destroy; override;
  end;
//Dichiarazione effettiva della classe
  TLibro = class (TObject)
  private
  Public
    Id: String;
    Titolo: String;
    Genere: String;
    CasaEditrice: TDate;
  End;
// classe che deve gestire le operazioni di lettura,
// scrittura e visualizzazione dei dati dei Libri
  TGestoreLibri = class (TDBManager)
    ElencoLibri : TObjectList;
  Private
    Function Load(Id: String): Boolean; override;
  Public
    function VisualizzaElenco(Criterio: String): Integer;
    //Procedure Elimina(Id: String);
  end;
implementation
                  // **********************
                  // ***** TDBManager *****
                  // **********************
constructor TDBManager.Create;
Begin
  Inherited Create;
  ConnessioneDB := TZConnection.Create(Nil);
  // ...un po' d'impostazioni;
  Tabella := TZQuery.Create(nil);
  Tabella.Connection := ConnessioneDB;
end;
destructor TDBManager.Destroy;
Begin
  FreeAndNil(Tabella);
  FreeAndNil(ConnessioneDB);
  inherited Destroy;
end;
//[...] continuerebbe con altre cose
End.
Nell'Interface del form che visualizza l'elenco ho scritto:
var
  FormElencoLibri: TFormElencoLibri;
  GestoreLibri : TGestoreLibri;
Nell'OnCreate del form che visualizza l'elenco ho scritto:
procedure TFormElencoLibri.FormCreate(Sender: TObject);
begin
  GestoreLibri.Create;
  ElencoGrid.Cells[0,0] := 'Titolo';
  ElencoGrid.Cells[1,0] := 'Id';
end;
Ok fin quì?
Dunque, ho inserito un breakpoint nel FormCreate ed all'avvio del programma,
quando si chiama GestoreLibri.Create mi dà un errore di memoria. Ho fatto un
po' di prove senza risultato, tranne se inserisco una variabile Pippo:
TZConnection interna al TDBManager.Create, la creazione da quella variabile
funziona, diversamente no.
...mi sa, a questo punto, di non aver capito "qualcosa"!
Ciao.

 memoria. Ho fatto un
La sintassi corretta per creare l'istanza di un oggetto di classe
TDbManager è:
GestoreLibri := TDbManager.Create(nil);
Se usi invece GestoreLibri.Create avrai una violazione di accesso in
quanto stai cercando chiamare il costruttore di un oggetto che ancora
non esiste.
guastatore

 non esiste.
I can't believe!!! Non ci posso credere!!!
Mi son fatto fregare così facilmente?
Vabè, va.
Grazie per la sbirciata, per il resto sto andando per la via giusta?
Ciao.

> Grazie per la sbirciata, per il resto sto andando per la via giusta?
Il discorso è un pò più complesso di quello che sembra dato che stai
"sconfinando" negli OPF (Object Persistent Framework) o in qualcosa di
molto simile. Personalmente erediterei tutti gli oggetti da un antenato
comune che non sia TObject ma un'altra classe specializzata che
possiede i metodi Load e Save in grado di caricare e salvare le
proprietà del singolo oggetto sul db. Il TDbManager lo lascerei per
gestire il db (nulla vieta che discendenti possano lavorare su strati
di db differenti) ma ripeto il discorso si complica un pò. Prova a dare
un'occhiata a questi articoli interessanti:
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=15511
http://www.atug.com/andypatterns/RM.htm
Se hai difficoltà con il primo link manda alla mia email un indirizzo
di posta valido, te li spedisco io.
guastatore

 di posta valido, te li spedisco io.
E' andato tutto benone. Thanks.
Ciao.

Rimanendo sempre in tema:
Ma per visualizzare un form devo solo necessariamente invocare uno
ShowModal?
Perchè non mi consente un semplice Show e poter quindi passare in esecuzione
da un form all'altro?
Grazie.

Francesco Poli wrote:

Puoi usare anche il metodo Show per visualizzare i form. Quale problema
stai incontrando ?
Se stai creando le form a runtime allora devi prestare attenzione al
metodo Show ed eventualmente distruggere le istanze delle form quando
non più necessarie.
guastatore

 E' andato tutto benone. Thanks.
Perfetto ! :-) Se vuoi approfondire il discorso degli OPF posso
segnalarti altri link che sono interessanti per ampliare il proprio
orizzonte informatico ;-)
www.techinsite.com.au
 Qui puoi stampare la guida dell'OPF che anche se
un pò datata, illustra alcuni pattern e metodi interessanti per la
persistenza degli oggetti.
http://www.carterconsulting.org.uk/
http://www.ambysoft.com/persistenceLayer.html
http://www.ambysoft.com/
Ciao
guastatore

 non più necessarie.
Il problema è che ho creato un form di visualizzazione all'interno di una
procedura Show, ma praticamente non riesco a vederla.
Procedure TAlunno.Show;
Var
  Scheda : TFormScheda;
Begin
  Try
    Scheda := TFormScheda.Create(Nil);
    AssociaValori;
    Show; // se metto showmodal il form si vede
  Finally
    FreeAndNil(Scheda);
  End;
End;
Ho provato a mettere la variabile Scheda nella sezione Interface, così come
fa il delphi quando si creano programmi in maniera "visuale", ho provato
anche con Application.CreateForm(TFormScheda, FormScheda), sempre lo stesso
risultato! Sembra come se esegua il comando Show e poi passa subito al
FreeAndNil, invece con lo showmodal no.
Dottore ...è grave?

 Da Cronache della Galassia (Foundation) di Isaac ASIMOV 
Ho capito, dobbiamo ricominciare con le 5 12 :-))))))))))
Antonio

Ho capito, dobbiamo ricominciare con le 5 12 :-))))))))))
ahahah mi sa che hai troppo ragione, ho perso piu' di 100 punti solo questo
week end con le 3 0.. sigh stavo proprio bene con un ELO di 1239!!!
Scusate ng per l'OT... :)


 Bhe più che guastatore... "Aggiustatore" ;P
Ti ringrazio, in effetti questo nick lascia perplessi :-)
guastatore

manca in classe. ;)
".. e il mito di guastatore tutor, incomincio' a prender forma su usenet"
Da Cronache della Galassia (Foundation) di Isaac ASIMOV 
:-D


    FreeAndNil(Scheda);
      ^^^^^^^^^^^^^^^^^^^^
La freeandnil viene invocata l'istruzione successiva la show, ovviamente cosi'
facendo il form viene creato, mostrato e distrutto in qualche decimo di
secondo!
Uno show per rendere la maschera attiva e non bloccare l'utente su quella e
solo quella maschera del programma, deve essere innescato in maniera
asincrona, magari ad esempio sulla pressione di un bottone:
procedure TfrmPippo.abbonamenti1Click(Sender: TObject);
begin
   if not Assigned(TFormScheda) then
      FormScheda := TFormScheda.Create(Application);
   AssociaValori;
   FormScheda.Show;
end;
Ovviamente la form dovrai distruggerla quando uscirai dal programma o dalla
maschera da cui dipende FormScheda.
Ti suggerirei di creare il form all'inizio del programma , e distruggerlo
all'uscita dello stesso. Quando non ti serve piu' la maschera, nascondila col
metodo hide.
Spero di averti aiutato e non confuso!
Ciao!


 guastatore
Bhe più che guastatore... "Aggiustatore" ;P
Ciao e... grazie ancora!!!

 Dottore ...è grave?
Non molto :-)) Dica 33 ;)
Il problema è che la form viene creata e visualizzata ma poiché la
chiamata al metodo Show è asincrona l'esecuzione del resto delle
istruzioni procede e quindi viene subito distrutta dal try..finally.
Per questo motivo, non puoi usare quel costrutto ma dare un'occhiata
all'evento OnCloseQuery che consente di impostare il parametro Action
di tipo TCloseAction (dai uno sguardo all'help per capire cosa fare).
guastatore

"Visual-qualcosa".
Visual, visual... gia': questo fa parte della storia dell'informatica e quando
incontro giovani programmatori come te, di una generazione dopo la mia (io da
bambino giocavo con goldrake e andavo dai miei amici e giocare con lo spectrum
48k sinclair) mi si disegna sempre un bel sorriso sul viso.
Il concetto di visual e' nato dal fatto che si e' sempre cercato, con
l'evolversi delle tecnologie, di rendere la programmazione un procedimento
sempre piu' facile e veloce. 
Come ben sai, in se' un programma non e' che un flusso di istruzioni: una
volta un programmatore scriveva in un editor queste istruzioni, e non aveva
nessun supporto visivo di come fossero poi le maschere col quale l'utente
interagiva (in realta' non c'erano neanche le maschere, ma qui siamo troppo
indietro con gli anni). Poi, col tempo, si svilupparono delle interfacce
visuali per aiutare il programmatore a capire cosa vedeva l'utente e come
farlo interagire con la maschera, queste interfacce vennero chiamate IDE.
Il concetto di Visual divenne poi fondamentale: si capi' che un programmatore
avrebbe diminuito il tempo di programmazione e aumentato la produzione, se
assistito da queste interfacce dette appunto IDE, e da quei tempi l'uso di
"Visual" poi divenne fico, e allora tutti usarono questo termine per
promuovere le proprie tecnologie e i propri prodotti: nacquero il visual
modeling, il visual marketing, il visual designing, ecc... insomma Visual fu
la parola chiave dell'evoluzione della programmazione.
Ti sembrera' semi seria la mia descrizione del concetto, ma tant'e' che sono
appena rientrato dalla pausa brandy di meta' mattina, e.. hic! forse vedo le
cose un tantino,, hic! distorte..!



Si, ci crediamo proprio!
Tu da bambino passi le ore a giocare al dottore e all'infermiera,
altro che Goldrake e Jeeg!
;-)
Ciao.
--
ACSH
[D4]
---------------------------
Chi fa da se'
fatica il doppio

;-)
eh.... beh lo ammetto, ho fatto anche quello #-)
;)
