扩展屏幕中所有MenuItem的OnClick事件,执行另一段代码
Extend the event OnClick of all MenuItems in the screen to execute another block of code
我想给屏幕上的所有TMenuItems
设置一个事件OnClick
来做事件当前做的事情,另外几行代码。我目前正在使用 Delphi 5
例如,假设我有一个 TMenuItem
,代码为:
procedure TdesktopForm.MenuFoo1Click(Sender: TObject);
begin
ShowMessage(TComponent(Sender).Name)
end;
我还有以下程序:
procedure TdesktopForm.bar;
begin
ShowMessage('extra')
end;
我希望每次单击 TMenuItem 时程序都显示 TMenuItem 的名称以及 'extra' 消息。
显示的示例只是我的问题的演示,因为在真正的软件中我有超过 300 个菜单项,我想通用地执行此操作,因此我不必在所有当前的菜单项中添加额外的代码行菜单点击,也不会在我添加新菜单项时添加它们。执行顺序(在菜单点击和额外代码块之间)无关紧要。
我尝试使用 TActionList
但我无法检索触发该操作的对象,因此,我无法打印它的名称。我尝试使用 ActiveControl
但它总是 return 当前聚焦的对象,而不是我单击的实际菜单。而且,TAction
执行事件会覆盖我的 TMainMenu.OnClick
事件
只要您的所有事件处理程序都在某个时间点(在设计时或 运行 时)分配并且之后不更改,您可以这样做:
- 枚举菜单中的所有菜单项
为每个对象创建一个如下所述的对象
type
TEventInterceptor = class(TComponent)
private
FOrigEvent: TNotifyEvent;
FAdditionalEvent: TNotifyEvent;
procedure HandleOnClick(_Sender: TObject);
public
constructor Create(_MenuItem: TMenuItem; _AdditionalEvent: TNotifyEvent);
end;
constructor TEventInterceptor.Create(_MenuItem: TMenuItem; _AdditionalEvent: TNotifyEvent);
begin
inherited Create(_MenuItem);
FOrigEvent := _MenuItem.OnClick;
FAdditionalEvent := _AdditionalEvent;
_MenuItem.OnClick := HandleOnClick;
end;
procedure TEventInterceptor.HandleOnClick(_Sender: TObject);
begin
FOrigEvent(_Sender);
FAdditinalEvent(_Sender);
end;
请注意,此代码完全未经测试,甚至可能无法编译。
我也不确定这是否适用于 Delphi 5。它确实适用于 Delphi 6,所以机会很好。
编辑:
一些补充说明(感谢评论):
- 从 TComponent 继承此 class 使表单在销毁时自动释放它。
- HandleOnClick 应该在调用之前检查 FORigEvent 是否已分配。
我想给屏幕上的所有TMenuItems
设置一个事件OnClick
来做事件当前做的事情,另外几行代码。我目前正在使用 Delphi 5
例如,假设我有一个 TMenuItem
,代码为:
procedure TdesktopForm.MenuFoo1Click(Sender: TObject);
begin
ShowMessage(TComponent(Sender).Name)
end;
我还有以下程序:
procedure TdesktopForm.bar;
begin
ShowMessage('extra')
end;
我希望每次单击 TMenuItem 时程序都显示 TMenuItem 的名称以及 'extra' 消息。
显示的示例只是我的问题的演示,因为在真正的软件中我有超过 300 个菜单项,我想通用地执行此操作,因此我不必在所有当前的菜单项中添加额外的代码行菜单点击,也不会在我添加新菜单项时添加它们。执行顺序(在菜单点击和额外代码块之间)无关紧要。
我尝试使用 TActionList
但我无法检索触发该操作的对象,因此,我无法打印它的名称。我尝试使用 ActiveControl
但它总是 return 当前聚焦的对象,而不是我单击的实际菜单。而且,TAction
执行事件会覆盖我的 TMainMenu.OnClick
事件
只要您的所有事件处理程序都在某个时间点(在设计时或 运行 时)分配并且之后不更改,您可以这样做:
- 枚举菜单中的所有菜单项
为每个对象创建一个如下所述的对象
type TEventInterceptor = class(TComponent) private FOrigEvent: TNotifyEvent; FAdditionalEvent: TNotifyEvent; procedure HandleOnClick(_Sender: TObject); public constructor Create(_MenuItem: TMenuItem; _AdditionalEvent: TNotifyEvent); end; constructor TEventInterceptor.Create(_MenuItem: TMenuItem; _AdditionalEvent: TNotifyEvent); begin inherited Create(_MenuItem); FOrigEvent := _MenuItem.OnClick; FAdditionalEvent := _AdditionalEvent; _MenuItem.OnClick := HandleOnClick; end; procedure TEventInterceptor.HandleOnClick(_Sender: TObject); begin FOrigEvent(_Sender); FAdditinalEvent(_Sender); end;
请注意,此代码完全未经测试,甚至可能无法编译。 我也不确定这是否适用于 Delphi 5。它确实适用于 Delphi 6,所以机会很好。
编辑: 一些补充说明(感谢评论):
- 从 TComponent 继承此 class 使表单在销毁时自动释放它。
- HandleOnClick 应该在调用之前检查 FORigEvent 是否已分配。