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/)
-   -   Verständnisfrage VCL zu Application.CreateForm() (https://www.delphipraxis.net/140968-verstaendnisfrage-vcl-zu-application-createform.html)

delphifan2004 29. Sep 2009 23:36


Verständnisfrage VCL zu Application.CreateForm()
 
Hallo,

Bekanntlich sieht die Projektdatei von Delphi so aus:

Delphi-Quellcode:
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Was geschieht eigentlich in CreateForm()?

Wenn ich ein Formular zur Laufzeit erzeuge, schreibe ich:

Delphi-Quellcode:
procedure Irgendwas_das_eine_tForm_erzeugen_muss;
begin
  Form1 := TForm.Create(Application)
  // ... weiterer Quellcode
end;
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.

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.

DualCoreCpu 30. Sep 2009 08:27

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;

sirius 30. Sep 2009 08:32

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).

delphifan2004 30. Sep 2009 15:39

Re: Verständnisfrage VCL zu Application.CreateForm()
 
Demnach macht CreateForm sinngemäß das hier!

Delphi-Quellcode:
procedure TApplication.CreateForm(AFormClass: TFormClass; var AForm: TForm);
var Instance: TComponent;
begin
  Instance := AFormClass.Create(nil);
  AForm := TForm(Instance);
end;
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...)

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?

DualCoreCpu 30. Sep 2009 16:19

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?

Apollonius 30. Sep 2009 20:22

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 10:27 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