Что является эквивалентом Delphi для действия по вызову C # в форме (Как вызвать в Delphi)? - PullRequest
0 голосов
/ 27 июня 2009

В моем проекте на 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?

Заранее спасибо!

1 Ответ

8 голосов
/ 27 июня 2009

Необходимость Invoke () действие не имеет никакого отношения к вызывающему коду, находящемуся внутри или вне его класса, необходимо убедиться, что методы, работающие с элементами управления, вызываются только в контексте поток, в котором был создан элемент управления. Элементы управления имеют сходство потоков, которое не является специфичным для C # или .NET, оно присуще тому, как работает Windows. Сообщения для элемента управления / окна могут обрабатываться только в том потоке, в котором он был создан. Это относится и к Delphi, и весь VCL также не является поточно-ориентированным.

Наиболее близким к Invoke () Delphi VCL является метод Synchronize () . Он используется во вторичных потоках, чтобы запланировать выполнение кода в контексте основного потока VCL, потока пользовательского интерфейса, в котором необходимо создать все элементы управления VCL, в результате чего обрабатываются все сообщения Windows для этих элементов управления, и который единственный действительно безопасный для вызова любого из методов управления.

Программа Delphi сама по себе не создает никаких дополнительных потоков, вам придется делать это самостоятельно. Но если вы этого не сделаете, все происходит в контексте основного потока, и нет необходимости вызывать Synchronize () . Вы можете просто вызвать метод, который вам нужен.

Чтобы остаться в вашем примере: Вы устанавливаете новый текст для элемента управления редактирования так:

Form1.Edit1.Text := 'foo bar baz';

Предполагается, что модуль, содержащий класс TForm1, содержит переменную Form1, что обычно и происходит. Это похоже на синглтон в вашем коде C #. Это работает, потому что все элементы управления, помещенные в форму, будут иметь публичную видимость.

Off-Topic-замечанием

Обратите внимание, что хотя это довольно распространенный код, он нарушает Закон Деметры . Изменение элементов управления в форме приведет к необходимости впоследствии изменить весь код, который обращается к ним таким образом. Но это совсем другое обсуждение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...