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/)
-   -   Delphi Progressbar während Objekterzeugung aktualisieren (https://www.delphipraxis.net/161661-progressbar-waehrend-objekterzeugung-aktualisieren.html)

Echtet 14. Jul 2011 16:27

Progressbar während Objekterzeugung aktualisieren
 
Hallo Delphianer,

vielleicht hat jemand von euch für folgendes Problem eine Lösung:

Nachdem eine Anmeldemaske mit dem korrekten Kennwort ausgefüllt wurde, wird das Hauptformular (bestehend aus vielen Komponenten) erzeugt:

Application.CreateForm(TfrmMain, frmMain); //Objekt erzeugen

Da diese Erzeugung mehrere Sekunden dauert, wollte ich vor der Objekterzeugung eine Progressbar einschalten (als durchlaufende Marquee), um die Wartezeit optisch zu überbrücken.

Leider wird während der Objekterzeugung die Progressbar nicht aktualisiert.
Weiss jemand Rat?

Gruß,
Echtet

Luckie 14. Jul 2011 16:31

AW: Progressbar während Objekterzeugung aktualisieren
 
Zitat:

Zitat von Echtet (Beitrag 1111753)
Leider wird während der Objekterzeugung die Progressbar nicht aktualisiert.
Weiss jemand Rat?

Ohne Code wird es schwierig.

jaenicke 14. Jul 2011 16:38

AW: Progressbar während Objekterzeugung aktualisieren
 
Was dauert denn so lange? Die Erzeugung der Komponenten oder hast du da aus Versehen noch etwas in FormCreate oder so, das so lange dauert?

Grundsätzlich muss das Programm auch irgendwann zur Abarbeitung der WM_PAINT-Botschaften kommen, sonst aktualisiert auch nichts. Application.ProcessMessages bewirkt das.

Echtet 14. Jul 2011 16:55

AW: Progressbar während Objekterzeugung aktualisieren
 
Hallo,

Hier erst mal etwas Code:

Delphi-Quellcode:
  If DataModule1.IBDatabase.Connected = True then //wenn die Verbindung funktioniert...
  begin
    Screen.Cursor := crAppStart;
    KlangAbspielen(login);
    ProgressBarLogin.Position := 0;
    ProgressBarLogin.MarqueeSize := 50;  //Einschalten der ProgressBar
    Application.Processmessages; <-- hier zusätzlich eingefügt
    Application.CreateForm(TfrmMain, frmMain); //Objekt erzeugen
    Application.Processmessages; <-- hier zusätzlich eingefügt
    frmMain.Show;
    frmLogin.Visible := False; //Anmeldemaske ausblenden
  end;
Ich habe nun zweimal das "Application.Processmessages" eingefügt, leider bringt es keine Verbesserung. Ich müsste eigentlich während der Objekterzeugt weitere Application.Processmessages einfügen. Aber wie geht das?

Zitat:

Die Erzeugung der Komponenten oder hast du da aus Versehen noch etwas in FormCreate oder so, das so lange dauert?
Tja, es sind schon so ca. 200 Komponenten (auf mehreren Registerblättern verteilt).

In FormCreate steht folgendes:
Delphi-Quellcode:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
 LogEinschalten; //Verwendung der Komponente HotLog
 UngesicherteRegisterListe := TStringList.Create; //Liste erzeugen
 DokumentBMP := TBitmap.Create; //wegen Scanner-Funktionalität
 DokumentJPG := TJPEGImage.Create;
 Application.OnMessage := MyMsg; //wegen Scanner-Funktionalität
 TWOpenDSM(Application.Handle); //wegen Scanner-Funktionalität
end;
Ich werde mal die Zeiten für die obigen Befehle messen...

Gruß,
Echtet

shmia 14. Jul 2011 18:11

AW: Progressbar während Objekterzeugung aktualisieren
 
Zitat:

Zitat von Echtet (Beitrag 1111760)
Tja, es sind schon so ca. 200 Komponenten (auf mehreren Registerblättern verteilt

Das ist ein bisschen viel.
Beim Erzeugen von Komponenten gibt es das Problem, dass jede neu erzeugte Komponente ein "Notification" Aufruf verursacht.
Bei 200 Kompos wären das 1+2+3+...+199+200 Aufrufe.
Der Zeitaufwand wächst also Quadratisch.

himitsu 14. Jul 2011 18:26

AW: Progressbar während Objekterzeugung aktualisieren
 
Das OnCreate wird noch vor dem Anzeigen der Form aufgerufen ... wo nichts da ist, kann man wohl schlecht etwas anzeigen?

Echtet 14. Jul 2011 19:39

AW: Progressbar während Objekterzeugung aktualisieren
 
Hallo himitsu,

vielleicht stehe ich ja jetzt auf dem Schlauch...

Zitat:

Das OnCreate wird noch vor dem Anzeigen der Form aufgerufen ... wo nichts da ist, kann man wohl schlecht etwas anzeigen?
Ich muss doch erst das Formular mit Create erzeugen, bevor ich es mit Show anzeigen kann?

Oder habe ich Dich völlig falsch verstanden?

Gruß,

Echtet

Luckie 14. Jul 2011 20:13

AW: Progressbar während Objekterzeugung aktualisieren
 
Richtig. Und wie soll eine Komponente etwas anzeigen können, wenn sie noch gar nicht existiert?

omata 14. Jul 2011 20:18

AW: Progressbar während Objekterzeugung aktualisieren
 
Stichwort: Splashscreen

sirius 14. Jul 2011 21:24

AW: Progressbar während Objekterzeugung aktualisieren
 
Kannst du nicht etwas weniger auf einmal erzeugen. Es werden doch nicht gleich 200 Komponenten auf einmal sichtbar bzw. notwendig sein. HZier musst du evtl. etwas mehr Dynamik reinbringen.

Ansonsten muss sich eben jede Komponente melden, wenn sie fertig ist. Und dann kannst du auf einem extra Formular (z.B. Splash-Screen) den Fortschritt anzeigen.

Echtet 15. Jul 2011 10:38

AW: Progressbar während Objekterzeugung aktualisieren
 
Hallo,

Zitat:

Ansonsten muss sich eben jede Komponente melden, wenn sie fertig ist.
Das hört sich interessant an. Leider haben die Komponenten keine OnCreate-Ereignis, in das ich mich einklinken könnte. Hat jemand einen Tip zu dieser Variante?

Zitat:

Und wie soll eine Komponente etwas anzeigen können, wenn sie noch gar nicht existiert?
Ich vermute mal, dass sich hier ein Missverständnis eingeschlichen hat (oder ich verstehe es nicht):
1. Ich erzeuge ein Login-Formular.
Im Login-Formular befindet sich die Progressbar (momentan noch deaktiviert)
2. Ich prüfe User und kennwort ab
3. Ist beides Korrekt, wird die Progressbar aktiviert und sie sollte "loslaufen"
4. Nun wird das Hauptformular (mit den vielen Komponenten erzeugt und mit Show angezeigt)
5. Während diese Erzeugens des Hauptformulars ändert sich leider nicht die Fortschrittsanzeige der Progressbar.

Zitat:

Stichwort: Splashscreen
Das mit dem SplashScreen muss ich mir mal genauer anschauen. Ich dachte bisher, ein Splashscreen dient nur dazu, vor dem Start des Programms "die wartezeit zu versüßen". Bei mir läuft das Programm ja bereits (in Form der Login-Maske) und der SplashScreen müsste nun zwischen Login-Maske und Hauptformular erscheinen. Ist das so machbar?

Danke für die vielen Hinweise!
Gruß,
Echtet

stahli 15. Jul 2011 10:59

AW: Progressbar während Objekterzeugung aktualisieren
 
Hier ist erklärt, dass Dein Vorhaben im MainThread nicht so einfach umzusetzen ist.

Wenn es um wenige Sekunden nach der Anmeldung geht, würde ich im LoginForm einfach ein nettes Image "bitte warten..." anzeigen.

Für eine laufende ProgressBar müsstest Du diese (die betreffende Instanz) Deinem Mainform übergeben, das diese dann zyklisch hochzählt. Da der Ladefortschritt aber durch Dich schwer zu überwachen ist, wird das wohl schwierig werden.

Ein empfehlenswerter Ansatz für sehr komplexe Formulare kann sein, mit embeded Forms zu arbeiten (oder notfalls mit Frames).
Dadurch erhält man eine übersichtlichere Projektstruktur und Du könntest bei jedem Form, das eingebettet wird, einen Fortschritt darstellen.

sHoXx 15. Jul 2011 11:33

AW: Progressbar während Objekterzeugung aktualisieren
 
oder du machst so nen balken, wie er beim bootvorgang von xp kommt der einfach nur durchläuft und keinen fortschritt anzeigt

stahli 15. Jul 2011 11:39

AW: Progressbar während Objekterzeugung aktualisieren
 
Das ist dann eine ProgressBar im Marguee-Style.
Das Problem ist aber, dass diese still steht, wenn das Programm beschäftigt ist (z.B. weil es ein Formular lädt).

omata 15. Jul 2011 13:26

AW: Progressbar während Objekterzeugung aktualisieren
 
Liste der Anhänge anzeigen (Anzahl: 4)
Hier ein Beispiel...

Echtet 17. Jul 2011 17:58

AW: Progressbar während Objekterzeugung aktualisieren
 
Hallo Delphianer,

vielen Dank nochmal für die vielen Tips. Aufgrund der Hinweise zum SpashScreen habe ich mir diese Thematik nochmal näher angeschaut (velen Dank auch an Omata für die beispielhaften Routinen!).

Ich werde wohl aus den TMS-Componenten die Komponente für den SpashScreen verwenden. Damit kann ich einigermaßen die gewünschte Funktionalität abbilden.

Da mir anfangs nicht bewusst war, dass man einen SplashScreen nicht nur zu Programmbeginn einblenden lassen kann, hier mal skizzenhaft mein Vorgehen. Vielleicht hilft es dem einen oder anderen ebenso...

1. Form1 (Login = Hauptformular) wird beim Programmstart automatisch erzeugt.
2. frmMain wird nach korrekter anmeldung aufgerufen.
3. Die Spash-Komponente wird auf dem frmMain abgelegt.
4. Nachdem aus der Form1 der Befehl "Application.CreateForm(TfrmMain, frmMain);" ausgeführt wurde, startet nach kurzer Verzögerung der SpashScreen
5. frmMain wird angezeigt "frmMain.Show"
6. Spash-Komponente wird ggf beendet bzw blendet langsam aus

Gruß,

Echtet

jaenicke 18. Jul 2011 09:11

AW: Progressbar während Objekterzeugung aktualisieren
 
Naja, aber Moment, wenn das das Problem löst, sind das Problem doch nicht die vielen Komponenten, sondern das was in OnCreate oder OnShow passiert, oder?
Denn die Komponenten sind ja bereits vollständig erzeugt, wenn du in OnCreate ankommt.

Echtet 18. Jul 2011 14:17

AW: Progressbar während Objekterzeugung aktualisieren
 
Hallo,

deswegen sagte ich ja auch "damit könne ich einigermaßen die Funktionalität abbilden".

Du hast sicherlich recht, dass die Lösung nicht perfekt ist. Ich denke schon, dass die Anzahl der Komponenten eine Rolle spielt, denn diese werden doch mit der Erzeugung des Hauptformulars ebenfalls erst (automatisch mit dem Formular) erzeugt.

Tatsächlich habe ich immer noch eine Wartezeit, bis der SplashScreen angezeigt wird, aber diese ist kürzer als ohne die SpashScreen-Lösung.

Ich bleibe aber weiter dran, ob es ggf. noch weiter verbesserungsmöglichkeiten gibt.

Gruß,
Echtet


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