Oppure

Loading
21/04/11 7:50
Goblin
Postato originariamente da lorenzo:

il problema secondo me è la variabile locale.
Quando il form2 si apre, la variabile Form2 viene allocata nello spazio di memoria della funzione Click come variabile locale.
Una volta terminata la funzione la variabile viene eliminata con la sua memoria e, quando il form2 viene chiuso, non trova più la memoria correttamente associata e tenta di pulire lo spazio appartenente a qualcun altro. Da qui il messaggio di errore.

Per risolvere o dichiari Form2 come globale(inteso come variabile membro di Form1 che è la classe principale del progetto) oppure la crei come finestra Modale: in quest'ultimo caso Form2 deve essere chiuso PRIMA di uscire dalla funzione click e quindi il problema della memoria non si pone.


mmmmm, allora
La variabile viene creata locale e gestita come tale, una volta invocato il metodo SHOW il comando passa alla form2, delphi7 non avendo la garbage collection non libera l'istanza alla form, la libera solo alla chiusura del owner, dunque sarà cura del programmatore liberare la memoria allocata per mezzo di una cafree nel close della form2.
Nel caso dichiari Form2 come variabile globale la logica del programma cambia, ossia: se la dichiari come variabile locale ad ogni click associ un istanza diversa e separata di form2 che vive di vita propria, se invece la dichiari come variabile globale devi stare molto attento a testare se già esiste l'istanza alla form altrimenti ti ritrovi che la tua variabile viene sovrascritta ad ogni click da una nuova istanza di Form2.
Nel caso di metodo modale, showmodal, non cambia molto in quanto non è stato messo nessun distruttore.

Riassumendo:

type
TForm1 = class(TForm)
...
private
Form2: TForm2;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Self);
Form2.Show;
end;
In questo modo ad ogni click di button1 la variabile viene sovrascritta per evitare ciò:
procedure TForm1.Button1Click(Sender: TObject);
begin
if not(assigned(Form2)) then
Form2 := TForm2.Create(Self);
Form2.Show;
end;
ma così facendo fai un semplice show di una form creata in precedenza, con tutti i rischi che comporta....

....
procedure TForm1.Button1Click(Sender: TObject);
var Form2: TForm2;
begin
Form2 := TForm2.Create(Self);
Form2.Show;
end;
Ad ogni click di button1 viene generata una nuova istanza di form2 che sarà distrutta dall'owner (self) alla chiusura dell'applicativo a meno che non si lavora diversamente.
se poi vogliamo il modale
procedure TForm1.Button1Click(Sender: TObject);
var Form2: TForm2;
begin
Form2 := TForm2.Create(Self);
Form2.Showmodal;
end;
anche qui ...vedere un codice così .. direi .. orrore e ribrezzo... meglio scrivere

procedure TForm1.Button1Click(Sender: TObject);
begin
With TForm2.Create(Self) do
try
ShowModal;
finally
free;
end;
end;
In questo modo l'istanza creata di form2 viene distrutta all'uscita

dunque il problema è: Cosa vuole fare il nostro amico camaleonteplus ? e cosa c'e' scritto in form2?

di più nin so
G.

Ibis redibis non morieris in bello
22/04/11 4:20
camaleonteplus
In Form1 ho inserito questo codice:
[CODE]procedure TForm1.Button1Click(Sender: TObject);
var
Frm: TForm2;
begin
Frm := TForm2.Create(Self); // "Self" rappresenta qui l'istanza di TForm1
Frm.Show;
end;[/CODE]
e ho modificato anche il buttonclick del form3 che era in showmodal gli ho dato il tipo di codice descritto sopra.
PS il form3 non da problemi.
aaa
22/04/11 4:54
camaleonteplus
Trovato l'errore, nel Form2 avevo inserito un codice preso da un mio sorgente appartenente ad un altro programma che stavo sviluppando dimenticando di modificare i dati:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     Form2.hide;
with TForm2.Create(Self) do
try
     ShowModal;
finally
     Free;
end;
     Application.Terminate;
end;

Adesso va tutto bene, mi sono distratto come al solito.
aaa