如何在Delphi中关闭自定义位置的PopupMenu?

4
我有一个使用了CoolTrayIconPopupMenu的项目,并且禁用了AutoPopup属性。我想把弹出菜单定位并展示给用户。虽然位置正确,但是如果用户点击其他区域或按下ESC键,菜单不会关闭。我没有发现任何类似于Active的属性可以判断菜单是否在使用中。
这里是我的菜单位置:
procedure TForm1.CoolTrayIcon1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  pnt: TPoint; yy:integer;
begin

GetCursorPos(pnt);
yy:=pnt.y; yy:=yy-500;

if (Button=mbRight) then begin
    PopupMenu1.Popup(pnt.X, yy);
end;

end;

如果需要关闭菜单,我应该如何管理呢?


如果用户尝试使用键盘显示菜单会发生什么? - David Heffernan
菜单应该通过右键单击打开,这很好,但是如何关闭呢? :D - roll
当用户请求时,应该打开上下文菜单。可以通过点击鼠标右键或使用键盘来实现。那个位于您右手CTRL键左侧的键。 - David Heffernan
点击鼠标右键。我不知道用户如果尝试使用键盘会发生什么,但我会去检查一下。 - roll
正确的处理方式是在负责通知图标消息处理的代码中侦听 WM_CONTEXTMENU。系统会进行繁重的工作,并将适当的用户输入转换为该消息。由于通知图标的不同版本,细节有些模糊。而我不知道这个特定组件的作用。 - David Heffernan
1个回答

8
这是一个已知的问题,在此处进行了讨论:

PRB: 通知区图标的菜单无法正确工作

您需要按以下方式包装对Popup()的调用:
SetForegroundWindow(Handle);
PopupMenu1.Popup(pnt.X, yy);
PostMessage(Handle, WM_NULL, 0, 0);

在这段代码中,Handle 是与通知图标相关联的窗体句柄。

对我来说它不起作用。的确,菜单可以通过Esc键关闭,但在我弹出菜单后,我的应用程序完全死机,我无法访问主窗体上的任何内容。我提到我的托盘图标HWND是私有的,不是主窗体的HWND。 - Marus Gradinaru
1
这里运行良好。还有无数其他帖子和代码示例也是这样做的。所以我猜你要么做错了什么,要么缺少一些重要的细节。 - David Heffernan
可能是因为我在使用的句柄的 WndProc 中执行了这个(弹出式包装)代码? - Marus Gradinaru
可能会很困难,从这里很难判断。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接