AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Ist Fenster schon geschlossen?! (speziell: MDI-Fenster)
Thema durchsuchen
Ansicht
Themen-Optionen

Ist Fenster schon geschlossen?! (speziell: MDI-Fenster)

Ein Thema von s.h.a.r.k · begonnen am 7. Jan 2008 · letzter Beitrag vom 7. Jan 2008
Antwort Antwort
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#1

Ist Fenster schon geschlossen?! (speziell: MDI-Fenster)

  Alt 7. Jan 2008, 18:12
Hallo,

ich hoffe mit kann jemand weiterhelfen: ich hab bisher keinerlei Event oder Funktion gefunden, die genau dann ausgeführt wird, wenn ein Fenster (in meinem Fall ein MDI-Child) geschlossen wurde. Ich habe es bisher den folgenden, eher unsauberen Weg gewählt:

Beim OnCloseQuery des MDIs eine Methode in der MDI-Parent aufgerufen, die selbst wiederrum die OnClose des MDIs aufruft. Ich war hierbei in der Hoffungen, dass wenn OnClose abgeschlossen ist das MDIChild aus dem Speicher entfernt wurde und somit eben nicht mehr vorhanden ist.

Allerdings tritt genau an dieser Stelle ein Problem auf, denn selbst nach dem OnClose des MDIChilds exisitert das Child in MDIChildCount noch. Warum tut es das? Zugreifen kann ich nicht mehr darauf, da ich dann einen Zugriffsfehler erhalte. Wo liegt dann mein Problem? Ich hoffe ihr könnt mir hierbei helfen.

BTW(1): Ich kann das Projekt leider nicht hochladen, da zu viel dran hängt. Ihr wollte ja nicht gleich einen Server installieren, um mein Problem anhand des Projekts nachzuvollziehen *lach*

BTW(2): Gibt es eine Möglichkeit einen eigenen Handler (Fenstermanager) zu schreiben, der die folgenden (hoffentlich ohne nähere Beschreibung erklärenden) Methoden implementiert und dies so ziemlich automatisch macht, ohne, dass ich all zu viel Code dafür schreiben muss, d.h. ich will auch nicht aus dem Hauptformular, sowie auch nicht aus den MDIChilds, die entsprechende Funktion aufrufen müssen:
OnBeforeMDICreate
OnAfterMDICreate
OnMDIActivate
OnBeforeMDIClose
OnAfterMDIClose

Ich hoffe ihr versteh so in etwa was ich hiermit will

Mit freundlichen Grüßen
der haiiii
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: Ist Fenster schon geschlossen?! (speziell: MDI-Fenster)

  Alt 7. Jan 2008, 18:23
Zunächst mal wird mit folgendem Code ein MDI korrekt geschlossen:
Delphi-Quellcode:
procedure TMDI_Form.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if FormStyle = fsMDIChild then
     Action := caFree;
end;
Durch die If-Abfrage kann das MDI-Form auch leicht wieder in ein normales Form geändert werden, ohne dass man am Source viel ändern muss.

Beim Zugriff auf das Property MDIChildCount muss man schwer aufpassen !!
Folgender Code funktioniert nicht:
Delphi-Quellcode:
 // alle MDIs schliesen
 while MDIChildCount > 0 do
   MDIChildren[0].Close;
Dagegen funktioniert Folgendes:
Delphi-Quellcode:
var
  i : Integer;
begin
  for i := MDIChildCount -1 downto 0 do
    MDIChildren[i].Close;
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#3

Re: Ist Fenster schon geschlossen?! (speziell: MDI-Fenster)

  Alt 7. Jan 2008, 18:29
Zitat von shmia:
Zunächst mal wird mit folgendem Code ein MDI korrekt geschlossen:
Delphi-Quellcode:
procedure TMDI_Form.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if FormStyle = fsMDIChild then
     Action := caFree;
end;
Durch die If-Abfrage kann das MDI-Form auch leicht wieder in ein normales Form geändert werden, ohne dass man am Source viel ändern muss.
Das ist mir klar und stellt auch nicht das Problem dar.

Zitat von shmia:
Beim Zugriff auf das Property MDIChildCount muss man schwer aufpassen !!
Folgender Code funktioniert nicht:
Delphi-Quellcode:
 // alle MDIs schliesen
 while MDIChildCount > 0 do
   MDIChildren[0].Close;
Dagegen funktioniert Folgendes:
Delphi-Quellcode:
var
  i : Integer;
begin
  for i := MDIChildCount -1 downto 0 do
    MDIChildren[i].Close;
Genau hier steckt ja mehr oder weniger das Problem. Ich greife, nachdem ich eine Form geschlossen habe auf diesen Counter zu, wobei dieser eben noch die Form "enthält". Warum ist das allerdings so!? Ich denke, wenn ich ein OnClose einer Form aufrufe, danach dann den Counter abfrage, er doch eigentlich um 1 niedriger sein sollte als zuvor!?
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: Ist Fenster schon geschlossen?! (speziell: MDI-Fenster)

  Alt 7. Jan 2008, 18:52
Zitat von s.h.a.r.k:
Ich greife, nachdem ich eine Form geschlossen habe auf diesen Counter zu, wobei dieser eben noch die Form "enthält". Warum ist das allerdings so!? Ich denke, wenn ich ein OnClose einer Form aufrufe, danach dann den Counter abfrage, er doch eigentlich um 1 niedriger sein sollte als zuvor!?
Der Aufruf von [TForm].Close zerstört das Formular ja noch nicht, sondern caFree veranlasst den Aufruf von Release:
Delphi-Quellcode:
procedure TCustomForm.Release;
begin
  PostMessage(Handle, CM_RELEASE, 0, 0);
end;
Diese Message wird aber erst beim nächsten Application.ProcessMessages verarbeitet.
Also ist das Formular-Objekt noch nicht ganz vernichtet, aber im Prinzip schon zum Tode verurteilt.

Ich würde an deiner Stelle einen Callback Mechanismus einbauen:
Delphi-Quellcode:
procedure TMDI_Form.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if FormStyle = fsMDIChild then
   begin
     // sage dem Hauptformular Bescheid, dass ich (= das MDI-Child) geschlossen werden
     (Owner as TMainForm).MDIClosing(self);
     Action := caFree;
   end;
end;

procedure TMainForm.MDIClosing(f:TcustomForm);
begin
  // das Hauptformular erhält jetzt einen letzten Todesgruss von seinem sterbenden MDI-child
  // so hat man die volle Kontrolle über das Geschehen

  with f as TMDI_Form do
  begin
    if MenuItemAutosave.Checked and DataModified then // DataModified ist ein Property des MDI-Child
      SaveData; // SaveData ist eine Methode des MDI-Child
  end;
end;
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#5

Re: Ist Fenster schon geschlossen?! (speziell: MDI-Fenster)

  Alt 7. Jan 2008, 22:43
Das hatte ich ja schon, hat aber nicht zum gewünschten Ergebnis geführt, jedenfalls nicht so wie ich das haben wollte, muss es aber scheinbar doch so machen.

Hab mir auf der Heimfahrt gerade eben auch noch überlegt, dass ich mir eine eigene Containerklasse für die MDI-Forumlare bauen kann. Zudem bastle ich mir dann noch eine eigene TForm, in der ich dann spezielle Funktionen mit einbaue à la delete etc.

Hatte mir nur vorgestellt, dass es so etwas schon gibt, aber irgendwie ist dies scheinbar nicht so
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz