Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Sizce bu bir BUG'mıdır ?
#1
Senaryo:


  1. MDI bir uygulamanız var.
  2. Uygulamanızda birden fazla MDI Child formunuz var ve bu formlardan bir kısmı bir t anında ekranda görünür durumda ve bu formlarınızın OnCloseQuery olayında bir kısım kodlar var.
  3. Ana formunuzun OnCloseQuery olayında da bir kısım kodlar var.
  4. Kullanıcı uygulamanızı kapatmak istiyor.
Mevcut durumda şöyle oluyor:
  1. Tüm MDI Child formların OnCloseQuery olay yöneticileri tetikleniyor.
  2. En son ana formunuzun OnCloseQuery olay yöneticisi tetikleniyor.
Bu bir nesnenin sahibi olduğu nesneleri yok etmesi mantığında olduğu gibi işliyor. Ancak olması gereken bu mu acaba ? Bana kalırsa kullanıcı ana formun OnCloseQuery olayına bir kod yazdı ise, önce o kod çalıştırılmalı ardından CanClose değişkeni üzerinde varsayılan değerden farklı bir değer ataması yapıldı ise, mdi child pencerelerinde OnCloseQuery olayı çağrılmalı. Yani kullanıcı merkezi bir noktadan "Uygulamadan çıkmak istiyor musunuz ?" gibi bir soru sordu ise bunun cevabını beklemeden tüm pencerelere gitmek ve kapanabilirmiyim diye sormak pek makul görünmüyor. Çünkü kapanıp kapanmama kararı kullanıcıya sorulmak isteniyor.

Burada ise tam tersi bir durum söz konusu. Önce çocuk formların OnCloseQuery metodları çağrılıyor ve tüm CanClose'lar true ise, ana formun OnCloseQuery olayı tetikleniyor.

Sizin fikriniz nedir ?
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#2
CustomForm'un (Yani TForm'un atası) CloseQuery'si virtual tanımlanmış gözüküyor(Forms.pas):
function CloseQuery: Boolean; virtual;

O zaman ben bunu eze eze kullanabilirim Smile
Kendi formumda 
function CloseQuery: Boolean; override;
yazıp bunun kodlarında 
inherited CloseQuery;
yazıp yazmamak bana kalmış. Yazmazsam Child formaların kapanıştan haberi olmaz sanırım.
There's no place like 127.0.0.1
WWW
Cevapla
#3
Elbette sevgili kardeşim. Lâkin benim demek istediğim varsayılan davranışta bir problem mi var acaba Wink
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
Merhaba,

Ben bir BUG yerine kullanıcıya bırakılmış opsiyonel bir tercih olduğunu düşünüyorum. @SimaWB hocanında dediği gibi istenilen şekilde kod değişikliği ile yapılabilir. BUG olduğunu düşünmüyorum.

İyi çalışmalar Smile
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
Cevapla
#5
Bizim bellek yönetimi için yaptığımız işlemlerde bu sırada gitmiyormu Tuğrul hocam ? Birbirine bağımlı nesneler bağlantı sırasına göre sırayla free ediliyor, bundaki mantıkta aynısı olmuyormu? Önce child formlara kapanıştaki işlemlerini yap bende senden sonra kapatayım diyor. Ama dediğiniz gibi 50 tane forma var hiçbirisinde close değiştirilmemiş, buna rağmen hepsinin close olayı tetikleniyorsa burda bir BUG dan söz edilebilir. Varmı değişiklik bak, varsa çalıştır, yoksa es geç diyebilir tabi.
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
WWW
Cevapla
#6
(13-08-2018, Saat: 15:39)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Elbette sevgili kardeşim. Lâkin benim demek istediğim varsayılan davranışta bir problem mi var acaba Wink

Aslında ben de onu ifade etmeye çalıştım, hiç bir problem yok: 
Delphi gayet güzel bir şekilde bize seçenek sunmuş. İstersen haber verme diyor.

Diğer türlü olsaydı; böyle bir haber verme mekanizması olmasaydı, haber vermeye çalışmak daha zor olurdu.

Genel kullanımda ben ana formu kapatmak istediğimde çocuk formların haberdar edilmesi gerektiğini düşünüyorum. Çocuk form'da neler yapılıyor bilmiyoruz. Belki gerçekten yarım bırakılmaması gereken bir iş yapıyor. O yüzden, "bak ben kapatıyorum, işini bitir" demek gayet güzel.

Ben bunu, işletim sistemi kapanırken açık olan tüm uygulamalara mesaj gitmesine benzetiyorum. Ve çooooook doğal karşılıyorum Smile
There's no place like 127.0.0.1
WWW
Cevapla
#7
Sanırım, yine anlatamadım. Ben OnCloseQuery'ler child formlarda gerçeklenmesin demiyorum ki.

Programcı Main form'un OnCloseQuery olayında bir kod yazdı ise ve programı kullanan kullanıcıya şöyle bir mesaj çıkardı ise:

CanClose := AlertMessage('Programdan çıkmak istediğinize emin misiniz ?') = mrYes;

Bu durumda, açık durumda olan 100 tane child(farzedelim) formun OnCloseQuery'lerinin önce tetiklenmesinin bir anlamı yoktur. Çünkü, kullanıcı main form'daki alert mesajına cevaben HAYIR diyebilir. Child formların kapanıp kapanamayacağının kontrolünün; kullanıcının evet demesinden sonra yapılması daha yerinde olurdu demek istiyorum ben.

Örneğin;

function TfrmMain.CloseQuery: Boolean;
begin
  Result := TMessager.ShowMessage('Programdan Çıkmak İstiyormusunuz ?') = mrYes;

  if Result then
  begin
    // Child formlara da haber uçuralım :-)
    Result := inherited;

    if Result then 
      GercektendeProgramdanCikiyoruz;
  end;
end;

Şu anda varsayılan senaryoda ne oluyor peki ? Önce 100 adet form'un OnCloseQuery'leri işletiliyor sırası ile. Hepsinden CanClose true döndü ise en son ana formun'ki işletiliyor ve bir de bakıyoruz ki kullanıcı hayır demiş. Bu nedenle uygulamadan çıkamıyoruz zaten.

Umarım şimdi daha net anlatabilmişimdir.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#8
(13-08-2018, Saat: 16:26)esistem Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Bizim bellek yönetimi için yaptığımız işlemlerde bu sırada gitmiyormu Tuğrul hocam ? Birbirine bağımlı nesneler bağlantı sırasına göre sırayla free ediliyor, bundaki mantıkta aynısı olmuyormu? Önce child formlara kapanıştaki işlemlerini yap bende senden sonra kapatayım diyor. Ama dediğiniz gibi 50 tane forma var hiçbirisinde close değiştirilmemiş, buna rağmen hepsinin close olayı tetikleniyorsa burda bir BUG dan söz edilebilir. Varmı değişiklik bak, varsa çalıştır, yoksa es geç diyebilir tabi.

Bu tam olarak içinde 100'lerce item barındıran bir Liste'nin itemleri içinde döngüye girip onları Free edip ardından liste'yi Free etmekten vazgeçmeye benziyor ;-)
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#9
Kısaca ve belki de daha anlaşılır şekilde; aşağıdaki orjinal kodun:

function TCustomForm.CloseQuery: Boolean;
var
 I: Integer;
begin
 if FormStyle = fsMDIForm then
 begin
   Result := False;
   for I := 0 to MDIChildCount - 1 do
     if not MDIChildren[I].CloseQuery then Exit;
 end;
 Result := True;
 if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);
end;

değiştirilip aşağıdaki hâle gelmesi gerektiğine inanıyorum.

function TCustomForm.CloseQuery: Boolean;
var
 I: Integer;
begin
 if FormStyle = fsMDIForm then
 begin
   Result := False;

   if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);

   if Result then
     for I := 0 to MDIChildCount - 1 do
       if not MDIChildren[I].CloseQuery then Exit;
 end;

 Result := True;
 if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);
end;
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#10
Son yazdığınızda fsMDIForm için FOnCloseQuery her halükarda 2 kez çalışır gibi gözüküyor  Huh

Düzeltiyorum Smile
FOnCloseQuery'den False dönerse yada MDIChildCount sıfır ise yada MDIChild'larda CloseQuery kullanılmamışsa...
There's no place like 127.0.0.1
WWW
Cevapla




Konuyu Okuyanlar: 1 Ziyaretçi