Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   OnCloseQuery (https://www.delphipraxis.net/203731-onclosequery.html)

Willie1 17. Mär 2020 17:09

OnCloseQuery
 
Hallo Delphi-Freunde*innen,
ich habe in einem eigenen Prg in einem OnCloseQuery-Ereignis das Fenster mit der Frage "Beenden ? [Ok][Abbrechen]" nach bekannten Muster.
Wenn ich das Pgr offen lasse und Windows herunterfahre, kommt zu eine Warnung. Falls ich dann Windows nicht beende und dann [Abbrechen] klicke, läuft das Pgr. natürlich weiter.
Beende ich jetzt das Prg, öffnet sich nicht das oben genannte Fenster, sondern es kommt es zu einer Zugriffsverletzung und das Prg lässt sich nicht schließen.
Bevor ich hier etwas poste, wollte ich es eben nochmal ausprobieren und es war alles in Ordnung! Was zum Teufel ist da los? Die Zugriffsverletzung ist auch schon früher aufgetreten.

Genau das richtige zu Zeiten von Corona?!:)
Gruß und danke Willie.

Willie1 24. Mär 2020 16:53

AW: OnCloseQuery
 
Obwohl ich mich über eine Antwort gefreut hätte, ziehe ich meine Frage in diesen Corona-Zeiten zurück. Es gibt Wichtigeres.
Bleibt gesund Willie.

Redeemer 24. Mär 2020 16:56

AW: OnCloseQuery
 
Ohne Minimalbeispiel kann dir keiner helfen.

hoika 25. Mär 2020 07:31

AW: OnCloseQuery
 
Hallo,
Die Zugriffsverletzung ist auch schon früher aufgetreten.

-> MadExcept benutzen, um die Stelle zu finden.

Willie1 26. Mär 2020 16:27

AW: OnCloseQuery
 
Wie gesagt, der Fehler tritt nur gelegentlich auf und nur beim Herunterfahren von Windows, nicht beim normalen Beenden des Programms.

OnCoseQuery(CanClose...) symbolisch
begin
CanClose:=FrageBox('Progamm wirklich beenden?') = mrOK
if CanClose then
begin
hier schließe ich StringListen Objekte usw.
end
end

Der Fehler ist blöd, weil er sich nicht debuggen lässt und dann auch nur gelegentlich auftritt. Ist mir vielleicht auch nicht aufgefallen.
Willie.

hoika 26. Mär 2020 16:44

AW: OnCloseQuery
 
Hallo,
ahhhh

Zitat:

hier schließe ich StringListen Objekte usw.
Warum?
Dazu ist FormDestroy da.

Delphi.Narium 26. Mär 2020 17:54

AW: OnCloseQuery
 
Zitat:

Zitat von Willie1 (Beitrag 1460569)
Wie gesagt, der Fehler tritt nur gelegentlich auf und nur beim Herunterfahren von Windows, nicht beim normalen Beenden des Programms.

OnCoseQuery(CanClose...) symbolisch
begin
CanClose:=FrageBox('Progamm wirklich beenden?') = mrOK
if CanClose then
begin
hier schließe ich StringListen Objekte usw.
end
end

Der Fehler ist blöd, weil er sich nicht debuggen lässt und dann auch nur gelegentlich auftritt. Ist mir vielleicht auch nicht aufgefallen.
Willie.

Eigentlich ist klar, dass bei dieser Konstellation ein Fehler auftreten kann.

Grob in etwa sowas:

Windows soll beendet werden.
Das sagt den Programmen: Aufhören.
Die reagieren darauf und beenden sich.
Windows wartet ein bisserl.
Und dann kommt: Wer nicht hören will muss fühlen.
Sprich: Programme, die sich nicht selbst beenden, werden dann von Windows beendet.

Dein Programm bekommt von Windows gesagt: Aufhören.
Es fragt Dich dann: Wirklich? Darf ich auch?
Das dauert ggfls. ein bisserl.
Ggfls. länger, als Windows zu warten bereit ist.
Deshalb wird das nachfragende Programm von Windows beendet, während es noch auf die Antwort auf das "Darfichauch" warte. Kommt nun hier hinein das "Ja, Du darfst" seitens des Anwenders, ist nicht auszuschließen, dass die schon windowsseitig begonnen "Aufräumarbeiten" Teile dessen, was Du bei if CanClose wegräumen möchtest, nicht mehr existiert. Und dann hast Du den "Salat", äh, die Zugriffsverletzung

Bitte bedenke: Wenn Dein Programm beim Beenden nachfragt, ob es beendet werden soll oder nicht, was passiert, wenn in der Fragebox nicht mit mrOk geantwortet wird?
Windows wird das Programm trotzdem beenden, es sei denn, Du signalisiert Windows, dass es sich bitte nicht beenden soll und alle noch laufende Programm weiterlaufen dürfen.

Alternativ im OnCoseQuery abfragen, ob Windows beendet wird. Wenn ja, dann darf kein Dialog zur Abfrage auf ein Programmende erfolgen.

Eventuell hilft Dir dashier dabei: http://delphidabbler.com/tips/185

Und, wie Frühlingrolle schon richtig bemerkte:

Im OnCloseQuery wird gefragt, ob aufgehört werden darf oder eben auch nicht.

Im OnClose wird dann aufgeräumt, nicht in dem Ereignis, in dem nachgefragt wird.
Oder halt, wenn im FormCreate was erstellt wurde, wird das im FormDestroy weggeräumt. Nicht jedoch im OnCloseQuery.

Willie1 26. Mär 2020 18:16

AW: OnCloseQuery
 
Hallo Leute,

Delphi-Narium, das hast du prima erklärt! Danke.
ich habe verstanden. Das um zu bauen, ist ja nicht allzu schwierig.

Gruß Willie.

himitsu 26. Mär 2020 21:07

AW: OnCloseQuery
 
Und wenn die Form durch ein Free geschlossen wird, dann wird OnClose/OnCloseQuery nichtmal aufgerufen.

Statt einer MessageBox kann es besser sein hier einen Dialog auf Basis von TForm zu benutzen, denn sobald Application den Befehl für das Beenden bekommt, werden alle modalen Fenster geschlossen und dein Programm kann ohne Warten runterfahren.



Auch kann es nicht schaden auf die Message für das Beenden von Windows zu reagieren und benentsprechend zu steuern ob der Fragedialog überhaupt aufgehn soll.



Und nein, on OnClose/OnCloseQuery gibt man nichts frei, außer es wurde im OnShow erstellt,
wobei eben zu beachten ist, dass OnClose nicht immer aufgerufen wird, womit man in OnShow/OnClose niemals etwas erstellen/freigeben darf.
(außer man macht das Freigeben sowohl im OnClose als auch nochmal im OnDestroy, falls es noch nicht passiert war)

hoika 27. Mär 2020 03:32

AW: OnCloseQuery
 
Hallo
korrekt,
FormCreate: Erzeugen von Objekten
FormDestroy: Freigeben von Objekten

Auch im Sinne des folgenden Codes:
Delphi-Quellcode:
Form2:=TForm2.Create(Self);
Form2.TuWas;
Form2.Free;

hoika 27. Mär 2020 06:57

AW: OnCloseQuery
 
Hallo,
in meinem Bsp wird OnClose nicht aufgerufen.

Create -> Free (Destroy) wird immer aufgerufen
Create -> Close wird nicht immer aufgerufen

Und um gleichen Code zu haben, sollte man das OnDestroy nehmen.

Delphi.Narium 27. Mär 2020 09:11

AW: OnCloseQuery
 
Liste der Anhänge anzeigen (Anzahl: 1)
@Frühlingsrolle

Create wird beim Erstellen aufgerufen.

Close beim Schließen.

Beim Hauptformular führt das Schließen eines des Formulares auch zum Programmende.

Bei jedem weiteren Formular aber nicht.
Wenn ich dort also im Create was erstelle, das Formular öffne (show), irgendwas mache, es dann schließe, dort alles im Create erstellte im OnClose bzw. OnCloseQuery freigebe und es dann später mit einem Show wieder anzeige, kann das zu eher unschönen Effekten (Zugriffsverletzungen) führen.

Probier' das doch bitte einfach mal in einem Testprogramm mit mehreren Formularen aus. In allen Formularen, außer dem Hauptformular erstellst Du halt die Routinen für's Create und OnClose bzw. OnCloseQuery. Im Create erstellst Du Stringlisten oder sonstige Objekte, im OnClose bzw. OnCloseQuery gibst Du sie frei.

Ins Hauptformular machst Du mehrere Buttons, je Unterformular einen und dann zeigst Du beim Klick auf den Button mit Show jeweils das entsprechende Unterformular an. Wie oft funktioniert das ohne Fehlermeldung?

Wird beim Schließen des Hauptformulars OnCloseQuery der Unterformulare aufgerufen? Oder das OnClose der Unterformulare?

p80286 27. Mär 2020 10:41

AW: OnCloseQuery
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1460601)

Beim Hauptformular führt das Schließen eines Formulares auch zum Programmende.

Nur Beim Hauptformular führt das Schließen eines Formulares auch zum Programmende.

Ich hatte schon an meinen Kenntnissen gezweifelt. Im übrigen bin ich der Meinung Daten (z.B. Stringlisten) sind unabhängig von Formularen. Diese aufzuräumen muß irgendwo anders stattfinden. Vorzugsweise da wo sie verarbeitet werden.

Gruß
K-H

himitsu 27. Mär 2020 12:17

AW: OnCloseQuery
 
Weil es "besser" ist alles auf der Ebene freizugeben, wo es erstellt wurde.
OnShow->OnHide/Close
OnCreate->OnDestroy
Constructor->Destructor

Und wie mehrmals erwähnt, wird OnClose nicht immer aufgerufen, weswegen es sich für Freigaben garnicht eignet. (außer es gibt nochmal eine Freigabe im OnDestroy)

Delphi.Narium 27. Mär 2020 14:53

AW: OnCloseQuery
 
Zitat:

Zitat von p80286 (Beitrag 1460605)
Zitat:

Zitat von Delphi.Narium (Beitrag 1460601)

Beim Hauptformular führt das Schließen eines Formulares auch zum Programmende.

Das schließen des Hautpformulares führt zum Programmende.

Nur Beim Hauptformular führt das Schließen eines Formulares auch zum Programmende.

Ich hatte schon an meinen Kenntnissen gezweifelt. Im übrigen bin ich der Meinung Daten (z.B. Stringlisten) sind unabhängig von Formularen. Diese aufzuräumen muß irgendwo anders stattfinden. Vorzugsweise da wo sie verarbeitet werden.

Gruß
K-H

Wir meinen das Gleiche, nur habe ich wohl etwas sehr schwammig formuliert.

Nur beim Hauptformular führt das Schließen des eines HauptfFormulares auch zum Programmende.

Und die Stringliste in meinem Beispiel diente nur zur Verdeutlichung und zum Auslösen eines Fehlers. Sie war nicht als empfehlenswertes Vorgehen gedacht.

p80286 27. Mär 2020 21:18

AW: OnCloseQuery
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1460645)
Nur beim Hauptformular führt das Schließen des eines HauptfFormulares auch zum Programmende.

:thumb: That's it! :thumb:

Gruß
K-H

Willie1 28. Mär 2020 10:15

AW: OnCloseQuery
 
Hallo,
mir schwirrt jetzt der Kopf. Aufräumen (z.B. Stringlisten) des Hauptfenstern bei OnDestroy. Ist das eure Meinung?
Ob MeeageBox, ein selbst gebautes Fenster oder VistaTaskDialog ist übrigens gleich. Bei allen drei Konstrukten trat der von mir beschriebene Zugriffsfehler auf. Ich werde das Aufräumen verlegen.
Willie.

Delphi.Narium 28. Mär 2020 11:00

AW: OnCloseQuery
 
Jedenfalls nicht im OnClose oder OnCloseQuery.

Beide können beliebig oft oder aber auch garnicht aufgerufen werden.

Das Vorhandensein dieser beiden Routinen impliziert nicht deren Aufruf.

Oder:

Aufrufhäufigkeit von OnClose: 0:n
Aufrufhäufigkeit von OnCloseQuery: 0:n
Aufrufhäufigkeit von OnDestroy: 1

Was davon mag der sicherere Ort für das Aufräumen von Objekten sein?


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