Announcement

Collapse
No announcement yet.

Fortschrittsanzeige während Laden eines Forms

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Fortschrittsanzeige während Laden eines Forms

    Hallo,

    Ich kenne die Möglichkeit mit der Unit "SplashLoad" von Andreas Kosch eine Fortschrittsanzeige für das Laden eines Programmes zu erzeugen.

    Ich habe aber noch keine Lösung eine Fortschrittsanzeige für das Laden eines Formulares zu erzeugen.

    Z.B. Form A ruft Form B.

    Der Aufruf von Form B dauert lange und soll daher mit einer Anzeige eines Fortschrittsbalkens versehen werden.

    Ich habe die Technik von SplashLoad in "FormActivate" von Form B eingebaut. Dies bringt jedoch nicht den gewünschten Erfolg, da die ProgressBar erst kurz vor dem Erscheinen des Formulares angezeigt wird.

    Wie löst man ein derartiges Problem ?

    Sofort nach dem Befehl für den Aufruf von Form B (aus Form A erteilt) soll die Fortschrittsanzeige angezeigt werden.

    Gruss<br>Helmut

  • #2
    Hallo,

    Die Ladezeit des Forms beträgt ca. 17 Sekunden !! PIII-733 MHz.
    Ohne eine Progressbar macht das Programm durch die langen Reaktionszeiten einen irritierenden Eindruck.

    Eine Fortschrittsanzeige würde den Effekt der Wartezeit mildern.

    Wer weiß Rat

    Comment


    • #3
      Hallo,

      man könnte die langwierige Formular-Initialisierung in einen Thread auslagern. Der Thread aktualisiert im folgenden Beispiel ein TProgressBar-Anzeige im Hauptformular, wobei nach jeder Erhöhung über Sleep(25) eine Ruhepause von 25 Millisekunden eingelegt wird. Der Thread bleibt bis zum Programmende erzeugt (auch wenn er nichts mehr ausführt).

      Thread-Unit:
      <pre>
      { ************************************************** **************
      Source File Name : Smart_Thread.PAS
      Typ : Thread-Unit
      Autor : Andreas Kosch
      Erstellt am : 13.11.1998
      Compiler : Delphi 4.01 UpdatePack #1
      Betriebssystem : Windows 95
      Revisionen : Auslagern von zeitintensiven Initialisierungen
      in einen Thread, damit das Hauptformular
      schnell bedienbar ist.
      ************************************************** ************** }

      unit Smart_Thread;

      interface

      uses
      Windows, Messages, SysUtils, Classes, ComCtrls;

      type
      TOnCreateThread = class(TThread)
      private
      FValue : Integer;
      FProgress : TProgressBar;
      procedure UpdateProgress;
      procedure HideProgress;
      protected
      procedure Execute; override;
      public
      constructor Create(aProgress: TProgressBar);
      end;

      implementation

      { TOnCreateThread }

      constructor TOnCreateThread.Create(aProgress: TProgressBar);
      begin
      FProgress := AProgress;
      inherited Create(False);
      end;

      procedure TOnCreateThread.Execute;
      begin
      while (not Terminated) and (FValue <= 100) do
      begin
      Synchronize(UpdateProgress);
      Inc(FValue);
      // Wartepause zur Demonstration einlegen
      Sleep(50);
      end;
      Synchronize(HideProgress);
      end;

      procedure TOnCreateThread.UpdateProgress;
      begin
      FProgress.Position := FValue;
      end;

      procedure TOnCreateThread.HideProgress;
      begin
      FProgress.Visible := False;
      end;

      end.
      </pre>
      Beispielprogramm:

      Beim Beenden des Programms müssen zwei Fälle beachtet werden:<br>
      1. Programm wird geschlossen, obwohl der Thread noch läuft <br>
      2. Programm wird geschlossen, wobei der Thread nichts mehr ausführt (Execute ist abgeschlossen) <br>
      Aus diesem Grund wird in der Ereignisbehandlungsmethode OnDestroy zuerst TThread.Terminate und anschließend TThread.WaitFor aufgerufen.
      <pre>
      { ************************************************** **************
      Source File Name : SmartTestFrm.PAS
      Typ : Hauptformular-Unit
      Autor : Andreas Kosch
      Erstellt am : 13.11.1998
      Compiler : Delphi 4.01 UpdatePack #1
      Betriebssystem : Windows 95
      Revisionen : Auslagern von zeitintensiven Initialisierungen
      in einen Thread, damit das Hauptformular
      schnell bedienbar ist.
      ************************************************** ************** }

      unit SmartTestFrm;

      interface

      uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ComCtrls, Smart_Thread, StdCtrls, Buttons;

      type
      TFormMain = class(TForm)
      StatusBar1: TStatusBar;
      ProgressBar1: TProgressBar;
      BitBtnHelp: TBitBtn;
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure BitBtnHelpClick(Sender: TObject);
      private
      { Private-Deklarationen}
      FOnCreateThread : TOnCreateThread;
      public
      { Public-Deklarationen}
      end;

      var
      FormMain: TFormMain;

      implementation

      {$R *.DFM}

      procedure TFormMain.FormCreate(Sender: TObject);
      begin
      FOnCreateThread := TOnCreateThread.Create(ProgressBar1);
      end;

      procedure TFormMain.FormDestroy(Sender: TObject);
      begin
      if Assigned(FOnCreateThread) then
      begin
      FOnCreateThread.Terminate;
      FOnCreateThread.WaitFor;
      end;
      end;

      procedure TFormMain.BitBtnHelpClick(Sender: TObject);
      begin
      ShowMessage('Trotz noch laufender Initialisierung bedienbar!');
      end;

      end.
      </pre&gt

      Comment


      • #4
        Hallo Helmut, <p>
        eine Alternative zu Andreas Vorschlag mit dem Thread wäre, dafür zu sorgen, daß das neue Formular sich zuerst auf dem Bildschirm darstellt und dann erst die zeitintensive Aktion startet. In der Fußzeile kann dann ein ProgressBar dargestellt werden, der von der Aktion gespeist wird und danach wieder unsichtbar gemacht oder gelöscht wird.<p>
        Ich verwende hierzu immer eine Member-Variable: ROnCreate: Boolean;<br>
        Im Ereignis FormCreate setze ich sie auf True und im FormPaint-Ereignis sieht's dann so aus:<pre>
        begin
        if ROnCreate then begin
        { Wird in der Methode FormCreate gesetzt. }
        ROnCreate := False;
        { Ab hier kommt alles was eigentlich in FormCreate gemacht werden sollte,
        aber damit es erst dann geschieht, wenn das Hauptformular für den Benutzer
        auch schon sichtbar ist, wird es eben hier gemacht. }

        end; // if ROnCreate

        // Ab hier kommt alles, was normalerweise in OnPaint gemacht werden soll.

        end;
        </pre>
        So kommst du ohne den Thread aus, der ja dem Benutzer an dieser Stelle nichts bringt. Er kann ja seine Arbeit dadurch nicht früher fortsetzen.
        <p>
        Gruß<p>
        Wolfgan

        Comment


        • #5
          Schlicht und einfach erst mal eine Progress Form mit StayOnTop anzeigen. Der zeitintensive Programmteil in Form B kann dann den Fortschritt treiben.
          Wenn das nicht geht, dann muss die Progress Form wie der Internet Explorer einfach nur einen Taetigkeitsbalken anzeigen

          Comment

          Working...
          X