扩展屏幕上所有MenuItems的事件OnClick来执行另一段代码

时间:2019-04-02 13:40:07

标签: delphi delphi-5

我想为屏幕上的所有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事件

1 个答案:

答案 0 :(得分: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;
    

请注意,此代码未经测试,甚至可能无法编译。 我也不确定这是否适用于Delphi5。尽管它适用于Delphi 6,所以机会很大。

编辑: 一些其他注释(感谢您的评论):

  • 从TComponent继承此类可以使表单在销毁时自动释放。
  • HandleOnClick可能应在调用它之前检查是否已分配FOrigEvent。