![]() |
Progress Form/Dialog VCL
Hallo,
folgende/s Frage/Problem habe ich. Ich habe eine Funktion die Daten aus Textdateien in eine Datenbank importiert. Da in den Textdateien einige tausend Datensätze enthalten sind, dauert dies ein paar Sekunden. Für diesen Fall würde ich gerne eine Fortschrittsanzeige anzeigen. Jedoch nicht direkt auf meinem Form sondern auf einem extra Dialog/Form der/das im Vordergrund steht und weiterhin bedienbar ist, die Form im Hintergrund sollte während dessen blockiert sein. Momentan habe ich einfach beim starten des Imports eine zweite Form geöffnet, die ich während des Import immer mal wieder aktualisiere in dem ich den Text ändere bzw. die Position einer Progessbar hochzähle und ein Application.ProcessMessages auslöse. Das funktioniert, leider nicht so wie ich das möchte. Je öfter ich Application.ProcessMessages auslöse umso langsamer wird der Import. Wenn ich jedoch Application.ProcessMessages nicht so oft auslöse, hängt die Fortschrittsanzeige bis ich wieder Application.ProcessMessages auslöse, auch bei Progessbar.Style [pbstMarquee]. Ich hab schon alles mögliche mit Threads probiert, nur irgendwie kriege ich es einfach nicht hin... Also, ich hätte gerne einfach einen weiteren Dialog der den Fortschritt meines Imports live anzeigt und weiterhin bedienbar ist und das HauptFormular blockiert. Kann mir da jemand paar Tipps geben? |
AW: Progress Form/Dialog VCL
Hast du so etwas in dieser Art schon probiert?
![]() |
AW: Progress Form/Dialog VCL
Wie änderst Du die Progressbar?
Mal ein Beispiel (schemahaft):
Delphi-Quellcode:
begin
Stringliste.LoadFromFile('irgendeine.datei'); Progressbar.Min := 0; Progressbar.Position := 0; Progressbar.Max := Stringliste.Count; for i := 0 to Stringliste.Count - 1 do begin FunktionDieDieZeileIndDiDatenbankBringt(Stringliste[i]); if i Mod 100 = 0 then // statt der 100 was Größeres oder Kleineres nehmen, jenachdem, wie schnell das Ganze ist ... Progressbar.Position := i; Application.ProcessMessages; end; end; end; |
AW: Progress Form/Dialog VCL
Zitat:
Delphi-Quellcode:
var
LastCall: Int64; ThisCall: Int64; [...] ThisCall := GetTickCount; if (ThisCall - LastCall > 100) or (LastCall > ThisCall) then begin Application.ProcessMessage; LastCall := ThisCall; end; |
AW: Progress Form/Dialog VCL
Hallo,
oder du aktualisierst den Progressbar PB alle 5% des weiteren Datenfortschritts, also PB.Pos mod PB.Max=0 (oder so ähnlich). Dann sind das nur 20 Aufrufe, der Nutzer sieht aber trotzdem, dass es weitergeht. |
AW: Progress Form/Dialog VCL
Oder man lagert den Import in einen Thread aus und schickt per PostMessage Nachrichten an WndProc oder einen eigenen MessageHandler, wertet dort die Message aus und setzt die GUI.
So blockieren sich Import und GUI nicht gegenseitig. |
AW: Progress Form/Dialog VCL
Liste der Anhänge anzeigen (Anzahl: 1)
Im Anhang hatte ich mal den Progress-Dialog von Windows gekapselt. Vielleicht ist der ja was für dich.
|
AW: Progress Form/Dialog VCL
Zitat:
Hättest du da vielleicht ein Beispiel wie man so etwas angeht? |
AW: Progress Form/Dialog VCL
Ich bastel gleich mal eine Demo. Die Profis werden mich für den Code vermutlich zerreißen. Aber das ist das Resultat aus verschiedensten Empfehlungen.
Demo kommt gleich. Hauptunit
Delphi-Quellcode:
Thread
type
TForm1 ... private ... ProgressThread: TProgressThread; public ... procedure WndProc(var msg: TMessage); override; end; const WM_PROGRESS_SET = WM_USER + 1; implementation {$R *.dfm} procedure TForm1.WndProc(var msg: TMessage); begin inherited; case msg.msg of WM_PROGRESS_SET: begin ProgressBar1.Position := msg.WParam; end; end; end; procedure TForm1.Button1Click(Sender: TObject); begin ProgressBar1.Max := 1000; ProgressThread := TProgressThread.Create(Form1.Handle); end;
Delphi-Quellcode:
Das ist jetzt einfach nur schnell hingeschrieben. Die Kernfunktionalität (WndProc, PostMessage, Thread), sollte aber klar sein.
unit uProgressThread;
interface uses Winapi.Windows, System.Classes; type TProgressThread = class(TThread) protected var DestinationWindowHandle: THandle; private {Private-Deklarationen} protected procedure Execute; override; public constructor Create(const DestinationWindowHandle: THandle); end; implementation uses Unit1; {TProgressThread} constructor TProgressThread.Create(const DestinationWindowHandle: THandle); begin inherited Create; Self.DestinationWindowHandle := DestinationWindowHandle; end; procedure TProgressThread.Execute; var i: Integer; begin for i := 0 to 1000 do begin if Terminated then Break; PostMessage(DestinationWindowHandle, WM_PROGRESS_SET, i, 0); Sleep(25); end; end; end. |
AW: Progress Form/Dialog VCL
Danke für die Tipps.
Ich werde mir das diese Woche mal anschauen alles und danach berichten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:41 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 by Thomas Breitkreuz