Delphi-PRAXiS
Seite 1 von 8  1 23     Letzte »    

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/)
-   -   10.3.1: OnActivate wird vor OnCreate ausgeführt (https://www.delphipraxis.net/200117-10-3-1-onactivate-wird-vor-oncreate-ausgefuehrt.html)

Bbommel 21. Mär 2019 16:08

10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Hallo Lieblingsforum,

ich habe mir jetzt auch mal Delphi Rio Update 1 angesehen. Beim compilieren meiner Hauptanwendung ist mir dabei ein merkwürdiger und sehr lästiger Effekt aufgefallen: zur Initialisierung meiner Anwendung gibt es einigen Code im OnCreate und einiges im OnActivate des Hauptformulars der Anwendung. Im OnCreate werden einige essentielle Dinge initailisiert (Konfigurations-Objekte erzeugt, Konfiguration gelesen und ähnliches), im OnActivate werden dann, wenn man sich darauf verlassen kann, dass alle Komponenten und ggf. zusätzlichen Formulare erzeugt sind, ein paar visuelle Einstellungen vorgenommen (das passiert natürlich nur beim ersten Aufruf von OnActivate).

Auch wenn es manchem jetzt in den Fingern juckt, eine Bitte: die Frage ist jetzt nicht, ob das ein geschicktes Design ist. :-)

Diese Konstruktion funktioniert nun aber so, seitdem es die Anwendung gibt, also seit mittlerweile mehr als 12 Jahren und sie hat somit auch schon so einige Generationen Delphi gesehen. Nun habe ich mich beim Testen aber eben gewundert, dass die Anwendung nicht richtig initialisiert wurde. Der oberflächliche Grund war schnell gefunden: das Ereignis OnActivate wird vor dem Ereignis OnCreate ausgeführt - damit sind einige Objekte noch gar nicht vorhanden, auf die in OnActivate zugegriffen wird.

Wenn ich eine komplett neue und ansonsten leere Delphi-VCL-Anwendung erstelle und den beiden Ereignissen eine Funktion zuweise (in dem Fall ein einfaches ShowMessage), dann ist die Reihenfolge der Ereignisse korrekt - erst Create, dann Activate.

Es muss also auf meinem Formular irgendetwas geben, das dafür sorgt, dass das "Activate" zu früh getriggert wird. Ich habe versucht, ein bisschen durch die Delphi-Units (Vcl.Forms, Vcl.ComCtrls) zu debuggen, aber irgendwann steig ich dann doch nicht mehr durch die Magie der VCL durch - auf den obersten Ebenen konnte ich zwischen 10.2.3 und 10.3.1 jedenfalls keine offensichtliche Änderung am Code feststellen. Das muss also irgendwo in den Tiefen der VCL passieren.

Aus meiner Sicht ist das erst mal ein Bug. Denn unabhängig davon, was ich alles an Komponenten auf das Hauptfromular geknallt habe, darf das ja nicht dazu führen, dass ein OnActivate vor einem OnCreate ausgeführt wird - hier ist ja auch die Reihenfolge in der Doku eindeutig beschrieben.

Habt ihr eine Idee, wie ich dem Ganzen weiter auf die Spur kommen kann? Könnte ich irgendwo den Moment abfangen, wenn das Activate in die Event-Queue geschrieben wird (oder was auch immer die da machen - es ist jedenfalls kein trivialer Aufruf eines "DoActivate", sondern im Aufruf-Stack steht vorher ganz viel mit "WndProc)? Wenn es tatsächlich ein Bug ist, würde ich schon gerne eine bessere Idee haben, was ich an Emba melden soll.

Ich würde mich über ein bisschen Hilfe sehr freuen.

Delphi.Narium 21. Mär 2019 16:16

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Wo ist das Ereignis OnActivate zugewiesen?

Im Objektinspektor?

Wenn ja, schmeiß es da raus und mach die entsprechende Zuweisung als letzte Zeile ins OnCreate.

Wird's dann besser?

Und nein, das ist keine professionell und durchdachte Lösung, sondern nur so 'ne Idee für: Hoffentlich geht's ;-)

Der schöne Günther 21. Mär 2019 16:18

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Sich darauf zu verlassen dass
Delphi-Quellcode:
OnActivate
nach
Delphi-Quellcode:
OnCreate
kommt, was ist da schlimm dran?

Ich hätte auch gesagt, der erste Schritt wäre herauszufinden warum OnActivate zu früh getriggert wird (z.B. mittels Debugger).

Bbommel 21. Mär 2019 16:32

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Wie gesagt, ob das schön ist oder nicht, soll jetzt nicht unbedingt das Thema sein. :-) Aus meiner Sicht sollte ich mich aber darauf verlassen können, da die Reihenfolge der Ereignisse auch explizit in der Doku erwähnt wird.

Der Vorschlag, das OnActicate erst am Ende von OnCreate zu setzen, hilft leider auch nicht (was ich zugegebenermaßen schon befürchtet habe). In dem Fall wird as OnActivate einfach gar nicht mehr ausgeführt (weil das Ereignis ja schon durch ist).

Wichtiger Hinweis noch: wie ich gerade gemerkt habe, tritt der Effekt nur in meiner Test-VM auf (Win 8.1, VMware Workstation Player 12). Aber: das mit 10.2.3 kompilierte Programm tut auch in der VM problemlos, das mit 10.3.1 nicht. Beide getestet auch außerhalb von Delphi.

Kopiere ich das mit 10.3.1 erzeugte Programm aus der VM auf meinen normalen PC, dann läuft es.

Vielleicht grenzt das ja das Problem für jemanden etwas ein.

Ich bin jetzt erstmal weg, mir raucht etwas der Kopf und ich brauche frische Luft... :-)

Bbommel 21. Mär 2019 16:39

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Kleiner Nachtrag: wie ich zur Not einen Workaround basteln könnte mit einer Statusvariablen, die bemerkt, dass das OnActivate vor dem OnCreate ausgeführt wurde, ist eigentlich auch klar. Mir geht es aber wirklich darum, irgendwie die Ursache herauszufinden, denn das finde ich schon ein bisschen merkwürdig, dass das passiert. Wenn sich dabei herausstellt: ja, ist halt so und ist auch erlaubt so und bisher hatte ich einfach nur "Glück", dann wird korrigiere ich natürlich mein Programm. Aber irgendwie habe ich bisher noch immer den Eindruck, dass das eigentlich so nicht passieren darf.

hoika 21. Mär 2019 16:44

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Hallo,
10.3 Community klappt wie erwartet, FormCreate vor FormActivate.

Ich würde es mal mit einem neuen leeren Projekt testen.

Delphi.Narium 21. Mär 2019 16:53

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Anderer Vorschlag:

Zuweisung des OnActivate aus dem Objektinspektor raus.

Im OnCreate ans Ende zuerst den Aufruf der OnActivate-Methode und dann das Ereignis zuweisen.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender : TObject);
begin
  ...
  FormActivate(Sender);
  Self.OnActive := FormActivate;
end;

Bbommel 21. Mär 2019 16:57

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
@hoika: Danke für die Rückmeldung. In einem leeren Projekt klappt es bei mir auch problemlos - hatte ich im Ursprungspost auch schon geschrieben. :-)

@Delphi.Narium: Ja, das wäre wohl der einfachste Workaround. :thumb:

Aber ich würde immer noch gerne die Ursache verstehen und ob es wirklich ein Fehler von mir ist oder ein Bug in der VCL.

hoika 21. Mär 2019 20:32

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Hallo,
Zitat:

Aber ich würde immer noch gerne die Ursache verstehen und ob es wirklich ein Fehler von mir ist oder ein Bug in der VCL.
Wo ist das Problem?
Binde deine verwendeten Komponenten immer weiter ein und finde die, die Murks macht.

Zitat:

Wenn ich eine komplett neue und ansonsten leere Delphi-VCL-Anwendung erstelle und den beiden Ereignissen eine Funktion zuweise (in dem Fall ein einfaches ShowMessage), dann ist die Reihenfolge der Ereignisse korrekt - erst Create, dann Activate.
Das hatte ich in dem vielen Text übersehen, sorry.


Diverse Fremdkomponenten erzeugen OnActivate (WM_ACTIVATE) an Stellen,
wo man sie nicht erwartet.
Fang mal bei TMS (TXXXDateTimePicker) an und hangel dich durch DevExpress.

Trail and Error

Uwe Raabe 21. Mär 2019 20:59

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
 
Bist du sicher, daß es wirklich vor dem OnCreate aufgerufen wird oder eventuell auch innerhalb des OnCreate, noch bevor das fertig ist?


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:21 Uhr.
Seite 1 von 8  1 23     Letzte »    

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