Wann ist eine Anwendung startbereit
-
- Beiträge: 758
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Wann ist eine Anwendung startbereit
Moin zusammen,
Gibt es ein Flag, Funktion, Event oder was auch immer, wo man weis, dass die Anwendung komplett initialisiert ist ?
Alle Formulare geladen sind, alle Construktoren durchlaufen wurden ?
Bestimmte Dinge dürfen erst abgearbeitet werden wenn die komplette Anwendung initialisiert ist.
Bei mir zum Beispiel habe ich einen Timer auf FormA und der sendet etwas auf die Schnittstelle RS232,
dann kommen Daten von der Schnittstelle und die werden an FormB gesendet.
Das Problem beim Starten:
Ich weis nicht wann ich etwas tätigen darf, wann ist denn FormB soweit dass es Daten empfangen kann ?.
Der Speicher für meine Messpuffer werden erst in FormB angelegt.
Ich weis auch nicht welche Reihenfolge durchlaufen wird, ist das immer in der Reihenfolge der Units.
Ehrlich gesagt möchte ich mich darum auch garnicht kümmern müssen.
Es gibt ja auch "Loaded" das habe ich auch schon überschrieben bei Komponenten, aber wann ist ALLES geloaded und wann wurden ALLE Construktoren
durchlaufen ?.
Ich habe auch oft in meinen Komponenten:
if (csDesigning in ComponentState) or (csLoading in ComponentState) then mache erstmal nix...
Siro
Gibt es ein Flag, Funktion, Event oder was auch immer, wo man weis, dass die Anwendung komplett initialisiert ist ?
Alle Formulare geladen sind, alle Construktoren durchlaufen wurden ?
Bestimmte Dinge dürfen erst abgearbeitet werden wenn die komplette Anwendung initialisiert ist.
Bei mir zum Beispiel habe ich einen Timer auf FormA und der sendet etwas auf die Schnittstelle RS232,
dann kommen Daten von der Schnittstelle und die werden an FormB gesendet.
Das Problem beim Starten:
Ich weis nicht wann ich etwas tätigen darf, wann ist denn FormB soweit dass es Daten empfangen kann ?.
Der Speicher für meine Messpuffer werden erst in FormB angelegt.
Ich weis auch nicht welche Reihenfolge durchlaufen wird, ist das immer in der Reihenfolge der Units.
Ehrlich gesagt möchte ich mich darum auch garnicht kümmern müssen.
Es gibt ja auch "Loaded" das habe ich auch schon überschrieben bei Komponenten, aber wann ist ALLES geloaded und wann wurden ALLE Construktoren
durchlaufen ?.
Ich habe auch oft in meinen Komponenten:
if (csDesigning in ComponentState) or (csLoading in ComponentState) then mache erstmal nix...
Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Re: Wann ist eine Anwendung startbereit
Tja, ich war da auch immer unischer und habe selbst mit "onShow" nicht immer gute Erfahrungen gehabt.
Habe mir angewöhnt, einen Timer auf die Mainform zu legen, den nenne ich "StartTimer".
Im OnShow wird dieser Timer gestartet. Der Timer hat eine Verzögerung von 20 ms.
Damit hatte ich noch niemals Probleme, dass etwas noch nicht fertig erzeugt war.
Habe mir angewöhnt, einen Timer auf die Mainform zu legen, den nenne ich "StartTimer".
Im OnShow wird dieser Timer gestartet. Der Timer hat eine Verzögerung von 20 ms.
Damit hatte ich noch niemals Probleme, dass etwas noch nicht fertig erzeugt war.
Gruß, Michael
-
- Beiträge: 758
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: Wann ist eine Anwendung startbereit
So ähnliche Ideen hatte ich auch schon,
Wenn die Anwendung aber etwas läd und das System auch grade was rumschrappelt, kann das Sekunden dauern...
und dann hat man wieder nichts gewonnen. Das ist natürlich keine schöne/saubere Lösung.
Ich hatte mir am Anfang aber auch mal so beholfen.
Wenn die Anwendung aber etwas läd und das System auch grade was rumschrappelt, kann das Sekunden dauern...
und dann hat man wieder nichts gewonnen. Das ist natürlich keine schöne/saubere Lösung.
Ich hatte mir am Anfang aber auch mal so beholfen.
Zuletzt geändert von siro am So 16. Mai 2021, 09:12, insgesamt 2-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Re: Wann ist eine Anwendung startbereit
Wenn du derartige Eingangsbedingungen hast, würde ich flags setzen, wenn nötige Aufgaben erledigt sind und der "Spaß" losgehen kann.
Über den Starttimer kannst du prüfen, ob alle Flags deiner Bedingungen erfüllt sind.
Über den Starttimer kannst du prüfen, ob alle Flags deiner Bedingungen erfüllt sind.
Gruß, Michael
-
- Beiträge: 758
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: Wann ist eine Anwendung startbereit
Grade eine Idee bekommem, wäre hier ein FLAG sinnvoll ??
Code: Alles auswählen
begin
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TFormMain, Form_Main);
Application.CreateForm(TFormBatterietest, FormBatterietest);
Application.CreateForm(TFormCurves, Form_Curve);
FReady:=TRUE; // vermutlich müsse das der richtige Zeitpunkt sein ????
Application.Run;
end.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
-
- Beiträge: 758
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: Wann ist eine Anwendung startbereit
Füge ich später ein Formular hinzu, steht mein Flag aber an falscher Stelle, habe ich grad ausprobiert:
Code: Alles auswählen
begin
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TFormMain, Form_Main);
Application.CreateForm(TFormBatterietest, FormBatterietest);
Application.CreateForm(TFormCurves, Form_Curve);
ReadyToRun:=TRUE; // vermutlich müsse das der richtige Zeitpunkt sien ????
Application.CreateForm(TForm1, Form1); // Bäääh, nicht hier...
Application.Run;
end.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Re: Wann ist eine Anwendung startbereit
Einen Timer, besser TIdleTimer, kann man durchaus dafür nutzen. Wenn man aber nur einen Aufruf benötigt, geht z.B. auch Application.QueueAsyncCall. Alles wird erst bei Application.Idle aufgerufen (wenn der MainThread in den "Leerlauf schaltet" - alle Messages abgearbeitet sind).siro hat geschrieben: So 16. Mai 2021, 08:59 Gibt es ein Flag, Funktion, Event oder was auch immer, wo man weis, dass die Anwendung komplett initialisiert ist ?
Alle Formulare geladen sind, alle Construktoren durchlaufen wurden ?
z.B.:
Code: Alles auswählen
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure Test(Data: PtrInt);
end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.QueueAsyncCall(@Test, 0);
end;
procedure TForm1.Test(Data: PtrInt);
begin
Caption := 'Gestartet';
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 758
- Registriert: Di 23. Aug 2016, 14:25
- OS, Lazarus, FPC: Windows 11
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: Wann ist eine Anwendung startbereit
Ersteinmal vielen Dank für die Infos an Michael und Michl.
Das muss ich mir jetzt mal genauer ansehen. IdleTimer klingt gut, den habe ich, glaube ich zumindest, auch verstanden.
Mit dem Asynchronous Call, hab ich noch nicht wirklich verstanden, werde aber auch damit mal etwas experimentieren.
Ich werde mir dafür ein spezielles Testprojekt erzeugen um das zu verfolgen.
Kann es eigentlich passieren, dass die Anwendung auch während des Startens kurz "IDLE" wird ?
Das muss ich mir jetzt mal genauer ansehen. IdleTimer klingt gut, den habe ich, glaube ich zumindest, auch verstanden.
Mit dem Asynchronous Call, hab ich noch nicht wirklich verstanden, werde aber auch damit mal etwas experimentieren.
Ich werde mir dafür ein spezielles Testprojekt erzeugen um das zu verfolgen.
Kann es eigentlich passieren, dass die Anwendung auch während des Startens kurz "IDLE" wird ?
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...
Re: Wann ist eine Anwendung startbereit
Mir ist kein Fall bekannt. Alle Messages zum Erstellen der Controls werden in die MessageQueue eingetragen und abgearbeitet, bevor die Anwendung Idle wird.siro hat geschrieben: So 16. Mai 2021, 11:20Kann es eigentlich passieren, dass die Anwendung auch während des Startens kurz "IDLE" wird ?
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: Wann ist eine Anwendung startbereit
Mein Standard-Vorgehen in dem Fall, dass die Initialisierung im OnCreate-Event des Hauptformulars zu früh kommt und OnActivate bzw. OnShow nicht geeignet sind (weil sie wiederholt aufgerufen werden können), ist eine Methode "BeforeRun" im Hauptformular, die ich in der Projekt-Datei - wie der Name sagt - vor Application.Run aufrufe und in der all die nötige Initialisierung steckt.
Alternativ könnte man den Code auch in OnActivate oder OnShow stecken und die wiederholte Ausführung durch ein Flag "InitDone" unterbinden:
Code: Alles auswählen
type
TForm1 = type(TForm)
public
procedure BeforeRun;
end;
procedure TForm1.BeforeRun;
begin
// Initialisierungs-Code
end;
-----------
program Project1;
....
begin
...
Application.CreateForm(TForm1, Form1);
...
Form1.BeforeRun;
Application.Run;
end.
Code: Alles auswählen
procedure TForm1.FormActivate(Sender: TObject);
begin
if not InitDone then
begin
... // Initialisierungscode
InitDone := true;
end;
end;
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Wann ist eine Anwendung startbereit
Hi!
FormActivate ist die richtige Stelle, bei der man davon ausgehen kann, dass alles von FromCreate abgearbeitet ist. Hier erhält die HauptForm auch den Focus. Unter Linux wird onActivate nur einmal ausgeführt. Für Windows gibt's diese Spezialbehandlung:
Weiterhin kann man eine globale variable setzen, die verhindert, dass Procedure ausgeführt werden, obwohl noch nicht alles initialisiert ist, wie z.B. FormPaint
Solange startup noch true ist, steigt man z.B. aus FormPaint mit exit aus.
In FormActivate setzt man dann startup auf false und die Application kann laufen, wie gewünscht.
Winni
FormActivate ist die richtige Stelle, bei der man davon ausgehen kann, dass alles von FromCreate abgearbeitet ist. Hier erhält die HauptForm auch den Focus. Unter Linux wird onActivate nur einmal ausgeführt. Für Windows gibt's diese Spezialbehandlung:
Code: Alles auswählen
procedure TForm1.FormActivate(Sender: TObject);
begin
OnActivate:= nil;
end;
Code: Alles auswählen
var startup: Boolean = true;
In FormActivate setzt man dann startup auf false und die Application kann laufen, wie gewünscht.
Winni
Re: Wann ist eine Anwendung startbereit
Das kannst du nicht so allgemein sagen. Auch eine globalisierte Variable hilft nicht in allen Fällen.
Ich habe hier zum Beispiel eine große Datenbankanwendung, die nach dem Start eine allgemeine Übersichtstabelle zeigt. OnPaint wird nach OnActivate gefeuert und endet mit einem SIGSEGV, da die Daten noch nicht aus der Datenbank geholt wurden. Daher ist Application.OnIdle für mich der früheste Zeitpunkt die Anwendung als startbereit zu erklären. Noch interessanter ist es in einer anderen Anwendung. Diese lasse ich starten und mach sie "nutzbar". Zeitintensive Daten hole ich per Thread. Erst wenn diese alle da sind, ist die Anwendung wirklich initialisiert bzw. voll nutzbar. Wie gesagt, es kommt je nach Anwendungsfall darauf an.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Wann ist eine Anwendung startbereit
Hi!
Natürlich- wenn Du mit so langsamen Zeugs wie einerDB arbeitest, dann brauchst Du ne zweite boolsche Variable, die anzeigt ob die DB schon ready ist.
Außerdem würde ich nie automatisch Daten aus einer DB beim Programmstart anzeigen.
Dafür darf der User schon mal irgendwo hinklicken.
Winni
Natürlich- wenn Du mit so langsamen Zeugs wie einerDB arbeitest, dann brauchst Du ne zweite boolsche Variable, die anzeigt ob die DB schon ready ist.
Außerdem würde ich nie automatisch Daten aus einer DB beim Programmstart anzeigen.
Dafür darf der User schon mal irgendwo hinklicken.
Winni
- af0815
- Lazarusforum e. V.
- Beiträge: 6770
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Wann ist eine Anwendung startbereit
Ich verwende seit Jahren und nicht nur bei Lazarus immer OnActivate mit einem InitFlag.
Das ist seit Delphizeiten die Stelle, wo wirklich alle Komponenten erzeugt sind und beim Hauptformular (das ist auch wichtig !!) mit dem ersten Auftauchen des Formular zusammenhängt. Ich habe gelernt micht nicht auf die Reihenfolge der Events zu verlassen, schon nicht zu Delphis Zeiten. Zu diesem Zeitpunkt sind auch alle Datenmodule etc. bereits initialisiert und man kann auch hier Verbindungen öffnen, auch wenn RAD-DB Komponenten im Spiel sind. Auch die Liste der erzeugten Formulare und Datenmodule ist dann abgearbeitet, wobei natürlich das erste Formular das Hauptformular ist. Das muss man schon beachten, bzw. berücksichtigen, wenn man das ändert.
Generell habe ich mir angewöhnt nur ein (Haupt-) Formular zu haben und nur dieses erzeugt alles was es benötigt selbst. Damit werden auch lästige Sachen bei Lazarus, wenn man ein Projekt klont, wie das plötzlich Formulare aus der Liste der automatisch erzeugten Formulare verschwindet, nicht so tragisch. Das sieht man dann beim ersten Start, wenn überhaupt kein Formular erzeugt wird.
Mit der Methodik, habe ich duzende Programme im beruflichen Umfeld am Laufen, egal ob Win, Linux/X64 oder Raspian .
Zu den DB-Conntions, dort einen Autostart zu machen, ist eher was für Leute die auf Probleme stehen. Von mir aus, gehören die automatisch deaktiviert, wenn man nicht im RAD-Design ist. Wenn man die verwendet, dann maximal für eine ganz einfache 'Hello DB'. Das und ein 'SELECT * FROM' und ich sage - nicht genügend setzen.
Das ist seit Delphizeiten die Stelle, wo wirklich alle Komponenten erzeugt sind und beim Hauptformular (das ist auch wichtig !!) mit dem ersten Auftauchen des Formular zusammenhängt. Ich habe gelernt micht nicht auf die Reihenfolge der Events zu verlassen, schon nicht zu Delphis Zeiten. Zu diesem Zeitpunkt sind auch alle Datenmodule etc. bereits initialisiert und man kann auch hier Verbindungen öffnen, auch wenn RAD-DB Komponenten im Spiel sind. Auch die Liste der erzeugten Formulare und Datenmodule ist dann abgearbeitet, wobei natürlich das erste Formular das Hauptformular ist. Das muss man schon beachten, bzw. berücksichtigen, wenn man das ändert.
Generell habe ich mir angewöhnt nur ein (Haupt-) Formular zu haben und nur dieses erzeugt alles was es benötigt selbst. Damit werden auch lästige Sachen bei Lazarus, wenn man ein Projekt klont, wie das plötzlich Formulare aus der Liste der automatisch erzeugten Formulare verschwindet, nicht so tragisch. Das sieht man dann beim ersten Start, wenn überhaupt kein Formular erzeugt wird.
Mit der Methodik, habe ich duzende Programme im beruflichen Umfeld am Laufen, egal ob Win, Linux/X64 oder Raspian .
Zu den DB-Conntions, dort einen Autostart zu machen, ist eher was für Leute die auf Probleme stehen. Von mir aus, gehören die automatisch deaktiviert, wenn man nicht im RAD-Design ist. Wenn man die verwendet, dann maximal für eine ganz einfache 'Hello DB'. Das und ein 'SELECT * FROM' und ich sage - nicht genügend setzen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).