如何在执行期间调用在新组件中创建的过程

Posted

技术标签:

【中文标题】如何在执行期间调用在新组件中创建的过程【英文标题】:How to invoke a procedure created inside the New Component during the implementation 【发布时间】:2021-05-12 17:17:57 【问题描述】:

我已经创建并实现了一个新组件,在这个创建的组件中,有一个过程InitCombo,需要在实现中调用。

我该怎么做?

这是新组件内的过程InitCombo

procedure TNewComponent.InitCombo;       //TComboBox ancestor
begin
  FStoredItems.OnChange := nil;
  StoredItems.Assign(Items);
  AutoComplete := False;
  FStoredItems.OnChange := StoredItemsChange;
  doFilter := True;
  StoredItemIndex := -1;
end;

这是我尝试调用但返回错误消息:

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  TNewComponent.InitCombo;
end;

Error Messages
[dcc32 Error] makeasale_u_v1.pas(84): E2076 This form of method call only allowed for class methods or constructor

请注意,编译、构建、安装都进行得很顺利并且可以正常工作。除了如何调用组件内部的过程?

【问题讨论】:

TNewComponent 是一种类型。您不能在类型上调用方法;你必须有一个实例。目前尚不清楚您实际上要做什么,因此很难提供帮助。另外,Procedure 是 Delphi/Pascal 中的关键字,所以不要将过程命名为 Procedure。这是您提供 minimal reproducible example 来演示问题的好地方,而不是编写甚至无法编译的代码。 您可以在运行时分配事件! @DelphiCoder Calss hack:你的意思是 interposer 类吗? 插入器类与其派生的名称相同,例如TComboBox = 类(StdCtrls.TComboBox)。现在您可以访问原始 TComboBox 的私有和受保护字段以及方法/属性。 请不要在 cmets 中进行此讨论,请edit 您的问题并将相关详细信息添加到问题中,以便可以看到它们。您需要清楚具体地了解您想要做什么,这样我们就不必玩“20 个问题”来从您那里获取信息。 【参考方案1】:

仅基于您问题第一段的以下部分

有一个过程 InitCombo 需要在实现中调用。

您似乎对编写组件的一些事情感到困惑。

首先,您可以在其构造函数中初始化组件属性以初始化事物,或者在覆盖的Loaded 方法中初始化,该方法在组件从使用该组件的 .dfm 文件流式传输后调用。请注意,Loaded 更改不应触及用户可以在 Object Inspector 中设置的属性或事件,因为这样做会阻止使用用户的设置。

constructor TNewComponent.Create(AOwner: TComponent);
begin
  inherited;
  // Do your stuff here
end;

procedure TNewComponent.Loaded;
begin
  // Do your stuff here
end;

其次,发布的事件(可以在对象检查器的事件选项卡中看到)属于使用组件的程序员,而不是组件作者。永远不要对那些事件处理程序做任何事情。如果最终用户分配了处理程序,您的组件不应该接触这些事件,除非调用它们。所以下面的代码是绝对不正确的,因为OnChange事件属于你组件的用户,而不是你的组件代码:

procedure TNewComponent.InitCombo;       //TComboBox ancestor
begin
  FStoredItems.OnChange := nil;
  ...
  FStoredItems.OnChange := StoredItemsChange;
end;

如果您绝对必须这样做,则需要通过保存最终用户分配的任何事件处理程序来正确执行此操作,然后再将其恢复:

procedure TNewComponent.InitCombo;
var
  OldOnChange: TNotifyEvent;
begin
  OldOnChange := Self.OnChange;
  // Do your stuff here
  Self.OnChange := OldOnChange;
end;

第三,除非您使用class procedureclass function,否则您不能调用类本身的方法(换句话说,您不能使用TNewComponent.DoSomething)。您在组件本身的实例上调用方法或访问属性。在您的组件代码中,这将通过使用 Self 来完成,它指的是当前实现的组件,如 Self.DoSomething

【讨论】:

非常感谢。这对我非常有用。欣赏它。

以上是关于如何在执行期间调用在新组件中创建的过程的主要内容,如果未能解决你的问题,请参考以下文章

如何导出在 storybook 中创建的 React Native 组件以便在实际应用中使用?

在 Terraform 中,如何在包含的模块中引用根模块中创建的组件

如何调用在另一个函数中创建的对象

如何在 VBA 的另一个函数中调用我在 VBA 中创建的函数?

你如何调用在javascript中的数组中创建的对象的函数?

如何在 Qt 的后续函数调用中访问在函数中创建的小部件