If the only thing you're trying to do is update the progress bar from the thread, there is a lighter weight option. I would consider using PostMessage instead. You don't want your thread to know too much about the details of the frame anyway.
When you create the thread, give it the handle of your frame so it knows where to post the message. Have the frame listen for the Windows message, which includes the progress position, and update the progress bar.
Here is a very simple example that increments the progress bar from 0 to 100 with a short sleep between each increment:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
const
WM_PROGRESS_MESSAGE = WM_USER + 99;
type
TProgressThread = class(TThread)
private
FWindowHandle: HWND;
protected
procedure Execute; override;
public
property WindowHandle: HWND read FWindowHandle write FWindowHandle;
end;
TFrame2 = class(TFrame)
ProgressBar1: TProgressBar;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure OnProgressMessage(var Msg: TMessage); message WM_PROGRESS_MESSAGE;
public
end;
implementation
{$R *.dfm}
{ TFrame2 }
procedure TFrame2.Button1Click(Sender: TObject);
var
lThread: TProgressThread;
begin
lThread := TProgressThread.Create(True);
lThread.FreeOnTerminate := True;
lThread.WindowHandle := Self.Handle;
lThread.Start;
end;
procedure TFrame2.OnProgressMessage(var Msg: TMessage);
begin
ProgressBar1.Position := Msg.WParam;
end;
{ TProgressThread }
procedure TProgressThread.Execute;
var
lProgressCount: Integer;
begin
inherited;
for lProgressCount := 0 to 100 do
begin
PostMessage(FWindowHandle, WM_PROGRESS_MESSAGE, lProgressCount, 0);
Sleep(15);
end;
end;
end.
Unit1.Form1.ProgressBar, put 'Unit1' in the uses clause of the implementation section of the thread unit. Or, is it a long shot? - Sertac Akyuz