[英]What is Delphi's equivalent of C#'s invoke action on form(How to invoke in Delphi)?
在我的C#項目中,我使用以下代碼在自己的類之外訪問表單。
public static FormMain singletonInstance { get; private set; }
public static void PFA(Action<FormMain> action) //PFA = PerForm Action
{
var form = FormMain.singletonInstance;
if (form != null)
{
form.PerformAction(action);
}
}
public void PerformAction(Action<FormMain> action)
{
if (InvokeRequired)
Invoke(action, this);
else
action(this);
}
而“ FormMain”中的構造函數為:
public FormMain()
{
InitializeComponent();
singletonInstance = this;
}
我不知道如何在Delphi中做到這一點。
問題(Delphi):我在類之外調用時,如何更改表單上的某些內容(例如Edit1.Text)?
提前致謝!
Invoke()動作的需要與該類內部或外部的調用代碼無關,必須確保僅在創建該控件的線程的上下文中調用對控件進行操作的方法。線程親和力,不是C#或.NET特有的,它是Windows工作方式所固有的。 控件/窗口的消息只能在其創建的線程中處理。 Delphi也是如此,整個VCL也不是線程安全的。
與Delphi VCL最接近的Invoke ()方法是Synchronize()方法。 它在輔助線程中用於計划要在主VCL線程(需要在其中創建所有VCL控件的用戶界面線程)的上下文中執行的代碼,因此將在這些VCL控件的所有Windows消息均得到處理的情況下進行處理。唯一真正安全的調用任何控制方法的方法。
Delphi程序不會自行創建任何輔助線程,您必須自己執行此操作。 但是,除非您這樣做,否則所有操作都會在主線程上下文中發生,並且無需調用Synchronize() 。 您可以簡單地調用您需要調用的方法。
為了保持您的示例:您為編輯控件設置新文本,如下所示:
Form1.Edit1.Text := 'foo bar baz';
假定包含TForm1
類的單元通常包含一個變量Form1
。 這類似於C#代碼中的單例。 之所以有效,是因為放置在表單上的所有控件都具有公共可見性。
題外話 :
請注意,盡管這是相當常見的代碼,但它違反了Demeter定律 。 更改表單中的控件將需要隨后更改以此方式訪問它們的所有代碼。 但這完全是另一個討論。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.