Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
[ÇÖZÜLDÜ - SOLVED] Owner - Parent Form nasıl kullanılmalı?
#1
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.
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#2
ana form destroy edilmişken child formun metodunun çalışmaması lazım. mantık hatası var gibi.
WWW
Cevapla
#3
@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.
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#4
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;
WWW
Cevapla
#5
Alt Formda ParentFormu var bloğunda tanımlayıp, ana form close olduğunda nil atarsanız sonuç alabilirsiniz.
WWW
Cevapla
#6
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..  Idea

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)
  • AnaForm'un OnDestroy eventine AnaForm := nil; ekledim ve bekledim ki if Assigned( FAnaForm ) dediğimde nil dönsün. Ama şaşkınım ki öyle dönmedi.
  • Başka bir deneme -ki sanırım bu sizin çözümünüz olacakIdea AnaForm := nil; demeden hemen önce ( yine OnDestroy eventi ) AnaForm.Tag := 99; şeklinde değer verdim, AltFormda bu değerin baki kaldığını gördüm. 
  • Özetle, ana formun free olduğu yerde o formun TAG değerine önceden karar vereceğiniz bir değer verdiğinizde ve alt formda bu değeri sorguladığınızda, ana formun kapanmış mı yoksa hayata devam mı ediyor olduğunu anlayabileceksiniz..

Bir ekleme :  

 if FParentForm <> nil then showmessage('nil değil...');
şeklinde sordum nil mesajı değil geldi.
ama hemen altında
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.
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#7
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.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#8
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????
WWW
Cevapla
#9
@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;
PostgreSQL - Linux - Delphi, Poliüretan
WWW
Cevapla
#10
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 Smile
WWW
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  SQL Table Type parametre gecisi hakkında (Çözüldü) adelphiforumz 1 153 09-04-2026, Saat: 15:53
Son Yorum: adelphiforumz
Question Delphi formunu nasıl otomatik tam ekran yapabilirim ? erdemklt0 2 324 23-01-2026, Saat: 10:02
Son Yorum: csunguray
  TMS Web Core- REST İşlemlerini Nasıl Yapabilirim? kajmerantime 0 429 13-06-2025, Saat: 14:07
Son Yorum: kajmerantime
  form close de form bosalmiyor sadikacar60 11 1.626 24-01-2025, Saat: 19:25
Son Yorum: sadikacar60
  FastReport Dinamik Sayıya Göre Etiket Bastırma [ÇÖZÜLDÜ] bünyamin68 2 752 09-01-2025, Saat: 13:47
Son Yorum: bünyamin68



Konuyu Okuyanlar: