组件可以用它自己的处理程序替换它的所有者表单的事件(OnClose)吗?

use*_*134 1 delphi components delphi-5

我正在研究一个放在我项目的每个形式上的组件.在运行时,是否可以让组件在其所有者表单的OnClose事件处理程序中包含代码.换句话说,表单将触发它自己的OnClose事件处理程序,但该组件还将包含在所有者表单的OnClose事件上运行的其他事件处理程序代码.(这就是所谓的矢量替换吗?)谢谢.

Dav*_*nan 7

您需要让组件声明一个字段来存储表单的原始字段OnClose.然后你可以在组件的构造函数中做:

FOriginalFormClose := (Owner as TForm).OnClose;
(Owner as TForm).OnClose := FormClose;
Run Code Online (Sandbox Code Playgroud)

然后该组件FormClose将读取:

TMyComponent.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // do stuff for this component
  if Assigned(FOriginalFormClose) then
    FOriginalFormClose(Sender, Action);
end;
Run Code Online (Sandbox Code Playgroud)

当然,as演员将这个组件绑定到表单所有,但如果你想要更多的灵活性,你可以很容易地满足它.

这是对您提出的问题的直接回答,但如果不质疑您的整体设计,那将是我的疏忽.如果您希望组件存在于应用程序中的每个表单上,那么您肯定应该派生TForm包含您的自定义的子类.然后让应用中的每个表单都基于该公共基本表单类.

这种方法还有许多其他好处.例如,@ LachlanG添加了以下非常贴切的评论,我完全同意:

让组件插入其拥有形式是不合需要的.绝大多数组件应该是自包含实体,更改组件所有者会破坏Delphi组件的预期合同.

通用基本表单方法通过将与表单一起使用的代码放在表单内来解决此问题.

如果您确实沿着具有共同基础形式的路线走下去,那么您应该覆盖DoClose而不是使用该OnClose事件.在DoXXX创建公共基类或组件时,始终使用事件提升程序而不是事件本身.

  • 我同意大卫的观点,认为让一个组件插入它拥有它的形式是不可取的.绝大多数组件应该是自包含实体,更改组件所有者会破坏Delphi组件的预期合同. (3认同)