回答
事實上,根本不應該調用任何方法或修改任何VCL控件的屬性或對用戶可見的任何內容(應用程序的用戶界面,這意味着Delphi中的VCL通常是控件,無論是在框架中或不)直接從後臺線程。
但是,您可以使用PostMessage
或TThread.Synchronize
或TThread.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;
由於正確地指出,你不能調用任何可視組件的任何成員在後臺線程。
要禁用線程代碼中的按鈕,必須具有對按鈕的引用或對可以分配線程對象的事件的引用 - 然後可以在排隊或同步過程內引發線程,如所以: -
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(或者包含按鈕的表單),你可以在其中定義和創建你的線程,這不一定是好的設計,但它可以工作。
謝謝!!!但我需要在一個框架中做到這一點,而不是以一種形式。 – maxfax
- 1. 德爾福通用框架
- 2. 德爾福 - 的控制面板中的
- 3. 德爾福:框架的TList的問題
- 4. 德爾福多線程CMD
- 5. 德爾福:一個線程
- 6. 德爾福:CopyFileEx和線程
- 7. 德爾福線程與TRestRequest
- 8. 德爾福微控制器編程
- 9. 德爾福TTask從主線程
- 10. 德爾福v.Word - 如何從德爾福
- 11. 德爾福的DragDrop組件在線程
- 12. 德爾福 - 終止阻塞的線程
- 13. 線程安全的德爾福
- 14. 的ActiveX德爾福阻塞線程VCL
- 15. 德爾福 - Omnithreadlibrary,控制檯應用程序中的主線程死亡
- 16. 從德爾福ADOStoredProc
- 17. 德爾福 - 從TPanel
- 18. 德爾福指針鑄造
- 19. 德爾福控制檯管道切換?
- 20. 德爾福firemoneky控制在運行時
- 21. 控制+點擊凍結德爾福XE
- 22. 德爾福:組件和控件不適用於框架
- 23. 德爾福 - 同步線程與幀
- 24. 德爾福線程不運行
- 25. 多線程德爾福停止
- 26. 德爾福訪問線程變量
- 27. 德爾福COM EXE和線程
- 28. 德爾福 - 跨線程事件處理
- 29. 德爾福事件處理無線程
- 30. 背景工作線程德爾福2010
您的工作方式與沒有線程的方式完全相同,不同之處在於您將所有處理ListView控件的內容都放在一個沒有任何參數的方法中,並且將其從線程調用爲Synchronize(MethodName)。 –
如果使用PostMessage如何設置一個框架的句柄?謝謝! – maxfax
創建線程時,在線程對象中創建一個屬性並將其設置爲'MyThread.NotificationHandle:= MyForm.Handle;' –