Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi MDI Fenster schließt nicht richtig (https://www.delphipraxis.net/190595-mdi-fenster-schliesst-nicht-richtig.html)

Eppos 19. Okt 2016 12:43

MDI Fenster schließt nicht richtig
 
Hallo zusammen,

ich erstelle mehrere MDI Fenster innerhalb meiner Anwendung.
Code:
  Form1 := TForm1.Create(self)
Soweit so gut, es gibt nun MDI Forms, die durch Klicken von Buttons, die Form1 aufrufen sollen, jedoch zuvor geschlossen werden.
Bevor die Form aufgerufen wird, prüfe ich auf...
Code:
  If Form1 <> nil then begin
    Form1.Close;
    Form1 := nil;
  end;
und anschließend soll das Fenster so angezeigt werden...

Code:
  Form1 := TForm1.Create(self);
  Form1.FormStyle := fsNormal;
  Form1.Visible := False;
  Form1.ShowModal;
Funktioniert auch tadellos, jedoch heißt die Form "Form1_1"...
Ich vermute das das erste Fenster nicht richtig geschlossen wird.

Hat jemand eine Idee wie ich das "_1" unterbinden kann?

Gruß
Eppos

Uwe Raabe 19. Okt 2016 13:23

AW: MDI Fenster schließt nicht richtig
 
Ein
Delphi-Quellcode:
Close
schließt in der Regel lediglich das Form. Soll es gleichzeitig freigegeben werden, dann kann man im
Delphi-Quellcode:
OnClose
-Event die
Delphi-Quellcode:
TCloseAction
auf
Delphi-Quellcode:
caFree
setzen.

Eppos 19. Okt 2016 14:19

AW: MDI Fenster schließt nicht richtig
 
hm...

So steht es bereits drin
Code:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Form1 := nil;
end;
Noch ne Idee?

Jasocul 19. Okt 2016 14:32

AW: MDI Fenster schließt nicht richtig
 
Meinst du das?
Delphi-Quellcode:
Form1.Caption := 'Form1';

Eppos 19. Okt 2016 14:35

AW: MDI Fenster schließt nicht richtig
 
korrekt, also es steht dann
Code:
  Form1.Caption := 'Form1_1';
drin...

Uwe Raabe 19. Okt 2016 20:08

AW: MDI Fenster schließt nicht richtig
 
Der Code, der das
Delphi-Quellcode:
Form1.Close
aufruft und der das neue
Delphi-Quellcode:
TForm1.Create
macht, werden die direkt hintereinander ausgeführt? In dem Fall wird durch das
Delphi-Quellcode:
Close
selbst bei
Delphi-Quellcode:
caFree
das Form nicht sofort freigegeben. Vielmehr wird über
Delphi-Quellcode:
Release
eine Message in die Queue gestellt, die dann bei nächster Gelegenheit das Form freigibt.

Wenn das obige also der Fall ist, dann existiert während des erneuten
Delphi-Quellcode:
TForm1.Create
die alte Instanz noch und das führt zur Vergabe des neuen Namens.

Abhilfe: das
Delphi-Quellcode:
caFree
im FormClose-Event entfernen, ebenso wie das
Delphi-Quellcode:
nil
setzen. Dann noch das
Delphi-Quellcode:
Form1.Close
in ein
Delphi-Quellcode:
Form1.Free
abändern.

Jasocul 20. Okt 2016 06:09

AW: MDI Fenster schließt nicht richtig
 
Dann ergänze deinen Code doch:
Delphi-Quellcode:
  Form1 := TForm1.Create(self);
   Form1.FormStyle := fsNormal;
   Form1.Visible := False;
   Form1.Caption := 'Form1'; // Diese Zeile einbauen
   Form1.ShowModal;

Eppos 20. Okt 2016 09:51

AW: MDI Fenster schließt nicht richtig
 
@Uwe Raabe
Ich habe jetzt nur statt
Code:
Form1.Close
ein
Code:
Form1.Free
gesetzt.
Dann funktioniert es.

@Jasocul
Das erscheint mir eher das Problem vielleicht zu beheben, aber die Ursache bleibt vorhanden.
Trotzdem Danke, jedoch zu unsauber.

Aviator 20. Okt 2016 10:21

AW: MDI Fenster schließt nicht richtig
 
Zitat:

Zitat von Eppos (Beitrag 1351453)
@Jasocul
Das erscheint mir eher das Problem vielleicht zu beheben, aber die Ursache bleibt vorhanden.
Trotzdem Danke, jedoch zu unsauber.

Ohne Jasocul jetzt in den Rücken fallen zu wollen, aber das ist die richtige Einstellung. Immer schön alles freigeben was nicht mehr benötigt wird. Dann gibt es später auch keine Probleme.

Jasocul 20. Okt 2016 10:45

AW: MDI Fenster schließt nicht richtig
 
Mir fällt keiner in den Rücken :wink:

Das ist nicht unsauber.
Beim erfolgreichem Form1.Close mit Action = caFree, wird das Form1.Free nur nicht sofort ausgeführt (wie Uwe Raabe bereits angedeutet hat). Die Queue braucht da halt ein bisschen Zeit.

Im Grunde läuft das intern doch ganz anders ab:
Form1 ist nur irgendeine Instanz-Variable.
Die alte Form, die mit Close geschlossen wurde existiert noch in der Liste der Child-Forms der MDI-Hauptform.
Durch das Create zeigt die bisherige Instanz-Variable auf die neue Form. Die MDI-App prüft aber in der Liste, ob noch eine Form mit der automatischen Vergabe des Namens existiert. Da die Queue noch nicht abgearbeitet ist, gibt es da also noch eine (nämlich die alte Form). Auch wenn diese eigentlich geschlossen wurde/wird. Also wird eine neue Bezeichnung verwendet, damit das nicht durcheinander kommt.

Die Caption einer Form zur Laufzeit zu verändern, ist sicher nicht unsauber.

Übrigens könnte man das auch komplett ohne Instanz-Variable machen:
Delphi-Quellcode:
  with TForm1.Create(self) do
  begin
    FormStyle := fsNormal;
    Visible := False;
    Caption := 'Form1';
    ShowModal;
  end;
Aber ich bin kein großer Freund der with-Anweisung. Ich nehme auch immer lokale Instanz-Variablen. Man muss sich nur klar machen, dass die Instanz auch ohne die Variable existiert. Ein weiteres Create mit der selben Variablen, lässt diese nur auf die neue Instanz zeigen. Die vorherige Instanz ist trotzdem vorhanden.

Aviator 20. Okt 2016 11:01

AW: MDI Fenster schließt nicht richtig
 
Zitat:

Zitat von Jasocul (Beitrag 1351465)
Aber ich bin kein großer Freund der with-Anweisung. Ich nehme auch immer lokale Instanz-Variablen. Man muss sich nur klar machen, dass die Instanz auch ohne die Variable existiert. Ein weiteres Create mit der selben Variablen, lässt diese nur auf die neue Instanz zeigen. Die vorherige Instanz ist trotzdem vorhanden.

Ich auch nicht mehr. Hauptsächlich aus Gründen des Debuggings. :-D

Und wenn man sich die Instanz nicht irgendwo speichert, dann hat man u.U. ein schönes Speicherleck. :)
Habe allerdings keine Ahnung, wie das MDI technisch vom System verwaltet wird. Aber bei anderen Objekte wäre das der Fall.

himitsu 20. Okt 2016 11:23

AW: MDI Fenster schließt nicht richtig
 
MDI kümmert sich nur um die visuelle Darstellung (Parent usw.)
die Freigabe wird wie bei jeder anderen TForm behandelt, bzw. wie bei TComponent allgemein.

Zitat:

Zitat von Jasocul (Beitrag 1351465)
Beim erfolgreichem Form1.Close mit Action = caFree, wird das Form1.Free nur nicht sofort ausgeführt (wie Uwe Raabe bereits angedeutet hat). Die Queue braucht da halt ein bisschen Zeit.

Delphi-Quellcode:
MyForm.Close;
Application.ProcessMessages
MyForm := TMyForm.Create(Self);
...
OK, das geht aber dann doch eher Free statt Close oder halt mit 2 Forms leben.
Delphi-Quellcode:
MyForm.Free;
Application.ProcessMessages
MyForm := TMyForm.Create(Self);
...
Free hat aber ein "Problem", denn z.B. ein eventuell vorhandenes Event an OnCloseQuery wird nicht ausgeführt. (Free ist sofortiges Schließen ohne Rückfrage, samt Freigabe)

Aber warum eine Instanz des selben Form freigeben und eine neue Instanz erstellen, anstatt die bestehende Instanz wiederzuverwenden?

Jasocul 20. Okt 2016 11:25

AW: MDI Fenster schließt nicht richtig
 
Zitat:

Zitat von Aviator (Beitrag 1351469)
Und wenn man sich die Instanz nicht irgendwo speichert, dann hat man u.U. ein schönes Speicherleck. :)

Ist in diesem Fall kein Problem, da beim Schließen der Form ja dafür gesorgt wird, dass der Speicher freigegeben wird.

Eppos 20. Okt 2016 11:30

AW: MDI Fenster schließt nicht richtig
 
Mit unsauber meine ich...
Wenn Programmierer X den Namen der Form ändern muss, weis er nicht, dass es hier im Code oder an andererer Stelle eine Sonderlocke gibt.
In meinen Augen sehr gefährlich.

Jasocul 20. Okt 2016 12:01

AW: MDI Fenster schließt nicht richtig
 
@Himitsu:
Das Free wird in diesem Fall im OnClose aufgerufen. Das CloseQuery muss dann schon abgearbeitet sein. Passt also in diesem Fall noch.

@Eppos:
Welche Sonderlocke ist denn gefährlicher:
- Ein Free in einem Close-Event, welches eigentlich sowieso automatisch durchgeführt wird?
- Oder das Setzen einer Caption, was ein rein optischer Effekt ist?

Eppos 2. Nov 2016 13:00

AW: MDI Fenster schließt nicht richtig
 
@Jasocul
Als Sonderlocke meine ich das setzen der Caption, weil wir darüber weitere Funktionalitäten abbilden wie z.B.
-Formsettings
-Usersettings
-Sprachdaten
etc...


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:46 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