下午好:-), 我有一个框架。此框架由Main Form动态创建。
主要形式:
Interface := TInterface.Create(self);
with handlingInterface do begin
Parent := Form1;
Left := 0; Top := 35;
Width := 570; Height := 250;
end;
在Frame中我有一个Thread。我从Frame调用这个Thread。为什么我可以将Thread与Frame同步?没有:
var
Form1: TForm1;
我调用Frame内的线程,我想更改 ProgressBar in Frame 的位置。我不知道,为什么我可以在Thread的Synchronize方法中访问ProgressBar。
如果是Form中的Thread和ProgressBar - 同步访问是Form1.ProgressBar ......
但我在 Frame 中有Thread和ProgressBar。
答案 0 :(得分:9)
如果你要做的唯一事情是从线程更新进度条,那么有一个更轻的权重选项。我会考虑使用PostMessage。你不希望你的线程过多地了解框架的细节。
创建线程时,请为其提供框架的句柄,以便知道在何处发布消息。让框架侦听Windows消息,其中包括进度位置,并更新进度条。
这是一个非常简单的示例,它将进度条从0递增到100,每次增量之间的睡眠时间很短:
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.
答案 1 :(得分:2)
您可以在线程中提供进度条的引用。
示例线程类。
unit Unit6;
interface
uses
Classes, ComCtrls;
type
TProgressBarThread = class(TThread)
private
{ Private declarations }
FProgressBar: TProgressBar;
procedure MoveProgress;
protected
procedure Execute; override;
public
procedure SetProgressBar(ProgressBar: TProgressBar);
end;
implementation
{ ProgressBarThread }
procedure TProgressBarThread.Execute;
begin
{ Place thread code here }
Synchronize(MoveProgress);
end;
procedure TProgressBarThread.MoveProgress;
begin
FProgressBar.StepIt;
end;
procedure TProgressBarThread.SetProgressBar(ProgressBar: TProgressBar);
begin
FProgressBar := ProgressBar;
end;
end.
像这样使用
var
PBT: TProgressBarThread;
begin
PBT := TProgressBarThread.Create(True);
PBT.FreeOnTerminate := True;
PBT.SetProgressBar(ProgressBar1);
PBT.Start;
// PBT.Resume;
end;