如何在C ++中将自定义项目添加到系统菜单?
我需要枚举所有正在运行的应用程序。特别是所有顶部窗口。对于每个窗口,我需要将自定义项添加到该窗口的系统菜单。
我该如何在C ++中做到这一点?
更新。
我很高兴拥有适用于Windows,MacOS和Ubuntu的解决方案(尽管我不确定MacOS和Ubuntu是否具有"系统菜单"之类的东西)。
解决方案
一旦有了另一个窗口的顶级句柄,我们就可以调用GetMenu()来检索窗口的系统菜单,然后对其进行修改,例如:
HMENU hMenu = GetMenu(hwndNext);
我们可以使用EnumWindows()枚举顶级Windows。
对于我们问题的第二部分,我没有具体的答案,但是如果我们将窗口子类化,我想我们可以修改系统菜单。
编辑:或者做克里斯说:调用GetMenu()
回复:此更新请注意,即使Microsoft Windows也不要求Windows具有系统菜单。 GetMenu()可能返回0。我们还需要拦截窗口的创建,因为每个新的顶部窗口可能也需要它。
另外,我们提出的建议对其他应用程序具有侵入性。修改菜单时,如何确保它们不会损坏?以及如何确保抑制消息?特别是,我们如何确保在别人看到它们之前就将它们拦截?引用雷蒙德·陈(Raymond Chen)的话,想象如果两个程序尝试这样做会发生什么。
对于Windows,获取顶级窗口(除EnumWindows外,它使用回调)的另一种方法是获取桌面的第一个子对象,然后检索其所有同级对象:
HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD); while (wnd) { // handle 'wnd' here // ... wnd = GetNextWindow(wnd, GW_HWNDNEXT); }
至于获取系统菜单,请使用" GetSystemMenu"函数,将FALSE作为第二个参数。其他答案中提到的" GetMenu"将返回正常的窗口菜单。
但是请注意,虽然将自定义菜单项添加到外部进程的窗口很容易,但是响应该项目的选择有些棘手。我们将不得不向该过程中注入一些代码以便能够对窗口进行子类化,或者安装一个全局挂钩(可能是" WH_GETMESSAGE"或者" WH_CBT"类型)来监视" WM_SYSCOMMAND"消息。