AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Progress Form/Dialog VCL

Ein Thema von lxo · begonnen am 28. Sep 2018 · letzter Beitrag vom 2. Okt 2018
Antwort Antwort
Seite 1 von 2  1 2      
lxo

Registriert seit: 30. Nov 2017
260 Beiträge
 
Delphi 12 Athens
 
#1

Progress Form/Dialog VCL

  Alt 28. Sep 2018, 16:10
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?
  Mit Zitat antworten Zitat
API

Registriert seit: 18. Apr 2004
637 Beiträge
 
#2

AW: Progress Form/Dialog VCL

  Alt 28. Sep 2018, 16:23
Hast du so etwas in dieser Art schon probiert?


https://www.thoughtco.com/synchroniz...cation-1058159
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.418 Beiträge
 
Delphi 7 Professional
 
#3

AW: Progress Form/Dialog VCL

  Alt 28. Sep 2018, 16:43
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;
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.468 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Progress Form/Dialog VCL

  Alt 28. Sep 2018, 16:47
Je öfter ich Application.ProcessMessages auslöse umso langsamer wird der Import.
Eine Möglichkeit wäre, vor einem Aufruf von Application.ProcessMessages zu prüfen, wie lange der letzte Aufruf her ist. Erst dann, wenn das vor mehr als z.B. 100 ms war, wird dann Application.ProcessMessages aufgerufen:

Delphi-Quellcode:
var
  LastCall: Int64;
  ThisCall: Int64;

[...]
  ThisCall := GetTickCount;
  if (ThisCall - LastCall > 100) or (LastCall > ThisCall) then begin
    Application.ProcessMessage;
    LastCall := ThisCall;
  end;
Thomas Mueller
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Progress Form/Dialog VCL

  Alt 28. Sep 2018, 17:06
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.
Heiko
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#6

AW: Progress Form/Dialog VCL

  Alt 29. Sep 2018, 00:03
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.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

AW: Progress Form/Dialog VCL

  Alt 29. Sep 2018, 11:41
Im Anhang hatte ich mal den Progress-Dialog von Windows gekapselt. Vielleicht ist der ja was für dich.
Angehängte Dateien
Dateityp: pas dxProgressDialog.pas (11,4 KB, 54x aufgerufen)
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
260 Beiträge
 
Delphi 12 Athens
 
#8

AW: Progress Form/Dialog VCL

  Alt 30. Sep 2018, 10:49
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.
Genau sowas habe ich probiert nur leider nicht richtig hingekriegt.
Hättest du da vielleicht ein Beispiel wie man so etwas angeht?
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#9

AW: Progress Form/Dialog VCL

  Alt 30. Sep 2018, 11:30
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:
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;
Thread
Delphi-Quellcode:
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.
Das ist jetzt einfach nur schnell hingeschrieben. Die Kernfunktionalität (WndProc, PostMessage, Thread), sollte aber klar sein.

Geändert von DieDolly (30. Sep 2018 um 13:08 Uhr)
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
260 Beiträge
 
Delphi 12 Athens
 
#10

AW: Progress Form/Dialog VCL

  Alt 1. Okt 2018, 07:11
Danke für die Tipps.
Ich werde mir das diese Woche mal anschauen alles und danach berichten.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:06 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