Delphi 组件是否可以替换它';业主表格';s事件(OnClose)与它一起';谁是自己的主人?

Delphi 组件是否可以替换它';业主表格';s事件(OnClose)与它一起';谁是自己的主人?,delphi,components,delphi-5,Delphi,Components,Delphi 5,我正在开发一个组件,它被放置在我的项目的每一个表单上。在运行时,是否可以让组件将代码包含到其所有者表单的OnClose事件处理程序中。换句话说,表单将触发它自己的OnClose事件处理程序,但组件还将包含在所有者表单的OnClose事件上运行的其他事件处理程序代码。(这就是所谓的向量替换吗?) 谢谢。您需要让组件声明一个字段来存储表单的原始OnClose。然后您可以在组件的构造函数中执行以下操作: FOriginalFormClose := (Owner as TForm).OnClose; (

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

您需要让组件声明一个字段来存储表单的原始
OnClose
。然后您可以在组件的构造函数中执行以下操作:

FOriginalFormClose := (Owner as TForm).OnClose;
(Owner as TForm).OnClose := FormClose;
然后组件的
FormClose
将显示:

TMyComponent.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // do stuff for this component
  if Assigned(FOriginalFormClose) then
    FOriginalFormClose(Sender, Action);
end;
当然,
as
cast将此组件与表单所拥有的组件联系在一起,但是如果您想要更大的灵活性,您可以很容易地满足这一点

这是对你提出的问题的直接回答,但如果我不质疑你的总体设计,那将是我的失职。如果您希望应用程序中的每个表单上都有一个组件,那么您肯定应该派生一个包含自定义的
TForm
子类。然后,使应用程序中的每个表单都基于该公共基表单类

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

让组件干预其所属表单是不可取的。绝大多数组件都应该是自包含的实体,更改组件所有者会破坏Delphi组件的预期契约

公共基本表单方法通过将与表单一起工作的代码放置在表单中来解决此问题


如果确实要使用公共基本表单,那么应该重写
DoClose
,而不是使用
OnClose
事件。创建公共基类或组件时,始终使用
DoXXX
事件引发器,而不是事件本身。

您需要让组件声明一个字段来存储表单的原始
OnClose
。然后您可以在组件的构造函数中执行以下操作:

FOriginalFormClose := (Owner as TForm).OnClose;
(Owner as TForm).OnClose := FormClose;
然后组件的
FormClose
将显示:

TMyComponent.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // do stuff for this component
  if Assigned(FOriginalFormClose) then
    FOriginalFormClose(Sender, Action);
end;
当然,
as
cast将此组件与表单所拥有的组件联系在一起,但是如果您想要更大的灵活性,您可以很容易地满足这一点

这是对你提出的问题的直接回答,但如果我不质疑你的总体设计,那将是我的失职。如果您希望应用程序中的每个表单上都有一个组件,那么您肯定应该派生一个包含自定义的
TForm
子类。然后,使应用程序中的每个表单都基于该公共基表单类

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

让组件干预其所属表单是不可取的。绝大多数组件都应该是自包含的实体,更改组件所有者会破坏Delphi组件的预期契约

公共基本表单方法通过将与表单一起工作的代码放置在表单中来解决此问题


如果确实要使用公共基本表单,那么应该重写
DoClose
,而不是使用
OnClose
事件。在创建公共基类或组件时,始终使用
DoXXX
事件引发器,而不是事件本身。

我同意David的观点,组件干预其所属表单是不可取的。绝大多数组件都应该是自包含的实体,更改组件所有者会破坏Delphi组件的预期契约。@LachlanG+1我应该在回答中明确指出这一点,因为我完全同意。谢谢,谢谢大卫·赫弗曼,正是我想要的。回答正确。嗨,大卫,用你的例子观察一下。测试“if FOriginalFormClose nil”不应该是“if Assigned(FOriginalFormClose)then”吗?善意的问候。我同意David的观点,让一个组件干预它所拥有的表单是不可取的。绝大多数组件都应该是自包含的实体,更改组件所有者会破坏Delphi组件的预期契约。@LachlanG+1我应该在回答中明确指出这一点,因为我完全同意。谢谢,谢谢大卫·赫弗曼,正是我想要的。回答正确。嗨,大卫,用你的例子观察一下。测试“if FOriginalFormClose nil”不应该是“if Assigned(FOriginalFormClose)then”吗?亲切的问候。