Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: petrusic - Febbraio 11, 2021, 02:53:13 pm

Titolo: [Risolto] chiudere una Form Modale ... distruggendola?
Inserito da: petrusic - Febbraio 11, 2021, 02:53:13 pm
la domanda nasce in seguito all'esempio di codice da riportato in altra discussione:
Citazione
Citazione da: bonmario
Nel Form1, dovresti fare qualcosa del genere:
Codice: [Seleziona]
   Application.CreateForm(TForm2, Form2);
    Form2.ShowModal;
    FreeAndNil(Form2);
ho utilizzato:
Codice: [Seleziona]
 frm2:= TForm2.Create(Application);
 frm2.Showmodal;
 frm2.Close;           
in cui l'ultima dovrebbe agire come distruttore della Form2. Comunque ci lavorerò, per capire bene.
a cui Stilgar a risposto:
Citazione
Per la distruzione automatica, prova a controllare OnClose.
Dovrebbe permetterti di indicare la distruzione della memoria dopo la chiusura.

----------------------

A tale proposito ho trovato qui (https://forum.lazarus.freepascal.org/index.php/topic,44343.msg311667.html#msg311667)
un esempio di applicazione dell'evento OnClose:
Citazione
potresti mettere CloseAction: = caFree; in FormClose del modulo in modo che quando viene chiuso, verrà anche distrutto.
Allora, forte di quanto letto, l'ho utilizzato nel mio programmino corrente:
Codice: [Seleziona]
procedure TForm2.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  WriteLn('proc. TForm2.FormClose');
  CloseAction:= caFree;
end;                 

Quindi, in definitiva potrei :
uscire dalla Form2 (modale) in tre modi:
Codice: [Seleziona]
procedure TForm2.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  WriteLn('proc. TForm2.FormClose');
//  CloseAction:= caFree;   // la form viene distrutta e viene quindi liberata memoria
//  self.Close;   // la form viene chiusa ma rimane in memoria
//  self.Hide;    // la form viene semplicemente nascosta
end;   
traendo le seguenti conclusioni:
mentre Self.Close e Self.Hide nascondono la vista della Form modale,  l'unica che elimina la Form2, distruggendo ogni suo contenuto e puntamento è la prima.

Però, eseguire  **CloseAction:= caFree** dentro la Form2,  o eseguire **FreeAndNil(Form2);** al rientro, nella Form chiamante è la stessa cosa?

Provo a rispondermi da solo, per quanto letto poco fa sul wiki:
Citazione
FreeAndNil è una procedura definita nell'unità SysUtils della Free Pascal Runtime Library . Chiama il distruttore di un oggetto (tramite TObject.Free) e imposta anche la variabile oggetto (che è un riferimento alla memoria heap creata da una chiamata al costruttore) su nil.
Titolo: Re:chiudere una Form Modale ... distruggendola?
Inserito da: Stilgar - Febbraio 11, 2021, 05:07:17 pm
Ciao
Penso che dare un'occhiata alla documentazione sia un attimo meglio che cercare subito nei forum.


https://lazarus-ccr.sourceforge.io/docs/lcl/forms/tcustomform.onclose.html

https://lazarus-ccr.sourceforge.io/docs/lcl/forms/tcloseevent.html

Codice: [Seleziona]
type TCloseEvent = procedure(  Sender: TObject;  var CloseAction: TCloseAction) of object;


https://lazarus-ccr.sourceforge.io/docs/lcl/forms/tcloseaction.html

Codice: [Seleziona]
type TCloseAction = (  caNone,  Do nothing.  caHide,  The form is hidden.  caFree,  The form is destroyed.  caMinimize  The form is minimized.);

Utilizzare nella OnClose il comando self.Close, mi fa penare che si possa avere qualche problema di stack overflow.

In altre parole ti metti nelle condizioni di ottenere un loop mortale.

Close e Hide sarebbe meglio farla chiamare da fuori, non da dentro il gestore della callback della OnClose.

Impostando il valore di CloseAction[size=78%] in modo coerente con quello che vuoi ottenere (liberare memoria o semplicemente far fare altre cose alla form).[/size]

Stilgar
Titolo: Re:chiudere una Form Modale ... distruggendola?
Inserito da: petrusic - Febbraio 11, 2021, 05:33:14 pm
Grazie Stilgar. Ora è tutto chiaro.