![]() |
"Bitte warten"-Formular korrekt anzeigen
Hallo,
in meinem mittlerweile recht großen Programm gibt es verschiedene Aktionen, die länger dauern. Um dem Benutzer nun zu signalisieren, dass das Programm etwas arbeitet und nicht rumhängt (;)) habe ich ein Formular erstellt mit einer Progressbar, Maqueebar und einem Aktions-Label. Je nach Aktion wird die Marquee- oder Progressbar angezeigt. Das Form wird dynamisch erstellt und freigegeben. Damit es sich aber neuzeichnet müsste ich es eigentlich in einem gesonderten Thread erstellen. Nun ist das aber wegen der Synchronisierung nicht so einfach. Wie muss ich die Sache angehen? Kann ich in einem Thread das Formular erstellen lassen, wenn ich eine Methode synchronisiert aufrufe? Also, ist das der richtige Weg, damit das Formular "parallel" zu der Hintergrundaktion läuft? Mein Code sieht - ohne Thread - bisher so aus (recht simpel)
Delphi-Quellcode:
Danke im Voraus
var
... frmWait: TfrmWarten; begin frmWait:=TfrmWarten.Create(nil); try frmWait.FormStyle:=fsStayOnTop; frmWait.ShowMarqueeBar(True); frmWait.Show; frmWait.Repaint; //Aktionen, die viel Zeit brauchen ... ... ... finally FreeAndNil(frmWait); end; end; |
AW: "Bitte warten"-Formular korrekt anzeigen
Zitat:
in einen Thread zu schieben und den Benutzer weiter arbeiten zu lassen. Als den Thread zu missbrauchen nichts zu tun und eine VCL Komponente zu aktualisieren :shock: |
AW: "Bitte warten"-Formular korrekt anzeigen
An sich richtig. Nur während dieser Aktionen soll der Benutzer nicht weiterarbeiten dürfen. Es geht um Dinge wie Backups/Sicherung der Datenbank, Hinzufügen von Dateianhängen in die Datenbank etc.
Bei diesen Aktionen habe ich Angst, dass etwas schief geht. Deswegen lieber dem Benutzer verweigern, etwas anderes nebenher mit der Datenbank zu machen. Oder :?: |
AW: "Bitte warten"-Formular korrekt anzeigen
Zeig doch dein Warte-Formular mittels ShowModal an. Zusätzlich müsstest du nur noch das Schließen verhindern, solang der Thread läuft, z.B. im OnCloseQuery Event.
|
AW: "Bitte warten"-Formular korrekt anzeigen
oder kann man nicht das "Bitte Warten"-Fenster per nonVCL erzeugen und in einem Extra-Thread ausführen? - so kann die aktuelle Programmstruktur bestehen bleiben.
Bernhard |
AW: "Bitte warten"-Formular korrekt anzeigen
Mach's doch so:
Delphi-Quellcode:
Die Methode AddMessage() ruft intern immer auch noch BringToFront auf, damit das "Warten"-Formular nicht permanent hinter dem Hautpformular verschwindet.
var
... frmWait: TfrmWarten; begin frmWait:=TfrmWarten.Create(nil); try //frmWait.FormStyle:=fsStayOnTop; // lieber nicht-das ist zu "agressiv" für den Benutzer frmWait.ShowMarqueeBar(True); frmWait.Show; //Aktionen, die viel Zeit brauchen frmWait.AddMessage('Datenbank wird überprüft...'); ... // arbeiten frmWait.AddMessage('Index neu anlegen...'); ... frmWait.AddMessage('Fertig'); frmWait.Finish; finally frmWait.Free; end; end; Die Methode Finish sieht so aus:
Delphi-Quellcode:
Somit muss der Benutzer das Fenster zum Schluss schliesen.
procedure TfrmWarten.Finish;
begin PlaySound('RingIn', 0, SND_ALIAS); Cursor := crDefault; Hide; BtnClose.Visible := True; // Schliesen-Button einblenden ShowModal; end; Grund: er soll die Gelegenheit haben die Meldungen zu lesen. |
AW: "Bitte warten"-Formular korrekt anzeigen
Ich weis nicht ob das evtl. etwas "schmutzig" ist...
...das aufgerufene modale fenster hat eine property für eine "Arbeits-Methode", vergleichbar mit einem Event-Handler. Das "Bitte warten" Fenster mit Progressbar ist wie folgt ausgestattet:
Delphi-Quellcode:
Das Hauptformular mit der Arbeits-Procedure so:
type
TWorkerMethode = procedure (Sender : TObject; AProgressBar : TProgressBar) of object; TFormWorkProgress = class(TForm) ProgressBar1: TProgressBar; Timer1: TTimer; procedure Timer1Timer(Sender: TObject); private { Private-Deklarationen } FWorkerMethode : TWorkerMethode; public { Public-Deklarationen } property WorkerMethode : TWorkerMethode read FWorkerMethode write FWorkerMethode; end; var FormWorkProgress: TFormWorkProgress; implementation {$R *.dfm} procedure TFormWorkProgress.Timer1Timer(Sender: TObject); begin Timer1.Enabled := False; if assigned(FWorkerMethode) then FWorkerMethode(self, ProgressBar1); end;
Delphi-Quellcode:
Nur ganz grob... etwas Feintunig ist da noch nötig... das modale Fenster ist etwas blockiert. Evtl. das Close aus dem Timer raus (kann ja der Worker aufrufen, er hat ja den Sender)
procedure TForm1.Button1Click(Sender: TObject);
var FormWorkProgress : TFormWorkProgress; begin FormWorkProgress := TFormWorkProgress.Create(Application); try FormWorkProgress.WorkerMethode := Worker; FormWorkProgress.ShowModal; finally FormWorkProgress.Free; end; end; procedure TForm1.Worker(Sender : TObject; AProgressBar : TProgressBar); var i : Integer; begin for i := 1 to 100 do begin AProgressBar.Position := i; Sleep(100); Application.ProcessMessages; end; (Sender as TForm).Close; end; €: Etwas angepasst, jetzt stellt sich die App nicht mehr Tod. |
AW: "Bitte warten"-Formular korrekt anzeigen
Hier noch mal zwei Links mit Hintergrundinformationen:
![]() ![]() |
AW: "Bitte warten"-Formular korrekt anzeigen
|
AW: "Bitte warten"-Formular korrekt anzeigen
Vielen Dank für die vielen Antworten. Leider komme ich heute und morgen vllt auch nicht dazu, diese auszuprobieren. Ich melde mich wieder, wenn ich weiterarbeiten konnte.
Danke sehr! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz