Einzelnen Beitrag anzeigen

nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: dynamisch erzeugte Forms richtig freigeben

  Alt 1. Jul 2015, 18:01
Hello

Da hast du ja einen ganz schönen Brocken bekommen ...

Warum das "Nil" der SpeicherverzeichnisOberfläche, wenn er es erst danach erzeugt? Warum kein "if not Assigned" wie unten beschrieben? Oder ist das nur Programmiererspezifisch?
Ich vermute, dass frmSpeicherverzeichnis entweder eine globale Variable oder ein Property von TfrmSplash ist. Also existiert die Variable über den ganzen Programmablauf. Und er wollte damit wohl sicherstellen, dass der Programmablauf in der nachfolgenden Schleife nicht blockiert wird, wenn Speicherverzeichnis schon gesetzt wurde.

Weiterhin sieht es so aus, als ob er hier ein ShowModal "simuliert". Das lässt der darunterliegende Block vermuten:
Delphi-Quellcode:
while assigned(frmSpeicherverzeichnis) do
  begin
    Application.ProcessMessages;
  end;
Das ist sehr unsauber, da es den gesamten restlichen Programmablauf in der Schleife blockiert.

Warum er hier nicht einfach ...
Delphi-Quellcode:
if Speicherverzeichnis='then
  begin
    frmSpeicherverzeichnis := TfrmSpeicherverzeichnis.Create(Self);
    frmSpeicherverzeichnis.ShowModal;
  end;
... verwendet, kann ich aus dem Code jedoch nicht ersehen.

Warum das "self.hide" seiner Startoberfläche? Da sind keine Elemente/ Objekte, die er nochmal benutzt.
Ich vermute, dass er hier das Elternformular (frmSplash ) verstecken will?

Genauso auch hier:
Delphi-Quellcode:
procedure TfrmStartseite1B.btnOptionenClick(Sender: TObject);
begin
  if not Messung.MessungLaeuft then
  begin
    Application.CreateForm(TfrmOptionen, frmOptionen);
    frmOptionen.show;
    self.Enabled:=False;
  end
    else
    begin
      Application.MessageBox('Das Fenster kann nur aufgerufen werden, wenn ' +
        'aktuell keine Messung läuft.', 'Achtung', mb_OK + mb_ICONWARNING);
    end;
end;
Statt ...
Delphi-Quellcode:
Application.CreateForm(TfrmOptionen, frmOptionen);
frmOptionen.show;
self.Enabled:=False;
... kann man (theoretisch) auch ...
Delphi-Quellcode:
frmOptionen := TfrmOptionen.Create(Self);
frmOptionen.ShowModal;
... machen.

Ich habe im Forum so viel rausbekommen, dass ...
Form.close = Form.Visible := false
Jein, nicht ganz. Form.Close prüft über Form.CloseQuery , ob eine Form geschlossen werden kann. Wenn Form.CloseQuery CanClose := FALSE setzt, bleibt die Form offen.

Form.release = setzt eine Application. Message ab/ gibt aber nix frei
Richtig. Form.Release setzt eine Message in die MessageQueue, die "irgendwann" verarbeitet wird und erst dann wird das Fenster geschlossen.
Ich habe aber auch mal gelernt, dass man nicht mit Release arbeiten sollte.

Form.Free ist was anderes als Form.freeAndNil
Gibt es Form.FreeAndNil in Delphi 5 wirklich (noch)? Ich habe das jedenfalls hier nicht. Es gibt die Funktion FreeAndNil(var ObjectReference) , die eine übergebene Variable des Typs TObject nach dem Freigeben auf nil setzt. FreeAndNil macht also nichts anderes als ObjectReference.Free; ObjectReference := nil
Ist es wirklich sinnvol, die aufrufende Form immer Enabled:=false zu setzen?
Ohne den Rest zu kennen: Nein, sinnvoller wäre es, mit ShowModal zu arbeiten. Es sei denn es gibt zwingend Gründe, warum man das so machen müsste.

Auf manchen Seiten steht bei CloseQuery nur CanClose:=false und beim Abbrechen-Button aber nur close; !? da kann ich doch das CloseQuery weglassen oder?
Ich vermute, dadurch, dass der ursprüngliche Programmierer hier mit Release arbeit, er das CloseQuery "übergeht", um sicherzustellen, dass die Form nur dann geschlossen wird, wenn der Benutzer einen bestimmten Ablauf einhält. Zum Beispiel dass eine Form nicht über das [x] geschlossen werden darf, sondern nur über die zur Verfügung stehenden Buttons.

Mir wiederstrebt es irgendwie die Form nicht in sich selbst zu beenden (Form.CloseQuery)... ist das nicht sauberer
Wie schon gesagt: Wir kennen den Rest nicht und wissen auch nicht, was der Programmierer sich dabei gedacht hat. Aber ja, prinzipiell wäre es "sauberer", eine nicht mehr benötigte Form an der Stelle zu schliessen / freizugeben, wo sie ihren Zweck erfüllt hat.

reicht es nicht (so hab ich es bisher gemacht ... bin kein Programmierer):
Delphi-Quellcode:
procedure TfrmMomentanwerte.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
     frmMomentanwerte.Release;
     frmMomentanwerte := nil;
end;
CloseQuery sollte nur am Ende CanClose setzen. Sonst nichts anderes.

Wenn es eine globale Variable frmMomentanwerte gibt, die unbedingt auf nil gesetzt werden muss, dann sollte das entweder in OnClose oder OnDestroy passieren.

Lange Rede, kurzer Sinn: Das was der ursprüngliche Programmierer da gemacht hat, erscheint mir recht unsauber und "brachial". Aber wie schon gesagt, er wird scheinbar seine Gründe dazu gehabt haben. Jedoch denke ich, dass man das Ganze viel eleganter löser kann, indem man die Formen-Logik nochmal überdenkt und an vielen Stellen ShowModal benutzt.

Geändert von nuclearping ( 1. Jul 2015 um 18:05 Uhr)
  Mit Zitat antworten Zitat