Newsgroup: it.comp.lang.delphi
Titolo: Creazione di un form senza Free finale?

In un'applicazione ho una form che viene creata ogni volta che viene premuto
un pulsante. In questo modo posso avere a video 1, 2, 3...n copie di quella
form.
La domanda, stupidissima ma che al momento mi genera dei dubbi č:
se per un form modale uso la formula
var 
  form: tform;
form := tform.create;
form.showmodal;
form.free;
per un form normale come dovrei fare?
var 
  form: tform;
form := tform.create;
form.show
Non devo poi fare la free della variabile form?
-- 
Lis
Mercatino: 
http://snurl.com/sito_lis
Aiuta la ricerca contro il cancro: 
http://snurl.com/ida_team

Non devo poi fare la free della variabile form?
Nell'evento OnClose: 
action := caFree
-- 
"La velocità luce non è sufficiente Comandante Nunziatella, 
dobbiamo passare alla velocità smodata!"

 action := caFree
Giusto, dimenticavo...nell'evento Close della form ho specificato caFree.
Quindi non mi restano in giro puntatori "appesi" o memoria non deallocata?
grazie


grazie
No, nella misua in cui non ne rimangono facendo TForm.Free.
Ciaps  :)


 form := tform.create;
a casa mia sarebbe
  Form:= TForm.Create(RESPONSABILE_DELLA_SUA_DISTRUZIONE);
dove di solito RESPONSABILE_DELLA_SUA_DISTRUZIONE è Application.
Mettere Action:= caFree nell'OnClose non è necessario (se per esempio vuoi 
aprire e richiudere N volte la stessa form non modale nel ciclo di vita 
dell'applicazione).
Mettere Action:= caFree nell'OnClose diventa necessario solo nel caso in cui 
hai creato la form con 
  Form:= TForm.Create(nil);
-- 
Mauro Falzari 
   [ 
http://digilander.libero.it/mauro.falzari
 ]
 
 "Se guardi nell'abisso, anche l'abisso guarda in te." 
   (Friedrich Nietzsche)

aggiungo che porre 
  Form:= nil;
o chiamare 
  FreeAndNil(Form)
al termine del suo ciclo di vita, non guasta affatto


 al termine del suo ciclo di vita, non guasta affatto
Ma questo dove dovrei metterlo? Nella form_destroy della form che ho creato?


 dell'applicazione).
Nel mio caso la finestra può essere utilizzata più volte nel corso
dell'applicazione ma ci possono essere anche N finestre di quel tipo aperte
contemporaneamente.
Un esempio di quanto vorrei ottenere (e che funziona ma ho solo il dubbio di
gestire correttamente la memoria) è outlook e la finestra di creazione di
una nuova mail: posso crearne più contemporaneamente e posso crearne una
nuova semplicemente premendo un pulsante.
Quindi, per esempio (form1 è la form principale e form2 è la figlia):
procedure TForm1.btnCreaFinestra;
var
  F2: TForm2;
begin
  F2 := TForm2.Create(Self);
  F2.parametro1 := 1;
  F2.parametro2 := 2;
  F2.show;
end;
procedure TForm2.FormClose(xxx);
begin
  Action := caFree;
end;
in questo modo è tutto "pulito"?


Ma questo dove dovrei metterlo? Nella form_destroy della form che ho creato?
Cosa che però, in questo caso, non è possibile fare in quanto il free
non è esplicito.
mettere a nil il puntatore è semplicemente un esercizio di stile in
questa situazione ;-) 
Visto il tuo esempio
procedure TForm1.btnCreaFinestra;
var
  F2: TForm2;
begin
  F2 := TForm2.Create(Self);
  F2.parametro1 := 1;
  F2.parametro2 := 2;
  F2.show;
end;
La variabile potresti benissino non averla del tutto facendo così:
begin
  with TForm2.Create(Self) do begin
    Parametro1 := 1; 
    Parametro2 := 2;
    Show;
  end;
end;
addirittura, se non avessi parametri da passare, potresti
semplicemente fare
TForm2.Create(nil).Show; 
come vedi, il problema non si pone


 TForm2.Create(nil).Show; 
In effetti, sì...ma preferisco scrivere una linea in più di codice ed averlo
più leggibile


 questa situazione ;-) 
nel caso specifico che ha appena proposto Lis non sarebbe neanche possibile farlo. 
Il mio discorso (non sapendo a qual'era il problema preciso che aveva in mente Lis) era 
riferito al caso in cui si ha una form principale e una secondaria e si vuole aprire e chiudere 
questa per un numero qualsiasi di volte.
Esempio: una form principale e una secondaria (modale o non modale) Opzioni.
Nella form principale metterei un campo privato
  FOptionsForm: TfmOptions;
nella procedura che fa apparire la form Opzioni scriverei qualcosa tipo
  if not Assigned(FOptionsForm) then
    FOptionsForm:= TfmOptions.Create(Application); //(1)
//(2)
    FOptionsForm.Show;   //(3)
In questo modo, se la form Opzioni deve essere mostrata più volte, si evita di doverla ricreare 
ogni volta (sempre se è questo ciò che si vuole, altrimenti oltre a usare Action:= caFree, 
bisognerà provvedere a un meccanismo di notifica nel quale la form principale imposti 
FOptionsForm:= nil alla sua chiusura).
+++++++++++++
Note:
(1) o anche Self, è uguale, perchè ho dato per scontato che stiamo scrivendo nella form 
principale (equivalente a Application.MainForm), la chiusura determina il termine 
dell'applicazione;
(2) per lo stesso ragionamento si può avere lo stesso risultato con
   Application.CreateForm(TfmOptions, FOptionsForm);
(3) così viene mostrata come non modale, per mostrarla come modale scriverei:
var
  iModalResult: Integer;
(...) 
  iModalResult:= FOptionsForm.ShowModal;


 in questo modo è tutto "pulito"?
in questo modo quando la finestra non modale secondaria viene chiusa, 
viene automaticamente distrutta. Secondo il caso specifico che hai 
proposto tu, è la cosa migliore perchè così liberi da subito le risorse.


dell'applicazione;
Sono della vecchia scuola e per di più con gli anni sto diventando un
reazionario della programmazione O_o (mi rendo conto che è un mio
limite) e prefersco, se possibile, avere il controllo della
distruzione delle classi, per questo preferisco utilizzare nil nel
costruttore piuttosto che Application o self ;-)
Ciao


 campi privati non può andare bene
no no, sicuramente non può andare bene, infatti avevo precisato subito che si 
trattava di un caso differente.


 grazie
tieni presente che il with alle volte può portare a dei sottili e subdoli 
malfunzionamenti (credo a causa del compilatore). Mi è successo diverso tempo 
fa in un caso che non riesco ora a ricordare nè a ritrovare tra i miei 
sorgenti. Ricordo di aver perso tantissimo tempo per scovare la causa 
dell'errore (istruzioni che facevano uso di with).
Ricordo di aver postato il problema sui gruppi di Marco, ma sono ancora down 
e non posso cercarlo.


 dell'errore (istruzioni che facevano uso di with).
Sì, avevo gà sentito di questi possibili problemi per cui cerco di usarlo
con attenzione, ma in questo caso direi che è veramente comodo


 proposto tu, è la cosa migliore perchè così liberi da subito le risorse.
Grazie per la spiegazione, mi hai chiarito molti dubbi


Lis wrote:
<snip>
Un paio di considerazioni al volo:
1) La With è *pericolosa*, ma utile a volte.
2) Puoi evitare la free, in diversi modi. Vediamone alcuni:
1) Action := caFree nell'OnClose,
2) Chiamare Release nell'OnDestroy,
3) FreeAndNil da fuori.
SE non ricordo male, da qualche parte ci dovrebbe anche essere la MIA
implementazione della FreeAndNil per quelle versioni di Delphi che non la
supportano nativamente.
Una piccola nota: se chiami Release, viene fatto il free MA NON VIENE
ASSEGNATO NIL AL PUNTATORE.
Pessima invece, imho, l'idea di usare un costrutto come
TMiaForm.Create(nil).Show che è sempre a rischio memory-leak se uno non si
ricorda di impostare la Action nell'OnClose.
Diverso sarebbe se venisse usato un parametro di tipo Application,
oppure la VFI, definendo il comportamento nell'ancestor.
My 2c,
Andrea

 Andrea
Grazie anche per le tue precisazioni
