Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update progress indicator from a second thread?

I have a main form with a progress indicator on it. In the datamodule I've ten datasets, each of them has an OnBeforeOpen event defined.

I would like to show through the progress bar in the main form a percentage of progress of the opened datasets.

Since I'm completely new to multithreading programming, can someone please give me some advice?

Thank you very much

like image 307
Fabio Vitale Avatar asked Apr 03 '13 08:04

Fabio Vitale


1 Answers

Either post a message from the thread to the main thread and update the progress bar from there or use the TThread.Queue method to execute some code in the context of the main thread.

unit Unit12;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;

const
  WM_UPDATE_PB = WM_USER;

type
  TForm12 = class(TForm)
    ProgressBar1: TProgressBar;
    ProgressBar2: TProgressBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
    procedure WMUpdatePB(var msg: TMessage); message WM_UPDATE_PB;
  end;

var
  Form12: TForm12;

implementation

{$R *.dfm}

procedure UpdateFromThreadViaMessage;
var
  i: integer;
begin
  for i := 1 to 100 do begin
    Sleep(20);
    PostMessage(Form12.Handle, WM_UPDATE_PB, i, 0);
  end;
end;

procedure UpdateFromThreadViaQueue;
var
  i: integer;
begin
  for i := 1 to 100 do begin
    Sleep(20);
    TThread.Queue(nil,
      procedure begin
        Form12.ProgressBar2.Position := i;
      end);
  end;
end;

procedure TForm12.Button1Click(Sender: TObject);
begin
  TThread.CreateAnonymousThread(UpdateFromThreadViaMessage).Start;
  TThread.CreateAnonymousThread(UpdateFromThreadViaQueue).Start;
end;

procedure TForm12.WMUpdatePB(var msg: TMessage);
begin
  ProgressBar1.Position := msg.WParam;
end;

end.
like image 144
gabr Avatar answered Oct 22 '22 11:10

gabr