如何在 Delphi 应用程序中检测 TPopupMenu 的 OnClose (OnPopDown) 事件



我可以在TPopupMenu的OnPopUp事件中编写一些代码。但我还需要为OnPopDown举办另一场活动。使用Delphi 10.3.3有什么方法可以做到这一点吗?

您可以尝试各种选项。

方法1

在更简单的情况下,当您有一个需要跟踪其上下文菜单的特定控件时,您可以手动处理其WM_CONTEXTMENU消息:

protected
procedure WMContextMenu(var Message: TWMContextMenu);
message WM_CONTEXTMENU;

其中(例如(

procedure TForm1.WMContextMenu(var Message: TWMContextMenu);
begin
if
Assigned(PopupMenu)
and
(ClientRect.Contains(ScreenToClient(Message.Pos)) or (Message.Pos = Point(-1, -1)))
then
begin
Windows.Beep(200, 500); // pre-popup code
if (Message.XPos = -1) and (Message.YPos = -1) then // Menu key or Shift+F10
with ClientToScreen(Point(0, 0)) do
PopupMenu.Popup(X, Y)
else
PopupMenu.Popup(Message.XPos, Message.YPos);
Windows.Beep(400, 500); // post-popup code
end
else
inherited;
end;

测试CCD_ 2是必要的;重写";滚动条自己的上下文菜单。此外,您还需要考虑使用键盘(例如菜单键或Shift+F10(打开上下文菜单的情况。

方法2

如果这还不够,您可以创建自己的TPopupMenu子类,并覆盖其Popup方法,该方法是虚拟的。添加一个DoPopdown方法,并在最后调用它(遵循DoPopup方法的设计(。

为了快速测试这种方法,您可以使用一个中介器类:

type
TPopupMenu = class(Vcl.Menus.TPopupMenu)
procedure Popup(X, Y: Integer); override;
end;

实现为

{ TPopupMenu }
procedure TPopupMenu.Popup(X, Y: Integer);
begin
inherited;
Windows.Beep(400, 500); // post-popup code
end;

当然,创建一个在IDE中注册的真正的子类(TPopupMenuEx,也许是?(会更好。添加一个FOnPopdown: TNotifyEvent专用字段、一个受DoPopdown保护的函数和一个OnPopdown发布的属性。这正好模拟了CCD_ 11的机制。

不用说,这种方法也适用于TTrayIcon的菜单。

在较新版本(例如11.2 Alexandria(中,TPopupMenuOnClose事件中有内置

最新更新