为什么我会收到此错误消息:未声明的标识符:'OnClick'
我正在使用Delphi 7,这是我的完整代码:
procedure TForm1.Button1Click(Sender: TObject);
var
SavedOnClick : TNotifyEvent;
begin
SavedOnClick := TControl(Sender).OnClick;
try
// Code which takes some time
finally
TControl(Sender).OnClick := SavedOnClick;
end;
end;
答案 0 :(得分:10)
投射时,请使用TButton
代替TControl
。 OnClick
的{{1}}属性受到保护。
答案 1 :(得分:2)
如果查看TControl,OnClick属性被定义为protected。 IE除了后代类外,它是不可见的。有两个简单的方法,首先是使用TButton(发件人)。单击第二个将创建一个hack类,您可以使用它来到属性:
type
TControlOnClickHack = class(TControl)
published
property OnClick;
end;
然后使用TControlOnClickHack(发件人)。单击
警告,在决定使用后面的想法之前,请确保您的发件人有onClick事件。 TypInfo提供了一个名为IsPublishedProp的函数,在尝试取消设置/设置属性之前,最好先使用它。
答案 2 :(得分:1)
在与希望访问受保护成员的代码相同的单元中声明扩展 TControl 的类( OnClick 受 TControl 保护)。
由于新类位于单元中,因此我们可以直接从同一单元中的其他类访问受保护的成员。它没有(我会说“不应该”)需要在界面,因为它严格来说是你单位的实施细节:
unit ... ;
interface
:
implementation
:
type
TControlHelper = class(TControl);
// Now we can type-cast to the "helper" class to gain access
// to the protected members of the ancestor:
procedure TForm1.Button1Click(Sender: TObject);
var
SavedOnClick : TNotifyEvent;
begin
if Sender is TControl then
SavedOnClick := TControlHelper(Sender).OnClick;
try
// Code which takes some time
finally
if (Sender is TControl) then
TControlHelper(Sender) := SavedOnClick;
end;
end;
请注意,在检查发件人的类型时,我们会检查所需的祖先类的实例,因为它不会是我们的帮助程序类本身的实例。 TControl 的任何对象都可以作为 TControlHelper 安全地访问,无论它可能是实例的实际派生类。
出于这个原因,我不同意这是一个“黑客”,因为它具有我不认为应该适用的负面含义 - 这里没有任何不安全或易于破解的内容。这是一种利用语言功能的技术,仅此而已。
注意:我把这个类称为 TControlHelper ,但它不是Delphi 2007(?)及后来定义和实现的“类助手”,尽管它有大约90%的共同点你可以实现的,事实上imho比那些“真正的”帮助者更安全。
此外,您可以通过利用绝对关键字来清理类型转换,只要您保持类型检查到位,这是完美的(好,就像硬铸造一样安全),功能相同,阅读imho更清洁:
procedure TForm1.Button1Click(Sender: TObject);
var
control: TControlHelper absolute Sender;
SavedOnClick : TNotifyEvent;
begin
if Sender is TControl then
SavedOnClick := control.OnClick;
try
// Code which takes some time
finally
if (Sender is TControl) then
control.OnClick := SavedOnClick;
end;
end;