![]() |
Welchen Sinn macht dieser Code?
Vielleicht liegt es daran, dass ich Formulare selten erst zur Laufzeit erzeuge oder weil ich noch nicht richtig wach bin, aber ich verstehe den tieferen Sinn des Beispiels nicht. Der ist vermutlich schon vorhanden.
Delphi-Quellcode:
Form2 ist in Liste der verfügbaren Formulare. Zuerst stelle ich mir die Frage: warum? Wenn der Programmierer es sofort in Create von Form1 erzeugt, dann hätte man es auch direkt einbinden können. Um das Formular anzuzeigen braucht man nicht den Code in Button1Click, das würde auch so gehen. Einfach Form2.ShowModal.
procedure TForm1.FormCreate(Sender: TObject);
begin Form2 := TForm2.Create(Self); end; procedure TForm1.Button1Click(Sender: TObject); begin Form2 := TForm2.Create(Application); Form2.ShowModal; Form2.Release; end; Betrachten wir das anders, Form2 wird nur gelegentlich benötigt. Somit macht der Code in Button1Click Sinn, wozu dann aber der Part in FormCreate? Und wenn wir schon dabei sind, wieso einmal TForm2.Create(Self) und einmal TForm2.Create(Application)? //EDIT: Was ich noch vergessen habe zu sagen: natürlich wird in FormCreate von Form2 etwas erledigt was für Form1 auch wichtig ist, aber kann es es sein dass der Programmierer einfach nur vergessen hat das Fenster danach wieder frei zu geben? Es also keinen tieferen Sinn macht? |
AW: Welchen Sinn macht dieser Code?
Die Sache mit dem Owner hast du aber verstanden?
Create(Self) besagt, daß hier Form1 der Owner ist und wenn Form1 freigegeben wird, dann wird dvon auch Form2 freigegeben. Ich hoffe nur, daß hier die Variable Form2 auch eine Private der Form1 ist und nicht die Globale. :evil: Und beim Anderen ist die Application der Owner, womit das freigegeben würde, wenn die Anwendng beendet wird. Rein formal wäre es hier aber auch besser das Self zu übegeben, da die Form2 dort ja nur aktiv ist, solange es Form1 gibt, bzw. nur solange der Button-Klick ausgeführt wird. Womit man das auch eigentlich nil lassen könnte, da die Form ja manuell freigegeben wird und sich "eigentlich" kein anderer um die Freigabe kümmern müsste. Da man dort aber den Resourcenschutzblock vergessen hat, kümmert sich dann die Applikation um die Freigabe, wenn es im ShowModal knallt (Exception), was schnell passiert, wenn z.B. TForm2.Visible=True ist.
Delphi-Quellcode:
Und auch da ist wieder der Schrott mir der globalen Variable, denn die Form wird hier nur lokal erstellt und gleich wieder freigegeben.
procedure TForm1.Button1Click(Sender: TObject);
var Form2: TForm2; begin Form2 := TForm2.Create(Application); // Hier eigentlich besser Self, da eine Methode Dieses ja das Ding erstellt und freigibt. Oder nil, da es manuell freigegeben wird und kein Owner nötig ist. try Form2.ShowModal; finally Form2.Release; // Das ist fast sowas wie Form2.Free; nur daß beim Free die Form sofort freigegeben wird und beim Release erst später, wenn das Programm Lust dazu hat. end; end; PS: Man kann eine Form mehrfach erstellen und gleichzeitig anzeigen. Und gerade deswegen waren auch die bösen Kommentare zu der globalen Form2-Variable. Im TForm1.FormCreate wird deas Fenster einmal erstellt und in Button2.Click nochmal. Wenn man jetzt noch die automatische Erstellung im Projekt aktiv lässt, dann gibt es diese Form 2 bis 3 Mal. Wenn jetzt noch die globale Variable Form2 für alles verwendet wird, dann rate mal welche Form darin verlinkt ist und auf was man zugreift, wenn man diese benutzt. Tipp: Nach dem Buttonklick, steht da schrott drin, nämlich die veraltete Referenz auf die Form von dort, welche es nicht mehr gibt. Und dann noch das TForm2.Visible: Wenn das auf False steht dann wird die Instanz aus FormCreate nicht angezeigt, da dort das Show, bzw. Visible:=True fehlt. Und wenn das True ist, dann wird die Instanz aus FormCreate angezeigt, aber der Aufruf im Button1Click schlägt fehlt, denn eine sichtbare Form kann nicht Modal werden, weswegen auch der Hinweis auf den Resourcenschutzblock war, da dann die Form nicht mehr freigegeben wird. (Release wird ja nicht mehr ausgeführt) |
AW: Welchen Sinn macht dieser Code?
Eigentlich ist es ganz einfach was da passiert:
Delphi-Quellcode:
Nachdem dem Aufruf von
procedure TForm1.FormCreate(Sender: TObject);
begin // Erzeugen einer Instanz und die Referenz wird in Form2 gespeichert Form2 := TForm2.Create(Self); end; procedure TForm1.Button1Click(Sender: TObject); begin // Erzeugen einer Instanz und die Referenz wird in Form2 gespeichert Form2 := TForm2.Create(Application); Form2.ShowModal; Form2.Release; end;
Delphi-Quellcode:
haben wir also eine Instanz-Referenz in
TForm1.FormCreate
Delphi-Quellcode:
stehen.
Form2
Jetzt kommt der Aufruf von
Delphi-Quellcode:
und es wird eine neue Instanz erzeugt, die Referenz in
TForm1.Button1Click
Delphi-Quellcode:
gespeichert und am Ende wird die Instanz freigegeben.
Form2
Jeder Zugriff auf die Instan, deren Referenz in
Delphi-Quellcode:
steht, würde jetzt aber eine Zugriffsverletzung auslösen, denn diese Instanz wurde ja freigegeben.
Form2
Es dümpelt zwar irgendwo noch eine Instanz von
Delphi-Quellcode:
herum, aber wir haben ja - vorsorglich - die Referenz darauf vergessen (dann kann die auch nicht kaputt gehen) ;)
TForm2
Einen Memoryleak haben wir nicht, denn beim Beenden der Anwendung wird diese vergessene Instanz durch die Owner-Beziehung korrekt freigegeben. Nein, Sinn macht das ganze nicht, es sei denn, man möchte einfach nur Speicher belegen. EDIT: Hier mal eine kleine Erweiterung
Delphi-Quellcode:
Nach dem Start einfach mal auf den Button2 klicken und wunderbar, es funktioniert.
type
TForm1 = class( TForm ) Button1 : TButton; Button2 : TButton; procedure FormCreate( Sender : TObject ); procedure Button1Click( Sender : TObject ); procedure Button2Click( Sender : TObject ); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1 : TForm1; implementation {$R *.dfm} uses Unit2; procedure TForm1.Button1Click( Sender : TObject ); begin Form2 := TForm2.Create( Application ); Form2.ShowModal; Form2.Release; end; procedure TForm1.Button2Click( Sender : TObject ); begin Form2.ShowModal; end; procedure TForm1.FormCreate( Sender : TObject ); begin Form2 := TForm2.Create( Self ); end; Jetzt auf Button1 (geht auch) und dann wieder auf Button2 -> Zugriffsverletzung (wie zu erwarten) EDIT2: Und korrekterweise sollte das dann so aussehen:
Delphi-Quellcode:
procedure TForm1.Button3Click( Sender : TObject );
var LForm : TForm2; begin // wozu einen Owner, wenn wir es eh wieder freigeben wollen? // die Referenz in einer lokalen Variable speichern // try..finally um die Instanz gesichert wieder freizugeben LForm := TForm2.Create( nil ); try LForm.ShowModal; finally LForm.Free; end; end; |
AW: Welchen Sinn macht dieser Code?
Zitat:
Danke für die Erklärungen. |
AW: Welchen Sinn macht dieser Code?
Hallo,
kurz und knapp. Der Code macht keinen Sinn. Heiko |
AW: Welchen Sinn macht dieser Code?
Zitat:
Aber dann nicht auf der selben Variable und mit ein paar weiteren Änderungen. |
AW: Welchen Sinn macht dieser Code?
Ok, ich hab mir den Code jetzt weiter angesehen. In FormCreate von Form2 steht nur eine Zeile mit einer Prozedur. In der Prozedur werden einige Daten von Form1 an Form2 übergeben. Form2 ist ein Optionsfenster. Somit ergibt die Zeile
Delphi-Quellcode:
in FormCreate von Form1 sowieso keinen Sinn.
Form2 := TForm2.Create(Self);
Das Ganze macht erst Sinn in Button1Click, da da auch Informationen von Form2 an Form1 zurück fließen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:31 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 by Thomas Breitkreuz