我想为屏幕上的所有 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 的名称以及“额外”消息。
所示的示例只是我的问题的演示,因为在真实的软件中我有超过 300 个菜单项,我想通用地执行此操作,因此我不必向所有当前的菜单点击添加额外的代码行,当我添加新菜单项时也不添加它们。执行顺序(在菜单单击和额外的代码块之间)并不重要。
我尝试使用TActionList
,但我无法检索触发该操作的对象,因此,我无法打印它的名称。我尝试使用 ActiveControl,但它总是返回当前聚焦的焦点对象,而不是我单击的实际菜单。而且,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 继承此类使得表单在销毁时自动释放它。
- HandleOnClick 应该在调用之前检查 FOrigEvent 是否已分配。
关于delphi - 扩展屏幕中所有菜单项的 OnClick 事件以执行另一段代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55476267/