从另一个窗口显示系统菜单

3
我正在开发一个与Ultramon类似的开源项目,主要用于实现多任务栏功能。可以将其视为Windows任务栏,包括每个窗口的按钮等。该项目使用C/C++编写,并使用WinAPI。
我已经开始进行了一些功能的开发,但在尝试显示系统菜单(例如右键单击任务栏“按钮”时出现的菜单)时遇到了问题,无法按照预期在正确位置显示菜单。
我正试图使用:
HMENU menu = GetSystemMenu(item, false); 
SetForegroundWindow(hWnd);
TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, 0, 0, 0, hWnd, NULL);
PostMessage(hWnd, WM_NULL, 0, 0);

item是我想要菜单的HWND,hWnd是我想让菜单显示在其上的按钮/项的HWND。(现在它在0,0处显示,即我的主监视器左上角)。

这段代码对于自定义的系统菜单完美地工作。例如:它不是只有“恢复”,“最大化”等标准菜单,而是有一些额外的菜单项。这些菜单将始终显示在我想要的位置。

然而,默认的基本系统菜单(例如仅包含最大化、恢复、关闭等选项的菜单),只会在第一次使用时显示。之后它们就拒绝显示。除非我重新启动计算机,再次运行程序,此时它们就可以完美地工作了。

注意:SetForegroundWindow(hWnd);PostMessage(hWnd, WM_NULL, 0, 0); 在这里是因为我在某个地方读到,系统菜单只有在我将其带到前台的时候才能起作用,但它仍然不能正确地工作。

那么,有人知道如何使其正确地工作吗?或者为什么它只在我重新启动计算机后第一次工作?


刚刚测试了一下,如果我关闭窗口(例如退出程序)并重新打开它,它也会再次显示系统菜单。但再次强调,它只会显示一次,然后停止工作。


请提供链接到此项目的链接:) - zproxy
你应该检查用户在TrackPopupMenu中点击了哪个项目,然后将其传递给WM_SYSCOMMAND,而不是发送WM_NULL,对吧? - EricLaw
没有自定义系统菜单的应用程序的问题在于,GetSystemMenu 创建 菜单,据我所知,将所有权分配给您的进程。当您的进程退出时,菜单被销毁,但GetSystemMenu仍然返回相同(现在无效)的菜单句柄。Alt+Space仍然有效,可能是因为窗口管理器回退到其自己的全局副本的系统菜单。 - Lexikos
1个回答

0

这个方法可能有点不正规,但你尝试过设置窗口焦点然后通过类似于SendInput的方式发出Alt+Space吗?


这将不会在 [Paul] 想要它们出现的时间和地点显示系统菜单。 - Andreas Rejbrand

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