2011-03-13 126 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.