未声明的标识符:'OnClick'

时间:2011-07-27 18:29:33

标签: delphi

为什么我会收到此错误消息:未声明的标识符:'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;

3 个答案:

答案 0 :(得分:10)

投射时,请使用TButton代替TControlOnClick的{​​{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;