gpt4 book ai didi

delphi - 如何正确发布从 'Loaded' 过程执行的事件?

转载 作者:行者123 更新时间:2023-12-03 15:44:47 25 4
gpt4 key购买 nike

在仅运行时的包中,我定义了一个 TFrame 后代,它发布 OnLoaded 事件:

type
TMyMethod = procedure() of object;

TMyFrame = class(TFrame)
protected
FOnLoaded : TMyMethod;
procedure Loaded(); override;
published
property OnLoaded : TMyMethod read FOnLoaded write FOnLoaded;
end;

implementation

{$R *.dfm}

procedure TMyFrame.Loaded();
begin
inherited;
if(Assigned(FOnLoaded))
then FOnLoaded();
end;

在仅设计时的包中,我注册了 TMyFrame 组件,如下所示:

unit uMyRegistrations;

interface

uses
Classes, uMyFrame;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('MyTestComponents', [
TMyFrame
]);
end;

我已经安装了设计时包,我可以在工具选项板中找到TMyFrame,并且它的OnLoaded事件显示在对象检查器中。

我已将 TMyFrame 拖动到表单中,然后通过从对象检查器中双击来分配 OnLoaded 事件。分配事件后,我注意到每次尝试在 Delphi 中打开表单文件时都会出现访问冲突错误消息(它让我打开“.pas”文件,但无法切换到可视设计器 View )。

enter image description here

我是否正确发布了 OnLoaded 事件?如果是这样,还有什么问题吗?

更多信息:

  1. 我正在使用 Delphi 2007(不知道这是否重要)。
  2. 通过对不同的父类执行相同的操作也会出现该错误(不仅适用于 TFrame 后代)。

最佳答案

更新(不太虚假)答案

你接受了我原来的答案,但我写的不正确。罗布·肯尼迪指着article由前 Embarcadero 开发人员 Allen Bauer 撰写,主题为Assigned

Allen 解释说,Assigned 函数仅测试方法指针中两个指针中的一个指针。 IDE 在设计时通过将哨兵值分配给任何已发布的方法属性(即事件)来利用这一点。这些哨兵值对于方法指针中的两个指针之一(Assigned 检查的指针)具有 nil ,以及标识另一个指针中的属性值的索引。

所有这些意味着当您在设计时调用Assigned 时,将返回False。只要您在调用已发布的方法指针之前使用 Assigned 检查它们,那么您就永远不会在设计时调用它们。

所以我最初写的不可能是真的。

所以我挖得更深一些。我使用了以下非常简单的代码,使用 XE7 进行测试:

type
TMyControl = class(TGraphicControl)
protected
FSize: Integer;
procedure Loaded; override;
end;

....

procedure TMyControl.Loaded;
begin
inherited;
FSize := InstanceSize;
end;

....

procedure Register;
begin
RegisterComponents('MyTestComponents', [TMyControl]);
end;

每当执行 Loaded 方法时,这足以在设计时在 IDE 中引发 AV。

我的结论是,IDE 在流式传输时做了一些相当不正当的事情,并且当调用 Loaded 方法时,您的对象不处于适合使用的状态。但我确实没有比这更好的理解了。

<小时/>

原始(非常虚假)答案

您不得在设计时执行事件处理程序,而您的代码就是这样做的。原因是在设计时事件处理程序的代码不可用。

控件的代码可用,IDE 已加载它 - 但实现事件处理程序的代码不可用。该代码不是设计时包的一部分,而是当前在 IDE 中打开的项目的一部分。毕竟,它甚至可能还没有编译!

Loaded 方法应该像这样防御这种情况:

procedure TMyFrame.Loaded();
begin
inherited;
if not (csDesigning in ComponentState) and Assigned(FOnLoaded) then
FOnLoaded();
end;

关于delphi - 如何正确发布从 'Loaded' 过程执行的事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39959790/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com