AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi MDIChild schließen und sofort wieder öffnen
Thema durchsuchen
Ansicht
Themen-Optionen

MDIChild schließen und sofort wieder öffnen

Ein Thema von Tenobaal · begonnen am 17. Okt 2013 · letzter Beitrag vom 17. Okt 2013
Antwort Antwort
Tenobaal

Registriert seit: 9. Mai 2013
21 Beiträge
 
Delphi XE5 Professional
 
#1

MDIChild schließen und sofort wieder öffnen

  Alt 17. Okt 2013, 14:03
Delphi-Version: 2007
Hallo Community.
Seit TAGEN sitze ich an dem Problem im Zusammenhang mit dem Schließen und Öffnen von MDIChildren eines Hauptformulars.
Ich habe drei Funktionen/Prozeduren (teilweise hier aus dem Forum) zu meinem Hauptformular hinzugefügt:
  • function TForm_Main.IsFormOpen(Form:TForm) -> Überprüft, ob das Formular "Form" bereits existiert
  • procedure TForm_Main.CloseAllForms; -> Schließt alle Formulare (aber keine MDIChilds) mit Ausnahme des Hauptformulars
  • procedure TForm_Main.CloseAllMDIChilds; -> Schließt alle aktiven MDIChilds

Im folgenden sollen nun über das OnClick-Event des Buttons2 sämtliche Formulare und MDIChilds geschlossen werden. Im OnClick-Event werden deshalb die Proceduren CloseAllForms() und CloseAllMDIChilds() aufgerufen. Danach wird mit IsFormOpen() zu Testzwecken überprüft, ob dass MDIChild FormViewerConfig existiert.

Problem:
Nachdem CloseAllMDIChilds() ausgeführt wurde, werden die MDIChilds nicht SOFORT zerstört, sondern erst nach dem das Button2Click()-Event ausgeführt wurde. Das liegt wohl daran, dass CloseAllMDIChilds() nur das OnClose-Event der Formulare aufruft, aber diese nicht direkt zerstört. Erst nachdem Button2Click()-Event ausgeführt wurde sind diese tatsächlich zerstört und nicht mehr unter Screen.Forms aufgeführt. Wie kann ich die MDIFormulare SOFORT zerstören, aber trotzdem nicht auf das OnClose-Event verzichten?


Delphi-Quellcode:
//Funktion prüft, ob das Formular bereits existiert
function TForm_Main.IsFormOpen(Form:TForm): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := Screen.FormCount - 1 DownTo 0 do
    if (Screen.Forms[i] = Form) then
    begin
      Result := True;
      Break;
    end;
end;

//Alle Formulare schließen (Ausnahme MDIChild und Form_Main)
procedure TForm_Main.CloseAllForms;
var
  i: Integer;
begin
  for i := Screen.FormCount - 1 DownTo 0 do
    Begin
      If Not(Screen.Forms[i] = Form_Main) And (Screen.Forms[i].FormStyle <> fsMDIChild) then
      Begin
      Screen.Forms[i].Close;
      End;
    End;
end;

//Alle MDIChilds schließen
procedure TForm_Main.CloseAllMDIChilds;
var
  i: Integer;
begin
  For I := Self.MDIChildCount-1 downto 0 do
  Begin
  Self.MDIChildren[I].Close;
  End;
end;


procedure TForm_Main.Button2Click(Sender: TObject);
begin
  CloseAllForms; //Alle Forms schließen
  CloseAllMDIChilds; //Alle MDIChilds schließen
  If NOT IsFormOpen(FormViewerConfig) then
    Begin
    FormViewerConfig:=TFormViewerConfig.Create(Application, MyMotor);//Formular FormViewerConfig ist weiterhin aktiv, obwohl FormViewerConfig.Close() bereits ausgeführt wurde. Neue Instanz von FormViewerConfig wird nicht erzeugt.
    End;
End;
Nachtrag:
Wenn ich die Prozedur CloseAllMDIChilds() mit der Zeile "Self.MDIChildren[I].Free;" ergänze wird das MDIChild zerstört. Aber dieses Vorgehen sorgt bestimmt für Probleme, weil Self.MDIChildren[I].Close; auch Free() aufruft, nur zu einem späteren Zeitpunkt?!?

Delphi-Quellcode:
//Alle MDIChilds schließen
procedure TForm_Main.CloseAllMDIChilds;
var
  i: Integer;
begin
  For I := Self.MDIChildCount-1 downto 0 do
  Begin
  Self.MDIChildren[I].Close;
  Self.MDIChildren[I].Free;
  End;
end;

Geändert von Tenobaal (17. Okt 2013 um 14:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.024 Beiträge
 
Delphi 12 Athens
 
#2

AW: MDIChild schließen und sofort wieder öffnen

  Alt 17. Okt 2013, 16:22
Bei dem Close wird dem Form i.A. lediglich eine Message CM_RELEASE per PostMessage in die Message-Queue gestellt. Erst wenn das Form diese Message verarbeitet wird das Free aufgerufen.

Rufst du direkt nach dem Close ein Free auf, erreichst du im Prinzip das gleiche. Die CM_RELEASE Message in der Queue ist dann nicht mehr relevant (ich weiß jetzt nicht, ob die Message entfernt wird oder ob sie einfach ins Leere läuft, weil das Fenster nicht mehr da ist).

Disclaimer: ich kann das jetzt eigentlich nur für XE5 sagen, aber ich denke, daß ist in D2007 genauso.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#3

AW: MDIChild schließen und sofort wieder öffnen

  Alt 17. Okt 2013, 18:38
Do könntest auf Deinem Template im FormClose-Event Action mit caFree belegen. Z.B.
Delphi-Quellcode:
procedure TTemplate.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Formstyle = fsMDIChild then
    Action := caFree;
end;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.024 Beiträge
 
Delphi 12 Athens
 
#4

AW: MDIChild schließen und sofort wieder öffnen

  Alt 17. Okt 2013, 18:57
Do könntest auf Deinem Template im FormClose-Event Action mit caFree belegen.
Das hilft aber nicht. Es wird trotzdem Release aufgerufen, was wiederum das PostMessage ausführt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  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 20:38 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