If the only thing you are trying to do is update the progress bar from the stream, there is a lower weight option. Instead, I would rather use PostMessage. You do not want your thread to know too much about the details of the frame.
When you create a stream, give it a handle to your frame so that it knows where to send the message. Ask the frame to listen to the Windows message, which includes the progress position, and update the progress bar.
Here is a very simple example that increases the execution step 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.
source share