Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Beim Programmstart werden alle Units abgearbeitet (https://www.delphipraxis.net/196379-beim-programmstart-werden-alle-units-abgearbeitet.html)

Mario61 16. Mai 2018 19:39

Beim Programmstart werden alle Units abgearbeitet
 
Hallo,

ich habe 3 Formulare (Form1, Form2, Form3) ebenfalls exitieren dazu die Units (Unit1, Unit2, Unit3)
In jedem Formular befindet sich ein ShowMessage('xyz'). Beim Starten des Programmes werden alle MessagesBoxes angezeigt, noch bevor das erste Formular angezeigt wird.

Warum ?
Wie kann man das verhindern ?
Ich möchte in jeder Unit / Formular eigene unabhängige Routinen definieren, die nicht gleich beim Programmstart ausgefürt werden sollen.
Was muss ich tun ?

KodeZwerg 16. Mai 2018 19:43

AW: Beim Programmstart werden alle Units abgearbeitet
 
Setz die Form.Visible Eigenschaft auf FALSE solange bis Du es mit TRUE anzeigen lässt.

Mario61 16. Mai 2018 20:03

AW: Beim Programmstart werden alle Units abgearbeitet
 
Hallo,

Ich habe in Form2 eine MessageBox die erscheinen soll wenn ich Form2 über einen Button in Form1 öffne. Ob Form2 Visible =TRUE oder FALSE ist, die MessageBox aus Form2 erscheint noch vor Form1. Damit wird die Routine show Messagebox aus Form2 schon vor dem Ansprechen von Form2 geöffnet. Warum? Form2 ist noch gar nicht dran ! Das darf doch so nicht sein, oder?

Macht doch einfach mal ein neues Projekt mit einem Formular, dort irgend ein Label mit irgend einem Text, dann ein zweites Formular und in diesem ein ShowMessage('YXZ').
Dann passiert das !!! Warum ?

Gruß Mario.

KodeZwerg 16. Mai 2018 20:21

AW: Beim Programmstart werden alle Units abgearbeitet
 
Geh in deine .dpr Datei, da nimm alle Forms raus die beim starten nicht erscheinen sollen inkl. deren Code.
In deinem Knopf für "Zeige FormX" da platziere eine FormX.Create().
Das ist nur der Grundgedanke. Ein paar mehr Befehle müssen es dann schon sein.

Thomas Feichtner 16. Mai 2018 20:24

AW: Beim Programmstart werden alle Units abgearbeitet
 
Hallo,

in welchen Event der jeweiligen Form hast du das ShowMessage?
Wie sieht deine Projektdatei (DPR) aus?
Werden hier alle 3 Forms erzeugt? Wenn ja warum?
Ich lass nur das Hauptformular automatisch erzeugen.

Mario61 16. Mai 2018 20:49

AW: Beim Programmstart werden alle Units abgearbeitet
 
Hallo,
da haben wir es... die DPR-Datei... ich habe mit dieser noch nie rumhantiert. In meinem Projekt habe ich 10 Formulare und 10 Units... Der Start des Programms hat ewig gedaurt. In der DPR-Datei habe ich alle ausgeklammert die ich zum Start nicht benötige. Der Start des Programms hat sich rapide erhöht. Den Aufruf der Formulare habe ich dann diese aus der DPR-Datei entnommen. Das funktioniert jetzt alles wunderbar. Ich danke Euch... Kleine Frage dennoch, wenn ich ein Formular mit Beispielsweise Application.CreateForm(TFrmKonfig, FrmKonfig) geöffnet habe, muss ich es nach Beendigung irgend wie wieder schließen ?

Danke und Gruß Mario

Zacherl 16. Mai 2018 22:04

AW: Beim Programmstart werden alle Units abgearbeitet
 
Über Projekt -> Projektoptionen -> Formulare kann man auch in der IDE direkt einstellen, welche Formulare automatisch erzeugt werden sollen.

Alallart 16. Mai 2018 22:56

AW: Beim Programmstart werden alle Units abgearbeitet
 
@Mario61

Es gibt verschiedene Wege zum Ziel, der einfachste ist deine Message-Boxen in OnActivate oder OnShow Ereignisse zu legen. OnCreate wird beim erzeugen des Formulars ausgeführt, die anderen (je nach dem) erst beim Anzeigen.

KodeZwerg 16. Mai 2018 23:11

AW: Beim Programmstart werden alle Units abgearbeitet
 
Da Du über Application.CreateForm() FormX erzeugst brauchst Du Dir um sowas keine Gedanken machen, das verwaltet alles die Application Klasse. Worüber ich mir gerade eher Gedanken mache ist, was passiert wenn Du den Knopf zum Anzeigen von FormX mehrmals drückst, ob so Speicherlecks entstehen je nachdem was die Form so alles bereit hält? Also ich pers. würde Application.CreateForm() nur einmal benutzen und danach über Visible := True oder Show/ShowModal steuern. FormX beibringen das wenn es geschlossen wird lediglich ein Visible := False ausgeführt wird. Auf diese Weise wird nicht wieder und wieder die Form neu generiert. Ich hoffe das ich mich Verständlich ausgedrückt habe.
Da Du geschrieben hast das Deine FormX sehr lange braucht beim Programm-Start, vielleicht wäre es ja auch Sinnvoll einen Thread zu erstellen der in Deiner Hauptform ausgeführt wird, der erstellt alle Application.CreateForm() im Hintergrund und wenn Du die dann Anzeigen willst sind sie bereits geladen und schwupps aufm Bildschirm.
Das mit Deiner ShowMessage() kannst Du nur umgehen indem Du den FormCreate/Initialization Code in eine eigene Prozedur auslagerst und bei Bedarf diese Prozedure aus Deiner Hauptform aufrufen, das könnte zum Beispiel in dem Thread automatisch erledigt werden.
Der Vorteil wäre halt das Du von der Bedienung her kaum einen Unterschied spürst, alle Formulare sofort ansprechbar sind und Dein Programm beim Starten schön schnell sein könnte.
Es kommt halt auf Dein Programm und Sinn und Zweck an, das sollte halt nur ein Szenario abdecken.

CCRDude 17. Mai 2018 06:01

AW: Beim Programmstart werden alle Units abgearbeitet
 
Formulare auszuklammern um den Programmstart zu beschleunigen ist ein schneller Workaround, aber generell wäre es sinnvoller, FormCreate als constructor zu betrachten und zu behandeln, also entsprechend klein und definiert zu halten.

Daten laden etc. was für den Inhalt des Fensters wichtig ist geht auch später. Bei FormShow/FormActivate muss man schauen, dass das wiederholt getriggert werden kann... ich habe gute Erfahrungen mit dem ersten Aufruf von FormPaint, dann wird das Formular schon angezeigt). Dann muss man aber natürlich schauen, dass Interaktionen ggfls. noch disabled sind.

@KodeZwerg: die VCL ist aber nicht threadsicher, UI-Krams im Thread ist keine gute Idee :) Threads an sich sind natürlich innerhalb jeder einzelnen Form zum Laden der Daten oder ähnlich langwierigem dann wieder eine gute Idee.

KodeZwerg 17. Mai 2018 07:30

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von CCRDude (Beitrag 1402324)
@KodeZwerg: die VCL ist aber nicht threadsicher, UI-Krams im Thread ist keine gute Idee :) Threads an sich sind natürlich innerhalb jeder einzelnen Form zum Laden der Daten oder ähnlich langwierigem dann wieder eine gute Idee.

Gibt es einen Grund so etwas zu behaupten? Hauptform nicht im extra-Thread aber die Sub-Forms die man bei Start nicht benötigt. Bei Thread-Ende sollte erst der "Zeige FormX" Knopf aktiviert werden. Was sollte daran schiefgehen?

Bernhard Geyer 17. Mai 2018 07:35

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von KodeZwerg (Beitrag 1402326)
Zitat:

Zitat von CCRDude (Beitrag 1402324)
@KodeZwerg: die VCL ist aber nicht threadsicher, UI-Krams im Thread ist keine gute Idee :) Threads an sich sind natürlich innerhalb jeder einzelnen Form zum Laden der Daten oder ähnlich langwierigem dann wieder eine gute Idee.

Gibt es einen Grund so etwas zu behaupten? Hauptform nicht im extra-Thread aber die Sub-Forms die man bei Start nicht benötigt. Bei Thread-Ende sollte erst der "Zeige FormX" Knopf aktiviert werden. Was sollte daran schiefgehen?

Das ist Allgemeinwissen. Die Windows-Handels sind alle nur im erstellenden Thread gültig.
Erstellst du nun irgendwelche Formular in einem Thread, so wird es dann krachen wenn auf globale Instanzen (Screen-Objekt, Application, ...) zugegriffen wird, welche nicht in diesem Thread erstellt wurde.
Das gemeine ist das es lange Zeit gut gehen kann, aber dann auf einmal permaent der Programmstart mit Exceptions unterbrochen wird.

Bernhard Geyer 17. Mai 2018 07:42

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von CCRDude (Beitrag 1402324)
Formulare auszuklammern um den Programmstart zu beschleunigen ist ein schneller Workaround, aber generell wäre es sinnvoller, FormCreate als constructor zu betrachten und zu behandeln, also entsprechend klein und definiert zu halten.

Sehe ich umgekehrt. Wenn ich Formulare beim Programmstart nicht benötige, so werden diese nicht erstellt.
Da brauch ich dann auch nicht (aufwändig) die Ladefunktion in FormCreate und FormShow/Activate aufteilen.
Wäre auch ungünstig wenn wir alle 100 Formulare beim start schon anlegen würden und dann (damals unter Win9x) dann gleich in Ressourcenprobleme laufen würden ...

KodeZwerg 17. Mai 2018 08:06

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1402327)
Erstellst du nun irgendwelche Formular in einem Thread, so wird es dann krachen wenn auf globale Instanzen (Screen-Objekt, Application, ...) zugegriffen wird, welche nicht in diesem Thread erstellt wurde.
Das gemeine ist das es lange Zeit gut gehen kann, aber dann auf einmal permaent der Programmstart mit Exceptions unterbrochen wird.

Ahh ok, ich Versteh worum es geht und gebe in solcher Situation Recht! (wobei ich oft ein "if assigned()" als prüfer einsetze)
Aber auch ein "if assigned()" ist manchmal nicht sicher, das ist mir auch schon ab und zu aufgefallen.

Bernhard Geyer 17. Mai 2018 09:03

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von KodeZwerg (Beitrag 1402332)
Aber auch ein "if assigned()" ist manchmal nicht sicher, das ist mir auch schon ab und zu aufgefallen.

Vermutlich wenn dein (globale?) Variable nicht mit FreeAndNil wieder genullt wird.
Assigned prüft nur ob die Varible ein Null-Pointer ist, nicht ob ein gültiges Objekt dahinter hängt.

himitsu 17. Mai 2018 09:10

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von Mario61 (Beitrag 1402311)
In jedem Formular befindet sich ein ShowMessage('xyz'). Beim Starten des Programmes werden alle MessagesBoxes angezeigt, noch bevor das erste Formular angezeigt wird.

Warum ?
Wie kann man das verhindern ?
Ich möchte in jeder Unit / Formular eigene unabhängige Routinen definieren, die nicht gleich beim Programmstart ausgefürt werden sollen.
Was muss ich tun ?

Erstmal hattest du vergessen zu sagen wo das ShowMessage drin ist. (aber die Glaskugel :glaskugel: hat es einfacher, da es nicht so viele Stellen gibt)


Der Initialisaton-Abschnitt jeder Unit wird immer beim Laden der Anwendung/DLL ausgeführt.

Constructor und OnCreate jeder Form wird immer beim Erstellen Jener ausgeführt.
Und wenn du beim Programmstart alle Forms automatisch erstellen lässt, dann ist das deine Schuld.
(Projektoptionen bzw. die zugehörigen CreateForm in der DPR)

OnShow/OnActivate wird bei jenen Forms ausgeführt, welche angezeigt werden und den Eingabefokus bekommen. (die MainForm und alle die Visible=True in der DFM haben)


Die einzige wirkliche Lösung wurde ja schon genannt: Forms erst dann dynamisch erstellen, wenn sie auch verwendet werden.

Alallart 17. Mai 2018 09:45

AW: Beim Programmstart werden alle Units abgearbeitet
 
Bei allem Verständnis für gute Ideen, so stellt sich hier immer die Frage über wie viele Forms wir hier sprechen? Bei 100, da ist jede gute Idee besser als die andere, aber vermutlich spricht der TE von zwei oder drei Formularen. Die machen den Speicher voll, und der Ladevorgang ist nicht merklich.

Auf High-Level Niveau sind das alles tolle Ideen, aber so wie ich das verstehe hat der TE noch keine große Erfahrung mit OnCreate, OnShow und OnActivate. Jeder der Ereignisse wird zu einer unterschiedlichen Zeit und in einer Reihenfolge ausgeführt, man muss also das nehmen was da ist.

Zuerst an TE, es gibt kein Ereignis das etwas ausführt wenn OnCreate fertig ist. Das Formular wird erst dann erzeugt, wenn alles in der Prozedur OnCreate abgearbeitet wurde. Eine ShowMessage in OnCrate wird also angezeigt bevor das Formular angezeigt wird. Egal ob man alle drei Formulare am Anfang erzeugt oder dynamisch später. Und Activate wird ausgeführt wenn die Applikation, bzw. Fenster den Fokus erhält. Bei ShowModal merkt man den Unterschied zu OnShow nicht, bei Show schon, denn dann erhällt das Fenster öfter den Fokus. OnShow wird jedes Mal angezeigt wenn das Fenster neu angezeigt wird.

Und sollte es nötig sein, dass das ShowMessage nur einmal angezeigt wird, kann man noch eine globale boolean Variable dafür nehmen die prüft ob es es das erste mal ist, dass ShowMessage angezeigt wird.

Man kann das Problem also auch simpel lösen. Bei drei Fenstern.

Jumpy 17. Mai 2018 09:57

AW: Beim Programmstart werden alle Units abgearbeitet
 
Ich glaube das showmessage war nur ein Analyse-Tool des TE. Da würd ich mich nicht dran festbeißen.

Da ja viele Wege nach Rom führen, hier mal meine üblicherweise benutzter:

Ausser beim Mainform, schmeiße ich die globale Variable in jeder Form-Datei weg.
Nur das Mainform wird dann in der dpr erzeugt.
Wird auf der Mainform dann ein Button oder Menü geklickt, dass ein neues Form erzeugt, dann:
- Soll es ein Modales Form sein, so gibt es dafür eine Variable in der (vereinfacht) Button-Click-Prozedur und das Form lebt nur innerhalb dieser Prozedur, wird am Ende also frei gegeben.
- Ist es ein nicht Modales Form oder soll es ggf. öfter benutzt werden (und dabei z.b. nicht seine Inhalte verlieren), so gibt es eine Variable in der MainForm für dieses Form und es wird dann per Lazy-Load erstellt und angezeigt, so wird es nur erzeugt wenn es gebraucht wird, ist aber wiederverwendbar, wenn es denn bereits erzeugt wurde.

p80286 17. Mai 2018 10:11

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von Mario61 (Beitrag 1402311)
Ich möchte in jeder Unit / Formular eigene unabhängige Routinen definieren, die nicht gleich beim Programmstart ausgefürt werden sollen.
Was muss ich tun ?

Wahrscheinlich ist es hilfreich, wenn Du Dein Vorhaben etwas konkretisierst, und uns den vorhandenen Sourcecode zeigst.

Gruß
K-H

himitsu 17. Mai 2018 10:14

AW: Beim Programmstart werden alle Units abgearbeitet
 
Zitat:

Zitat von Jumpy (Beitrag 1402344)
Ich glaube das showmessage war nur ein Analyse-Tool des TE. Da würd ich mich nicht dran festbeißen.

Es ging nicht um den Befehl an sich ... irgendein Code wurde irgendwann ausgeführt, aber es wurde vergessen zu sagen wo das Wo war.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:08 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