【问题标题】:How to Detect a TPopupMenu's OnClose (OnPopDown) Event in Delphi applications如何在 Delphi 应用程序中检测 TPopupMenu 的 OnClose (OnPopDown) 事件
【发布时间】:2020-07-21 19:00:23
【问题描述】:

我可以在 TPopupMenu 的 OnPopUp 事件中编写一些代码。但我还需要另一个 OnPopDown 事件。有没有办法使用 Delphi 10.3.3 来做到这一点?

【问题讨论】:

  • @AndreasRejbrand 是的,它对我不起作用。
  • @Andrzej 究竟是什么方式?请更具体。该技术(覆盖TPopupListEx确实有效。我以前用过。
  • @RemyLebeau 我遵循了确切的步骤,编译成功,但标题没有改变,使用 Delphi 10.3.3。
  • @Andrzej 字幕与检测菜单关闭有什么关系?你现在混淆了这个问题。

标签: delphi delphi-10.3-rio


【解决方案1】:

您可以尝试多种选择。

方法 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;

测试ClientRect.Contains(ScreenToClient(Message.Pos)) 是必要的,这样您就不会“覆盖”滚动条自己的上下文菜单。此外,您需要考虑使用键盘(例如菜单键或 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 已发布属性。这精确地模仿了OnPopup 机制。

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

【讨论】:

  • 抱歉,这对我不起作用。可以只更改 PopupMenu1 的代码吗?
  • @Andrzej:什么不起作用?在第一种方法中,您需要更改控件,而不是弹出菜单。
  • 我想没有触发弹出前代码和弹出后代码
  • 它是一个单独的特定控件,您需要跟踪其上下文菜单吗?
  • 我有一个 VCL 应用程序。我丢了一个 PopupMenu1。我可以添加 PopupMenu1 的 OnPopup 事件,但我还需要在 PopupMenu1 关闭时添加一个事件。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 2022-12-20
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 2021-07-31
  • 1970-01-01
  • 2021-04-11
相关资源
最近更新 更多