![]() |
Verständnisfrage VCL zu Application.CreateForm()
Hallo,
Bekanntlich sieht die Projektdatei von Delphi so aus:
Delphi-Quellcode:
Was geschieht eigentlich in CreateForm()?
program Project1;
uses Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. Wenn ich ein Formular zur Laufzeit erzeuge, schreibe ich:
Delphi-Quellcode:
Aber im Hauptprogramm (in der .dpr Datei) wird Application.CreateForm() aufgerufen. Leider werde ich aus dem VCL Quellcode nicht wirklich schlau. Ich könnte evtl gezielter fragen, wenn ich den Quellcode der Methode hier veröffentlichen könnte, weiß aber nicht, ob das erlaubt ist. Könnte ich den Quellcode hier auflisten, dann würde ich gezielt nach dem Sinn und Zweck der Methoden fragen.
procedure Irgendwas_das_eine_tForm_erzeugen_muss;
begin Form1 := TForm.Create(Application) // ... weiterer Quellcode end; Was also passiert in der CreateForm() Methode? Ich besitze Turbo Delphi und so auch den Quelltext der Unit Forms, in der auch die TApplication Klasse definiert ist. Kann bitte jemand in Pseudocode erkären, was in CreateForm() passiert. |
Re: Verständnisfrage VCL zu Application.CreateForm()
Hallo Delphifan2004,
ich vermute mal, CreateForm kapselt die sonst manuell ins Hauptprogramm zu schreibende Anweisungsfolge:
Delphi-Quellcode:
procedure Application.CreateForm();
begin Form1 := TForm.Create; Application.InsertComponent(Form1); if Assigned(Form1.OnCreate) then Form1.OnCreate; end; |
Re: Verständnisfrage VCL zu Application.CreateForm()
Du kannst jederzeit in die Quellen reinsehen (Drücke auf die Methode mit Strg+linke Maustaste!).
Neben dem Constructor der Form wird bspw. noch die Mainform gesetzt (zuerst erstelltes Formular). |
Re: Verständnisfrage VCL zu Application.CreateForm()
Demnach macht CreateForm sinngemäß das hier!
Delphi-Quellcode:
Der originale Quelltext sieht zwar anders aus, aber so habe ich den grunsätzlichen Ablauf bisher verstanden, abgesehen von den Windows spezifischen Aktivitäten (Handle zuweisen...)
procedure TApplication.CreateForm(AFormClass: TFormClass; var AForm: TForm);
var Instance: TComponent; begin Instance := AFormClass.Create(nil); AForm := TForm(Instance); end; Die Delphi Hilfe sagt mir, das NewInstance nicht direkt aufgerufen werden soll, sondern automatisch von Konstruktor aufgerufen wird. Dennoch erfolgt im Original ein direkter Aufruf. Warum ist das dort nötig? |
Re: Verständnisfrage VCL zu Application.CreateForm()
Hmmm, TApplication stammt von TComponent ab. Müsste da nicht noch ein InsertComponent folgen, damit die Ereignisweiterleitung funktioniert?
Nach meinem Verständnis der Ereignsverteilung in einem Programm müsste doch das Ereignis an alle in der Applikation enthaltenen Komponenten, die natürlich auf der Form Platziert sind, gesendet werden. Eine Komponente, die aktuell ausgewählte würde dann das Ereignis entgegen nehmen und verarbeiten. Die anderen Komponenten sehen das Ereignis zwar, tun aber nix, wenn das Ereignis ankommt. In TApplication.Run sehe ich die Prozedur HandleMessage, die für die Ereignisverteilung zuständig sein dürfte. Woher aber weiß Windows, welche Komponenten auf meinem Formular sind? In TApplication.CreateForm() keine InsertComponent() Methode??? In TApplication.Run die Methode HandleMessage, die die Methode Idle aufruft. Aber ich kann in den Methoden nirgendwo erkennen, wo die Messages gezielt an die aktuell in der MainForm eingefügten Komponenten gesendet werden. Windows muss doch irgendwoher wissen, wohin die Messages gesendet werden müssen. Wer kann hier weiter helfen? |
Re: Verständnisfrage VCL zu Application.CreateForm()
Um die ursprüngliche Frage zu klären: TApplication.CreateForm anstatt vom einfachen Konstruktoraufruf erfüllt zwei Zwecke: Erstens wird, falls gerade das allererste Formular erstellt wird, das Mainform gesetzt. Zweitens wird die Schlamperei von einigen Delphi-Programmierern unterstützt. Letzteres kommt so:
Wenn ich MyForm := TMyForm.Create(Application) aufrufe, wird mit dem Aufruf des Konstruktors auch das OnCreate-Ereignis ausgelöst. Da der Konstruktor aber noch nicht zurückgekehrt ist, hat die Variable MyForm noch keinen neuen Wert erhalten, steht also gewöhnlich auf nil. Einige Programmierer verwenden allerdings statt Self gerne die Formular-Variable, was in OnCreate aus erwähntem Grund zu einem Fehler führt. Um das zu vermeiden, wird in CreateForm das Anfordern des Speichers und der Aufruf des Konstruktors getrennt: So erhält die Variable ihren Wert, bevor der Konstruktor aufgerufen wird und kann in OnCreate gefahrlos verwendet werden. @DualCoreCpu: Deine Vorstellung von Ereignissen ist falsch. Windows sendet Nachrichten an einen Thread. Der Thread erhält dann zusammen mit der Nachricht auch das Fenster, dem diese Nachricht gesendet werden soll. Die anderen Komponenten "sehen" die Nachricht also nicht. Der Thread kann dann Windows beauftragen, die Nachricht dem Fenster zur Bearbeitung zu überlassen (das MSDN-Stichwort wäre DispatchMessage). Windows muss nicht wissen, welche Nachrichten welchem Formular gehören. Windows arbeitet hier Thread-weise: TApplication.HandleMessage bearbeitet die Nachrichtenqueue des aktuellen Threads. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:52 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