[英]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.