扩展屏幕中所有菜单项的事件OnClick以执行另一个代码块

问题描述 投票:2回答:1

我想在屏幕上为所有OnClick设置一个事件TMenuItems,以执行事件当前所做的事情,以及另外几行代码。我目前正在使用Delphi 5

例如,假设我有一个TMenuItem代码:

procedure TdesktopForm.MenuFoo1Click(Sender: TObject);
begin
  ShowMessage(TComponent(Sender).Name)
end;

我也有以下程序:

procedure TdesktopForm.bar;
begin
  ShowMessage('extra')
end;

我希望每次单击TMenuItem时程序都会显示TMenuItem的名称以及“额外”消息。

显示的示例只是我的问题的一个演示,就像我有超过300个菜单项的真实软件一样,我想这样做一般,所以我不需要为所有当前菜单点击添加额外的代码行,也不需要添加我添加新的菜单项时。执行顺序(菜单点击和额外的代码块之间)无关紧要。

我尝试使用TActionList,但我无法检索触发动作的对象,因此,我无法打印它的名称。我尝试使用ActiveControl,但它总是返回当前聚焦的焦点对象,而不是我点击的实际菜单。而且,TAction执行事件会覆盖我的TMainMenu.OnClick事件

delphi delphi-5
1个回答
5
投票

只要所有事件处理程序都在某个时间点(在设计时或运行时)分配并且之后不再更改,您可以执行以下操作:

  1. 枚举菜单中的所有菜单项
  2. 为每个创建一个像下面描述的对象 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继承此类使得表单在被销毁时自动释放它。
  • HandleOnClick可能会在调用之前检查是否已分配FOrigEvent。
© www.soinside.com 2019 - 2024. All rights reserved.