2011-03-13 4 views
2

안녕하세요 :-), 프레임이 하나 있습니다. 이 프레임은 메인 폼에 의해 동적으로 생성되었습니다.Delphi - 프레임과 스레드 동기화

홈페이지 형태 : 프레임에서

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

나는 스레드가 있습니다. 프레임에서이 스레드를 호출합니다. 스레드와 프레임을 동기화 할 수있는 이유는 무엇입니까? 프레임 내부

var 
Form1: TForm1; 

I 호출 스레드와 나는 프레임의 ProgressBar의 위치를 ​​변경하려면 :이 어떤 없습니다. 나도 몰라. 왜 스레드 접근 방식을 ProgressBar와 동기화 할 수 있나. ... 액세스 Form1.ProgressBar입니다

동기화하지만 프레임에 스레드와의 ProgressBar이 -

경우 양식에 스레드와의 ProgressBar 될 것이다.

+0

@Nanik 같은

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. 

사용 : 어떻게 당신이이 경우에 내 동기화를 의미합니까? 동기화가 정확히 필요한 것은 무엇입니까? TThread의 해당 멤버 함수를 사용하면 TThread 파생 인스턴스 대신 주 스레드에서 해당 코드를 효과적으로 실행하기 때문에 원하는 것을 이미 얻을 수 있습니다. – 0xC0000022L

+0

코멘트 덕분에 게시물을 편집합니다. – Nanik

+0

'Unit1.Form1.ProgressBar', 스레드 유닛의 구현 섹션의 uses 절에 'Unit1'을 넣으십시오. 아니면, 긴 총입니까? –

답변

1

당신은 스레드 진행 막대에 대한 참조를 제공 할 수 있습니다 :

다음은 각 증분 사이에 짧은 수면 0부터 100까지 진행 막대를 증가하는 매우 간단한 예입니다.

샘플 스레드 클래스. 이

var 
    PBT: TProgressBarThread; 
begin 
    PBT := TProgressBarThread.Create(True); 
    PBT.FreeOnTerminate := True; 
    PBT.SetProgressBar(ProgressBar1); 
    PBT.Start; 
// PBT.Resume; 
end; 
+4

전 세계의 모든 사용자가 TThread.Synchronize를 사용한다는 것은 전 세계의 유일한 스레드 안전 메커니즘 인 것처럼 알고 있습니다. 그러나 게시물 메시지는이 경우에 훨씬 좋습니다. –

+1

@Warren 전적으로 동의합니다. @ Bruce의 답변에 투표했습니다. 그러나 나는이 답변이 @Nanik에게 다소 도움이된다고 생각합니다. 아마도 게시물 메시지를 사용하기위한 첫 단계 일 것입니다. –

8

스레드에서 진행률 표시 줄을 업데이트하려는 경우, 더 가벼운 옵션이 있습니다. 대신 PostMessage를 사용하는 것이 좋습니다. 어쨌든 프레임의 세부 사항에 대해 스레드가 너무 많이 알기를 원하지는 않습니다.

스레드를 만들 때 메시지를 게시 할 위치를 알 수 있도록 프레임의 핸들을 지정하십시오. 프레임이 진행 상태를 포함하는 Windows 메시지를 청취하도록하고 진행률 표시 줄을 업데이트하십시오.

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.