![]() |
Delphi-Version: 7
Form soll sich selbst zerstören
Hallo,
ich möchte, dass sich mein Form im OnClose-Eventhandler selbst zerstört. Ich denke, das geht so:
Delphi-Quellcode:
Das scheint auch zu funktionieren, aber:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin Release; end; Wie finde ich heraus, ob die Form noch da ist oder schon geschlossen wurde und sich zerstört hat??? So gehts jedenfalls nicht:
Delphi-Quellcode:
Nach release bleibt der Zeiger Form2<>NIL, die Form ist aber nicht mehr im Speicher, d.h. bei erneutem Button1Click folgt unweigerlich die Access Violation.
procedure TForm1.Button1Click(Sender: TObject);
begin if Assigned(Form2) then begin ShowMessage('Form 2 exists, opening...'); Form2.Visible:=true; Form2.BringToFront; end else begin ShowMessage('Form 2 does not exist, creating...'); Form2:=TForm2.Create(self); Form2.Visible:=true; Form2.BringToFront; end; end; Wie löse ich das? |
AW: Form soll sich selbst zerstören
Was stört dich am Standard:
Action := caFree; ? |
AW: Form soll sich selbst zerstören
Schonmal in der Hilfe von Delphi 7 nachgeschaut, wofür der Parameter
Delphi-Quellcode:
an die Procedur FormClose übergeben wird?
var Action: TCloseAction
Zitat:
Delphi-Quellcode:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin Action := caFree; end; |
AW: Form soll sich selbst zerstören
Einfach mal so aus dem Bauch heraus
Delphi-Quellcode:
if ((Form2 <> nil) and (Assigned(Form2))) then
|
AW: Form soll sich selbst zerstören
Die Selbstzerstörung besser so:
Delphi-Quellcode:
Und um herauszufinden, ob das Form2 existiert wäre es besser dieses in Screen.Forms zu suchen.
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin Action := caFree; end;
Delphi-Quellcode:
nur hingetippt, nicht getestet!
procedure TForm1.Button1Click(Sender: TObject);
var F: TForm; I: Integer; begin for I := 0 to Screen.FormCount - 1 do begin F := Screen.Forms[I]; if F is TFrom2 then begin ShowMessage('Form 2 exists, opening...'); F.Visible:=true; F.BringToFront; Exit; end; end; ShowMessage('Form 2 does not exist, creating...'); F:=TForm2.Create(self); F.Visible:=true; F.BringToFront; end; Die Variable Form2 würde ich löschen. |
AW: Form soll sich selbst zerstören
Und ob das Form da ist:
Delphi-Quellcode:
Ist IMO sicherer als über eine Variable...
function FormExists(AFormClass: TFormClass): Boolean;
Var I: Integer; begin Result := False; for I := 0 to Screen.FormCount - 1 do if (Screen.Forms[I].ClassType = AFormClass) then begin Result := True; Exit; end; end; // Aufruf: if FormExists(TForm2) then ... |
AW: Form soll sich selbst zerstören
Zitat:
Zitat:
Zitat:
Danke! P.S. Das Problem liegt meistens zwischen den Ohren! Es gibt gar kein Problem. Ich hatte Form2 nochmal in unit1 deklariert, drum wurde der nie auf NIL gesetzt, schön blöd... |
AW: Form soll sich selbst zerstören
Wenn ein Objekt sich selbst freigibt, dann darf es außerhalb keine Variablen geben, welche darauf zeigen, bzw. niemand darf mehr darauf zugreifen.
Ausnahme: Das Objekt setzt selbstständig diese (globale) Variable z.B. im Destructor auf NIL, womit dann Prüfungen alla Assigned überhaupt erst funktionieren können. z.B. im TForm.Destroy ein
Delphi-Quellcode:
oder
Form2 := nil;
Delphi-Quellcode:
if Form2 = Self then Form2 := nil;
Alternativ kann man bei TForm TCustomForm auch im globalen ![]() Seit einer Weile gäbe es auch das ![]()
Delphi-Quellcode:
, wo Delphi die Variable automatisch auf NIL setzt, wenn das Objekt freigegeben würde, aber Dieses funktioniert nicht überall, bzw. es ist nötig, dass für die jeweilige Platform z.B. ARC vorhanden ist.
var [weak] X: TObject;
![]() Zitat:
und es funktioniert nicht, wenn die Variable auf etwas zeigt, was es aber dort nicht mehr gibt. |
AW: Form soll sich selbst zerstören
Man muss sich bei der Benutzung der globalen Form-Variablen immer vor Augen halten, dass diese immer nur auf eine Instanz zeigen kann, auch wenn mehrere davon existieren. Wenn man also die Variable Form2 mit nil belegt, hat man möglicherweise die falsche Instanz erwischt und wundert sich anschließend.
|
AW: Form soll sich selbst zerstören
Ich zerstöre in so einem Fall die Form immer extern, d.h. die Form schickt eine 'Zerstörungsanfrage' per Message an ihren Owner und verlässt Close mit action = caNone. Für den Fall, dass der Owner nicht mehr existiert, wird mit action = caFree reagiert.
Daraufhin wird die Form von extern zerstört (der handle muss ja dort vorhanden sein, sonst macht das ganze keinen Sinn) und der Handle auf nil gesetzt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:21 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