Delphi - 将线程与帧同步

时间:2011-03-13 14:46:33

标签: multithreading delphi forms frame

下午好:-), 我有一个框架。此框架由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。

2 个答案:

答案 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;