Newsgroup: it.comp.lang.delphi
Titolo: Due Oggetti derivati da TForm vengono visualizzati uguali???

Sto sbagliando qualcosa che non mi riesce di comprendere e chiedo lumi a 
voi:
 
Tutte le Form di una applicazione (MDIChild) le tengo da creare alla 
bisogna e non sono in autocreate.
 
Fin'ora ho sempre inibito la possibilità di creare due (o più) volte la 
stessa form disabilitando il menù con il quale la richiamo e non mi sono 
mai accorto del problema che mi si è presentato questa volta.
 
In questa applicazione, invece, mi servirebbe visualizzare più volte la 
stessa form per visualizzare uno o più estratti conto da mostrare 
contemporaneamente per delle possibili comparative a video. Naturalmente 
intendo visualizzare in una form l'estratto conto di un cliente mentre 
nell'altra quello di un fornitore o un conto di costo o ricavo.
 
La form fa riferimento, nella sezione "Private", ad un datamodule dove 
sono presenti i Datasource e le query che estraggono i dati.
 
Creo la form con questa semplice riga contenuta nell'evento Click di un 
menù (per il momento lascio in secondo piano i memory leak che avrò):
 
ec1 = TfrmEstrattoconto.Create(Self);
ec2 = TfrmEstrattoconto.Create(Self);
 
ma, tutte le form a partire dalla seconda visualizzano sempre e soltanto 
il contenuto della prima form creata e soltanto da questa posso cambiare 
il cliente/Fornitore/Conto che viene propagato a tutte le altre!
 
Perché succede? non dovrebbero essere DUE oggetti differenti aventi vita 
propria?
 
Dalle prove che ho fatto:
1) i due oggetti sembrano differenti, il test ec1 = ec2 è false.
2) la memoria occupata dai due oggetti sembra differente, ho provato a 
visualizzare gli indirizzi da Watch List a run time.
 
Grazie.

Ciao Luigi,
  premetto che non mai avuto la necessita' di fare applicazioni MDIChild ma 
uso abbastanza i frame.
Quindi la  mia risposta potrebbe non essere non corretta.
 
[quoto]
La form fa riferimento, nella sezione "Private", ad un datamodule dove
sono presenti i Datasource e le query che estraggono i dati.
 
Creo la form con questa semplice riga contenuta nell'evento Click di un
menù (per il momento lascio in secondo piano i memory leak che avrò):
 
ec1 = TfrmEstrattoconto.Create(Self);
ec2 = TfrmEstrattoconto.Create(Self);
 
ma, tutte le form a partire dalla seconda visualizzano sempre e soltanto
il contenuto della prima form creata e soltanto da questa posso cambiare
il cliente/Fornitore/Conto che viene propagato a tutte le altre!
 
[fine]
 
Cosa succede nella create?
Come inizializzi i vari componenti per la gestione dei dati?
Forse e' qualcosa legato al MDIChild, hai provato lo stesso codice in una 
form normale?
Ricordati i nomi, cosi' puoi far riferimento a quello quando devi liberare 
l'oggetto.
 
Ciao
Daniele
 
 
 
 
 
 

Ciao.
Prima di tutto, MDI è non obsoleto quanto deprecato (in fondo anche delphi è defunto ma
A parte ciò, la causa del problema è ovvia:
 
hai 2 form che usano LA STESSA ISTANZA DATAMODULE.
 
La soluzione consiste nel creare una istanza del datamodule per ogni istanza del tuo form e linkarla a runtime.
 
A.

 
 
Grazie.

 
 
Faccio questa considerazione:
L'oggetto TField contiene l'oggetto TDataSet.
Il TDataSet viene creato più o meno nello stesso modo. Perché con il 
TField non succede quello che succede a me?
 
Grazie.

Confusione...
 
1) ti chiedo scusa: non avevo capito  che creavi una istanza DM per ogni istanza FORM
 
2)  il paragone cont tfield/tdataset non c'entra un kazzen con il tuo caso
 
 
Tornando al tuo problema, ok, ogni form si crea il prp datamodule.
Domanda:
 
NEL TUO FORM CHI DICE ALLE TUE DBGRID O ALTRO CHE SI DEVONO ATTAACCARE ALLE QUERY O ALTRO DEL  DM DICHIARATO IN PRIVATE ETC E NON QUELLO CHE PRESUMO SIA IN AUTOCREATE?
Se nel tuo form hai associato A DESIGNTIME una dbgrid a dmQualcosa. qualcosaltro, dopo aver creato il datamodule devi scrivere una cosa del tipo:
 
dbgrid.datasource := FdmEstrattoConto.qualcosa.
 
Questo codice c'è? Sta cosa la fai?
 
 
A.
 
 
 
 
 
Quello che fai tu, quindi e:
 
1) ogni form crea una istanza DM


 uso il metodo try..finally..end
Si ma come fai a trovare la form aperta sulla quale stai lavorando? (domanda 
banale fatta da uno che NON usa mdi)
 
Se poi nella form metti griglie, datamodule, dataset ecc... essi vanno 
opportunamente configurati (come giustamente di suggerisce Alberto).
 
Ciao e alla prossima
 
Daniele 
 

 
 
No, questo codice non c'è/Non la faccio perché il nome del DataModule a 
design time è anche quello run time.
In pratica:
 
dbgrid.datasource := FdmEstrattoConto.qualcosa
 
è valido sia a design time che run time.
 
Grazie.
 
Ciao.

 (domanda banale fatta da uno che NON usa mdi)
 
Le form hanno un proprio nome perché viene assegnata una variabile per 
ogni form creato:
 
ec1 = TfrmEstrattoconto.Create(Self);
ec2 = TfrmEstrattoconto.Create(Self);
 
per cui so e posso distinguere le varie form.
 
Ad ogni modo, nelle applicazioni MDI è possibile assegnare una voce del 
menu presente nella form MDIForm per elencare tutte le form MDIChild 
aperte indipendentemente se queste sono state assegnate a variabili o no.
 
Grazie.
 
Ciao.

 
 
Questa tua domanda mi fa pensare che, forse, non mi sono spiegato bene 
nel post originale:
 
Il difetto che riscontro NON è che non vedo nulla. Il difetto che 
riscontro è che la seconda/terza/.. form creata mostra sempre e solo i 
dati della _prima_ form e se provo a cambiare conto, ad esempio, non 
viene cambiata la visualizzazione che rimane quella della prima form ed 
è da quella form che posso fare i cambiamenti e che questi cambiamenti 
si propagano alle altre form come se tutte stessero facendo riferimento 
ad un datamodule _condiviso_ invece che privato.
 
Ma, anche quest'ultima affermazione (datamodule condiviso), non è del 
tutto corretto perché le form oltre la prima (cioè la seconda, la terza) 
_non_ interagiscono attivamente con il datamodule limitandosi a 
visualizzarne i dati che posso cambiare dalla prima form.
 
Grazie.

 Ciao.
 

           FM:=Nil; // Non si sa mai
 
Cosqa vuol dire "Non si sa mai"?
Credi forse che close liberi la form? Siamo messi bene...
 
:-|
 
A.

 
 
Ok, fatto il test:
 
   dblkcCliFor.DataSource := dmEstrattoConto.dsCliFor;
   dblkclkConto.DataSource := dmEstrattoConto.dsConto;
   zdbgEstrattoConto.DataSource := dmEstrattoConto.dsEstrattoConto;
 
_funziona!_
 
Quello che ho fatto è semplicemente _ripetere_ le assegnazioni già 
presenti nel form dal design time!
 
Però non capisco, perché?
 
Grazie.
 
Ciao.

 Cosqa vuol dire "Non si sa mai"?
Di solito libero con FreeAndNil, in effetti il close .... era un free
 
Peccato leggerti cosi' di rado ....
Sei su altri ng per caso??
 
Ciao
Daniele 
 

 _funziona!_
 
..ma non era quello che intendevo io..
 
Scusami, ma ci vuole cosi tanto a scrivere:
 
dblkcCliFor.DataSource := Datamoduleprivatocreatoquadentro.dsCliFor??
 
A.


 Daniele
 

 la "roccia" che era alcune versioni fa.
Hai ragione, lo sviluppo di Delphi, se non cambiano qualcosa, e' arrivato 
alla fine.
Vediamo cosa riserva il domani !!!
 
Un buon fine settimana
 
Ciao
 
Daniele 
 


E' un po' complesso, provo a spiegartelo brevemente:
 
Dipende da come e' gestito il caricamento del DFM di form e datamodule.
 
A design time praticamente tu colleghi i componenti della form
ai datasource del datamodul in modo visuale ma l'IDE salva questa
informazione dentro al file DFM.
 
Nel dfm lui scrive i nomi dei componenti (il .dfm e' un file di testo
alla fin fine..) e quando a run-time viene creata un'istanza della
form (o del datamodule), all'interno del costruttore delphi carica
il dfm corrispondente e lo utilizza per assegnare tutte le proprieta'
che tu hai assegnato a design-time
 
Per farlo deve risolvere i nomi dei componenti (che sono stringhe) 
e tradurli in componenti "veri" per (ad esempio) poter 
assegnare effettivamente il datasource dei tuoi controlli visuali.
 
Quando fa questo, fa una specie di FindComponent('dmEstrattoConto') per
trovare il datamodule esatto da cui prender i datasource.
 
Ora, quando tu crei un'istanza del datamodue TdmEstrattoConto, delphi
gli assegna il nome 'dmEstrattoConto', quindi la prima form
punta correttamwente al primo datamodule (perche' la FindComponent
trova proprio il primo datamodule che hai appena creato).
 
Cosa succede quando crei il secondo datamodule? delphi lo chiama
'dmEstrattoConto1', quindi quando va a caricare il dfm della tua seconda
form ed esegue il suddetto FindComponent, non trova il secondo
datamodule perche' ha un nome diverso, lui trova il primo.
 
Tutte le form finiscono quindi per puntare al primo datamodule.
 
Per sistemare questa cosa devi intervenire tu dopo e riassegnare 
manualmente la giusta istanza di datamodule ad ogni form.
 
ciao
Giacomo

 
 
Grazie.
 
Ciao.