Private veya public olması ile ilgili bir şey söylemedim ama ifadem yanıltıcı olmuş olabilir,
Formları yönetmek çok geniş bir kavram olduğu için sadece sorunuz çerçevesindeki kısım ile sınırlı tutuyorum o nedenle detayları kodlar üzerinden açıklayayım.
Ön hazırlık olması ve kapanırken bellek sızıntısı oluşuyor mu oluşmuyor mu basitçe anlamak için .DPR dosyasındaki begin bloğuna aşağıdaki kodu ekliyoruz.
...
begin
ReportMemoryLeaksOnShutdown := True; // bellek sızıntıları varsa program kapanırken bir rapor göstersin.
Application.Initialize;
...
Owner mekanizması denilen bir kavram var. Buna göre bir nesneyi oluştururken onun varlığını ve yokluğunu kontrol edecek bir sahip belirtmek gerekir. Dolayısıyla ana nesne yok edilirken ona bağlı alt nesneler de bu sayede otomatik olarak yok edilebilir.
unit Unit1;
interface
...
...
var
Form1: TForm1;
implementation
{$R *.dfm}
uses unit2, unit3;
procedure TForm1.Form21Click(Sender: TObject);
begin
{ artık global bir değişken (Form3) kullanmadığımız için bu kısım geçerli değil.
Application.CreateForm(TForm3, Form3);
Form3.ShowModal;
Form3.Free;
}
with TForm3.Create(Self) do // SELF = Bu nesne, yani bu durumda Form1 nesnesidir.
try
ShowModal;
finally
Free;
end;
end;
{ bu sizin orjinal kodunuz;
procedure TForm1.Formlar2Click(Sender: TObject);
begin
if Assigned(Form2) then
Form2.show
else
begin
Application.CreateForm(TForm2, Form2);
Form2.FormStyle := fsMDIChild;
Form2.Show;
end;
end;
}
procedure TForm1.Formlar2Click(Sender: TObject);
var
I: Integer;
Form2Exists: Boolean;
begin
Form2Exists := False;
// Tüm MDIChild formları kontrol et
for I := 0 to MDIChildCount - 1 do
begin
if MDIChildren[I] is TForm2 then
begin
Form2Exists := True;
MDIChildren[I].Show; // Zaten varsa, göster
exit;
end;
end;
if not Form2Exists then
begin
with TForm2.Create(Self) do
try
FormStyle := fsMDIChild;
Show;
finally
//Free; // doğrudan free etmiyoruz çünkü bu işi kullanıcı formun kapatma butonuna basarak kendisi manuel olarak gerçekleştirecek. detaylar TForm2.FormClose'da
end;
end;
end;
end.
2. forma gelelim;
unit Unit2;
interface
...
...
// Bu kısmı iptal edin.
//var
// Form2: TForm2; // bu tanıma gerek yok
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
{ bu kısım anlamını yitirdi.
if Assigned(Form2) then
ShowMessage('Assigned')
else
ShowMessage('not Assigned');
}
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
Close;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree; // bu atamayı yaparak aslında FREE işlemini bu kısım VCL'in derinliklerinde gerçekleştiriyor zaten.
//Form2 := Nil; // global bir değişkenimiz yok, o nedenle olmayan bir değişkenin referansını da artık sıfırlamamıza gerek yok.
end;
end.
3. forma gelelim;
unit Unit3;
interface
...
...
// bu kısmı iptal edin
//var
// Form3: TForm3;
implementation
{$R *.dfm}
uses unit2;
procedure TForm3.Button1Click(Sender: TObject);
//var F2 : TForm2; // --> Eğer değişken kullanmak zorundaysanız
begin
{ global veya yerel, bir değişkenimiz yok, alternatifi aşağıda
Application.CreateForm(TForm2, Form2);
Form2.Button2.Visible := True;
Form2.Position := poMainFormCenter;
Form2.ShowModal;
Form2.Free;
}
{ Eğer değişken kullanmak zorundaysanız
F2 := TForm2.Create(Self) ; // SELF yerine NIL, APPLICATION da verebilirsiniz, bu kısım sizin araştırma konunuz olsun.
with F2 do
}
with TForm2.Create(Self) do // Oluşturma sırasında aşağıdaki işlemleri de peşisıra gerçekleştiriyoruz.
try
Button2.Visible := True;
Position := poMainFormCenter;
ShowModal; // MODAL olduğu için uygulamanın tamamı bu noktada işin bitmesini bekliyor.
finally
Free; // MODAL'dan çıkıldığı an formu yok ediyoruz.
end;
end;
procedure TForm3.Button2Click(Sender: TObject);
begin
Close;
end;
end.
with TForm?.Create(Self) do yerine formlarınızda class function veya class procedure de tanımayabilirsiniz.