![]() |
|
[ÇÖZÜLDÜ - SOLVED] Owner - Parent Form nasıl kullanılmalı? - Baskı Önizleme +- Delphi Can (https://www.delphican.com) +-- Forum: Delphi (https://www.delphican.com/forumdisplay.php?fid=3) +--- Forum: Genel Programlama (https://www.delphican.com/forumdisplay.php?fid=6) +--- Konu Başlığı: [ÇÖZÜLDÜ - SOLVED] Owner - Parent Form nasıl kullanılmalı? (/showthread.php?tid=4925) Sayfalar:
1
2
|
[ÇÖZÜLDÜ - SOLVED] Owner - Parent Form nasıl kullanılmalı? - 3ddark - 04-06-2020 Merhaba, Elimde 2 adet form var. Bunlardan bir tanesi diğeri üzerinden açılıyor. Açılan alt form duruma göre Ana formdaki bazı rutinlerini çalıştırıyor. Fakat Ana Form kapatmış olabilir. Ben alt formdan Ana formun hala kullanılabilir yaşayan bir form ise bu rutini çağırmak istiyorum. Aksi durumda olmayan bir nesne içindeki rutini çağırmış olacağım ve hata alacağım. Formları dinamik olarak create ediyorum. Herhangi bir değişkende instance tutmuyorum. Açılan her form kendisini biliyor ve varsa Owner ve ParentForm bilgisini biliyor. Anlatmak adına basit kod örneği aşağıdadır. unit uFormAna;//main form unit
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls, Unit3;
type
TFormAna = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
public
procedure Msg();
end;
implementation
{$R *.dfm}
procedure TFormAna.Button1Click(Sender: TObject);
begin
TFormAlt.Create(nil, Self).Show; //create child form and show
end;
procedure TFormAna.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree; //destroy main form
end;
procedure TFormAna.Msg;
begin
ShowMessage('Message from Main Form'); //show message in main form
end;
end.
unit uFormAlt; //child form unit
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TFormAlt = class(TForm)
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
public
FParentForm: TForm;
constructor Create(AOwner: TComponent; AParentForm: TForm); reintroduce; overload; virtual;
end;
implementation
uses uFormAna;
{$R *.dfm}
constructor TFormAlt.Create(AOwner: TComponent; AParentForm: TForm);
begin
inherited Create(AOwner);
FParentForm := AParentForm; //main form value
end;
procedure TFormAlt.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree; //destroy child form
end;
procedure TFormAlt.FormDestroy(Sender: TObject);
begin
if Assigned(FParentForm) then //if main form is useable call msg routine
TFormAna(FParentForm).Msg;
end;
end.
Owner - Parent Form nasıl kullanılmalı? - sadettinpolat - 04-06-2020 ana form destroy edilmişken child formun metodunun çalışmaması lazım. mantık hatası var gibi. Owner - Parent Form nasıl kullanılmalı? - 3ddark - 04-06-2020 @sadettinpolat yorum için teşekkürler. Zaten amacım ana formun metodunun çağırılmasını engellemek. Bunuda ParentForm kontrolü ile sağlamak istiyorum. Bu yazdığım şeklin dışında nasıl bir mantıkla yapılabilir. Cvp: Owner - Parent Form nasıl kullanılmalı? - sadettinpolat - 04-06-2020 Yukarda belirttiğim mantık hatası haricinde kod doğru görünüyor. Ek bir tedbir olarak try except bloğu kullanılabilir. procedure TFormAlt.FormDestroy(Sender: TObject); begin try if Assigned(FParentForm) then //if main form is useable call msg routine TFormAna(FParentForm).Msg; except end; end; Owner - Parent Form nasıl kullanılmalı? - esistem - 04-06-2020 Alt Formda ParentFormu var bloğunda tanımlayıp, ana form close olduğunda nil atarsanız sonuç alabilirsiniz. Owner - Parent Form nasıl kullanılmalı? - mrmarman - 04-06-2020 Bu şekilde bir kullanım daha önce hiç ihtiyacım olmamıştı. Normalde her ürettiğim / üretilen thread olsun bileşen olsun mutlaka bir merkezden listesini tutarım. Sorunuz da bana mantıklı geldi. Liste tutmadan nesnel bir yaklaşım.. Denemek için şöyle bir test projesi oluşturdum. * Bir layer daha ekledim, bir MAINFORM ( Application Mainform oluyor, sizin ana form kapatılınca process sona eriryor, anlamak için hayatına devam etsin istedim.) * AnaForm (sizin ana form) * AltForm ( sizin alt form)
Bir ekleme : Kod: if FParentForm <> nil then showmessage('nil değil...');ama hemen altında Kod: ShowmessageFmt('%x', [ FParentForm.Handle ]);dediğimde access viloation verdi. Şaşırdığım konu bu... Kafamı karıştıran FParentForm içinde adres olduğuna göre form free edilse de memory'de kalıyor. RELEASE olamıyor. Dolayısıyla sizin Msg de çalışmaması gerekirken çalışıyor. Burada beklenmedik bir şey daha öğrendim... Soru için kendi adıma teşekkürler. Owner - Parent Form nasıl kullanılmalı? - Tuğrul HELVACI - 04-06-2020 Bir nesne kendisine ne kadar referans olduğunu bilmez, dolayısı ile nesnenin yok olması referans pointerlarını boşaltmaz. Bu gibi nedenlerden ötürü Free yerine FreeAndNil çağrımını tavsiye etmiştik forumda detaylı bir konu altında. Sizin mekanizmada ise Notification metoduna benzer bir yaklaşım gerekir. Owner geçmiş olsaydınız Notification çağrımı olacaktı ama sizinki biraz garip bir yaklaşım. Yeni oluşturduğunuz form öksüz kalabiliyor. Bu durumda ana formunuzdan çocuk formu create ettiğinizde, ana formunuzda bir değişkene ilgili form instance’sini kayıt edin; sonra ana formunuz kapanırken kayıt ettiğiniz instance’nin bir metodunu çağırın. SavedInstance.BenYokOluyorum; gibi. Cvp: Owner - Parent Form nasıl kullanılmalı? - esistem - 04-06-2020 Test etmedim ama mantık aşağıdaki şekilde işlemiyormu? anaform create edildiğinde hafızada bir yere yerleşiyor, bu arada altform ortalarda yok, butona basıp altform create edildiğinde, altformun içerisindeki FParentForm: TForm; değişkenide create edilip hafızada bir yere yerleştiriliyor ve anaforma eşitleniyor (kısaca bir kopyası hafızada başka bir yere yerleştiriliyor), biz anaformu kapatınca anaform.free diyoruz fakat bu esnada hafızada FParentForm hala yerleşik duruyor, altform'dan anaform'a ait bir işlem çağırdığımızda FParentForm dan alıp bize gösteriyor. eğer böyleyse ki böyle görünüyor, her iki taraf içinde bir sorun yok aslında???? Owner - Parent Form nasıl kullanılmalı? - 3ddark - 04-06-2020 @mrmarman hocam bende tam olarak sizin dediğiniz şekilde kullanıyorum. Main form var orada output dbgrid listeleme formlarını açıyorum. Her output olarak açılan form içinden gerekli input formları açıyorum. Açarken de showmodal olarak açmıyorum. DB işlemlerini her input form kendi içinde bitiriyor. İşlem sonunda kendisini kapatıyor ve kapanırken de output formdaki dbgrid içeğini refresh ediyor. Yeni eklenen kaydın listeye düşmesini sağlıyorum. Fakat formlar show modal olmadığı için kullanıcı kafasına göre önce output formu kapatabiliyor. Bu durumda Parent olmayan bir child form ortalarda geziyor. Çözüm olarak şu şekilde kullandığımda sorun olmuyor. Windowun Handle kontrolü ile sorunsuz çalışıyor. if FParentForm.HandleAllocated then if Assigned(FParentForm) then //if main form is useable call msg routine TFrmAna(FParentForm).Msg; HandleAllocated içeriği şı şekilde function TWinControl.HandleAllocated: Boolean; begin Result := WindowHandle <> 0; end; [ÇÖZÜLDÜ - SOLVED] Owner - Parent Form nasıl kullanılmalı? - esistem - 04-06-2020 Bende dediğiniz mantıkla yapıyorum güncelleme işlemlerini, sadece kullanıcı önce main formu kapatırsa, ondan türeyen child form varsa onuda kapatıyorum, 1-2 yanlış kullanımdan sonra kullanıcı kapatmaması gerektiğini öğreniyor
|