![]() |
FormClose erzeugt Exception - Washalb?
Moin, Moin,
bin gerade auf folgendes (mir unverständliches) Phänomen gestoßen: Auf der Main-Form wird mittels CheckBox eine neue Form geöffnet bzw. geschlossen:
Delphi-Quellcode:
In dieser Trace_Frm wird auf das Ereignis Close eine Liste freigegeben (die zuvor erzeugt wurde):
IF CheckBox1.Checked THEN Trace_Frm.Show;
IF NOT CheckBox1.Checked THEN Trace_Frm.Close;
Delphi-Quellcode:
Das Öffnen/Schliessen der Form funktioniert genau zweimal -- beim zweiten "unchecken" der CheckBox und dem Versuch die From zu schliessen wird eine Exception gefeuert: EInvalidPointer 'Ungültige Zeigeroperation'
procedure TTrace_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin Trace_List.Free; end; Was stimmt mit meinem Öffnen/Schliessen Mechanismus nicht? Jemand eine Idee? Dankeschön Gruß Jazzman |
Re: FormClose erzeugt Exception - Washalb?
Es gehört zusammen: Show/Hide und Create/Close. Show löst kein OnCreate aus, OnClose gibt aber deine Listen frei. (Eigentlich gehört Create zu Free bzw. Destroy (welches man nicht selbst aufrufen sollte), aber Close löst eben OnClose aus. Ich würde das Freigeben einfach aus dem OnClose ins OnDestroy schieben, und du kannst so weiter machen :))
|
Re: FormClose erzeugt Exception - Washalb?
Merci!
Gruß Jazzman |
Re: FormClose erzeugt Exception - Washalb?
Menno....
Zitat:
Delphi-Quellcode:
IF CheckBox1.Checked THEN
Trace_Frm.Show ELSE Trace_Frm.Close; |
Re: FormClose erzeugt Exception - Washalb?
oder gleich:
Delphi-Quellcode:
was in vorliegendem Fall wohl genau den gleichen Effekt haben sollte wie die bisherige Variante.
Trace_Frm.visible := Checkbox1.checked;
Aber das fehlende "else" hat mich auch sofort angesprungen. |
Re: FormClose erzeugt Exception - Washalb?
Das hier ist dein "Todesurteil":
Delphi-Quellcode:
Das Objekt wird freigeben, obwohl nach .Free noch weitere Methoden aufgerufen werden (unsichtbar von der VCL).
procedure TTrace_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin Trace_List.Free; end; Es hängt vom Zufall bzw. vom Stack ab, wann und wo es knallt. Deshalb gibt es die Methode Release.
Delphi-Quellcode:
Release wartet bis alle Windows-Botschaften verarbeitet wurden und gibt dann erst (verzögert) das Formular frei.
procedure TTrace_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin Release; // kann gefahrlos aufgerufen werden end; |
Re: FormClose erzeugt Exception - Washalb?
Noch ein Grund es ins OnDestroy zu packen :)
Das mit dem else stach mir auch direkt ins Auge, war für das Problem jetzt aber nicht wirklich von Belang - es ist streng genommen nichtmal falsch, nur ausgesprochen unglücklich und in den eher unteren Stil-Rängen anzusiedeln. |
Re: FormClose erzeugt Exception - Washalb?
Zitat:
Trace_List ist nicht das Formular, ansonsten hättest du da recht :mrgreen: Der Fehler ist, dass das Object Trace_List in OnCreate erzeugt wird um im OnClose geschmissen wird. Und beim nächsten Anzeigen des Formulars ist das Object Trace_List halt nicht da ... Ob das Free wirklich in OnDestroy gehört hängt ja von der Logik ab ... allerdings rein logisch betrachtet gehört es da hin :mrgreen: Ist also von daher ein Design-Fehler, das so aufzubauen. Um ganz sicher zu gehen, kann man das Formular auch immer zur Laufzeit erzeugen, dann ist das immer ganz frisch. Solange man mit dem Ein- Ausblenden des Formulars keine Lauflicht bauen will, ist der Performance-Verlust auch vernachlässigbar. Zudem aast man nicht so mit dem RAM rum. cu Oliver |
Re: FormClose erzeugt Exception - Washalb?
Zitat:
Delphi-Quellcode:
Jede Zeile, die mit *** markiert ist greift auf das Formular Objekt zu.
procedure TCustomForm.Close; // aus der VCL
var CloseAction: TCloseAction; begin if fsModal in FFormState then ModalResult := mrCancel else if CloseQuery then begin if FormStyle = fsMDIChild then if biMinimize in BorderIcons then CloseAction := caMinimize else CloseAction := caNone else CloseAction := caHide; DoClose(CloseAction); // hier wird das Event OnClose aufgerufen if CloseAction <> caNone then if Application.MainForm = Self then Application.Terminate // ??? else if CloseAction = caHide then Hide // *** else if CloseAction = caMinimize then WindowState := wsMinimized // *** else Release; // *** end; end; Aber das Objekt ist ja schon freigeben und deshalb kann es in jeder dieser Zeilen zu einer Zugriffsverletzung kommen. Bei der Zeile markiert mit ??? bin ich mir selbst nicht sicher, aber auch hier besteht potentiell die Gefahr, dass über verschlungene Wege auf das (freigebene) Formular Objekt zugegriffen wird. |
Re: FormClose erzeugt Exception - Washalb?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz