2011-03-13 57 views
2

下午好:-), 我有一个帧。这个框架是由主窗体动态创建的。德尔福 - 同步线程与帧

主要形式有:

Interface := TInterface.Create(self); 
    with handlingInterface do begin 
     Parent := Form1; 
     Left := 0; Top := 35; 
     Width := 570; Height := 250; 
    end; 

在框架我有一个线程。我从框架调用这个线程。为什么我可以同步线程与框架?没有任何:

var 
Form1: TForm1; 

内框调用线程,我想改变进度的位置框架。我不知道,为什么我可以在Thread的Synchronize方法中访问ProgressBar。

如果将表格主题和进度 - 同步访问Form1.ProgressBar ...

但我有螺纹和进度在框架

+0

@Nanik:你是什么意思我在这种情况下同步?究竟需要什么同步?如果你使用TThread的相应成员函数,你已经得到你想要的,因为它有效地运行主线程中的相应代码而不是TThread派生的实例。 – 0xC0000022L 2011-03-13 14:50:46

+0

感谢评论,我编辑帖子。 – Nanik 2011-03-13 15:01:51

+0

'Unit1.Form1.ProgressBar',把'Unit1'放在线程单元实现部分的uses子句中。或者,这是一个长镜头? – 2011-03-13 15:31:42

回答

1

你可以给你的进度条线的参考。

示例线程类。

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; 
+4

我知道世界上每个人都使用TThread.Synchronize就像它是世界上唯一的线程安全机制。但是在这种情况下,发布信息要好得多。 – 2011-03-13 19:29:34

+1

@Warren我完全同意。我投了@Bruce的回答。不过,我认为这个答案对@Nanik有些帮助,可能是作为使用邮件的第一步。 – 2011-03-13 19:45:13

8

如果您想要做的唯一的事情是从线程更新进度栏,那么有一个更轻的选项。我会考虑使用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.