2011-08-04 22 views
2

有一個框架(不是一種形式)和一個線程。如何參考Frame的控制線程?例如,我想禁用線程中的按鈕。但是我沒有指向按鈕的指針,幀中沒有全局變量。德爾福:指的是從框架中的線程控制

謝謝!

+0

您的工作方式與沒有線程的方式完全相同,不同之處在於您將所有處理ListView控件的內容都放在一個沒有任何參數的方法中,並且將其從線程調用爲Synchronize(MethodName)。 –

+0

如果使用PostMessage如何設置一個框架的句柄?謝謝! – maxfax

+1

創建線程時,在線程對象中創建一個屬性並將其設置爲'MyThread.NotificationHandle:= MyForm.Handle;' –

回答

7

事實上,根本不應該調用任何方法或修改任何VCL控件的屬性或對用戶可見的任何內容(應用程序的用戶界面,這意味着Delphi中的VCL通常是控件,無論是在框架中或不)直接從後臺線程。

但是,您可以使用PostMessageTThread.SynchronizeTThread.Queue向主線程發送事件或通知。

而不是引用線程對象中的框架或控件,最好將包含框架或其他控件的表單的句柄傳遞給線程,並使用用戶消息(WM_USER + 10001)like this.

我比較喜歡PostMessage到TTHread.Synchronize或Queue,因爲它非常簡單並且效果很好。由於它與Win32 API綁定,因此它不是一個跨平臺友好的技術。

你應該叫同步是這樣的:

TMyThread = class(TThread) 
    private 
    FFrame: TFrame; 
    ... 
    public 
    constructor Create(AFrame: TFrame); 
    ... 
    end; 

    constructor TMyThread.Create(AFrame: TFrame); 
    begin 
    FFrame := AFrame; 
    inherited Create; 
    end; 

    // do not call directly, only using Synchronize 
    procedure TMyThread.AMethodWithNoParameters; 
    begin 
    FFrame.Button1.Enabled := not FBusy; 
    end; 

    procedure TMyThread.DoWork; // called from Execute. 
    begin 
    FBusy := true; 
    Synchronize(AMethodWithNoParameters); 
    Sleep(100); //dummy; 
    FBusy := false; 
    Synchronize(AMethodWithNoParameters); 
    end; 
+0

非常感謝!我使用TThread.Synchronize。 Ho做Button1.Enable:= False使用Synchronize?如何參考按鈕? – maxfax

+1

@maxfax只需暴露給線程那些需要暴露的UI部分。 –

+0

@David Heffernan,謝謝+1!這是如何?我無法準確找到控制。 – maxfax

2

由於正確地指出,你不能調用任何可視組件的任何成員在後臺線程。

要禁用線程代碼中的按鈕,必須具有對按鈕的引用或對可以分配線程對象的事件的引用 - 然後可以在排隊或同步過程內引發線程,如所以: -

type 
     test=class(tthread) 
     ondisablebutton:tnotifyevent; 

{...} 

然後,當你與tthread.synchronize封裝可以調用事件,不要忘記來測試,如果它被分配過程....

procedure test.synchronisedprocedure; 
begin 
    if assigned(ondisablebutton) then 
    ondisablebuttone(self); 
end; 

當你創建你設計的線程對象,那麼你必須在ondisablebutton分配到形式的過程包含它看起來像這樣的按鈕: -

procedure form1.threadwantstodisablebutton(sender:tobject); 
begin 
    button1.enabled:=false; 
end; 

您創建線程則需要一個額外的行: -

mythread:=test.create; 
    test.ondisablebutton:=form1.threadwantstodisablebutton; 

像這樣,明明你必須有權訪問form1(或者包含按鈕的表單),你可以在其中定義和創建你的線程,這不一定是好的設計,但它可以工作。

+0

謝謝!!!但我需要在一個框架中做到這一點,而不是以一種形式。 – maxfax