什么是Delphi相当于C#在窗体上的调用操作(如何在Delphi中调用)?

Iva*_*nov 0 c# forms delphi invoke winforms

在我的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);
    }
Run Code Online (Sandbox Code Playgroud)

"FormMain"中的构造函数是:

    public FormMain()
    {
        InitializeComponent();
        singletonInstance = this;
    }
Run Code Online (Sandbox Code Playgroud)

我不知道如何在Delphi中做到这一点.

问题(Delphi):当Im在其类之外时,我如何在表单上更改某些内容(例如Edit1.Text),Invoke?

提前致谢!

mgh*_*hie 8

Invoke()操作的需要与调用代码在其类内部或外部无关,有必要确保仅在创建控件的线程的上下文中调用操作控件的方法.控件具有线程关联,它不是C#或.NET特有的,它是Windows工作方式中固有的.控件/窗口的消息只能在创建它的线程中处理.对于Delphi来说也是如此,整个VCL也不是线程安全的.

最接近Invoke()的Delphi VCL是Synchronize()方法.它在辅助线程中用于调度要在主VCL线程(需要创建所有VCL控件的用户界面线程)的上下文中执行的代码,因此处理这些控件的所有Windows消息,并且唯一一个真正安全地调用任何控制方法.

Delphi程序本身不会创建任何辅助线程,您必须自己完成.但除非你这样做,否则一切都发生在主线程上下文中,并且不需要调用Synchronize().您只需调用需要调用的方法即可.

继续您的示例:为编辑控件设置新文本,如下所示:

Form1.Edit1.Text := 'foo bar baz';
Run Code Online (Sandbox Code Playgroud)

这假设包含TForm1该类的单元包含一个Form1通常所做的变量.这类似于C#代码中的单例.它的工作原理是因为放在表单上的所有控件都具有公共可见性.

偏离主题的评论:

请注意,虽然这是相当常见的代码,但它违反了得墨忒耳定律.更改表单中的控件将使得有必要随后更改以这种方式访问​​它们的所有代码.但这完全是另一个讨论.