如何在C ++中将自定义项添加到系统菜单?

时间:2008-09-26 10:19:11

标签: c++ enumeration

我需要枚举所有正在运行的应用程序。特别是所有顶级窗户。对于每个窗口,我需要将自定义项添加到该窗口的系统菜单中。

如何在C ++中实现这一目标?

更新

我非常乐意为Windows,MacOS和Ubuntu提供解决方案(但是,我不确定MacOS和Ubuntu是否具有'系统菜单')。

4 个答案:

答案 0 :(得分:8)

对于Windows,另一种获取顶级窗口的方法(除了使用回调的EnumWindows之外)是获取桌面的第一个子节点,然后检索其所有兄弟节点:

HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD);
while (wnd) {
    // handle 'wnd' here
    // ...
    wnd = GetNextWindow(wnd, GW_HWNDNEXT);
}

至于获取 system 菜单,请使用GetSystemMenu函数,FALSE作为第二个参数。其他答案中提到的GetMenu会返回普通窗口菜单。

但是,请注意,虽然将自定义菜单项添加到外部进程的窗口很容易,但是响应该项的选择有点棘手。您要么必须向流程注入一些代码才能能够对窗口进行子类化,或者安装全局钩子(可能是WH_GETMESSAGEWH_CBT类型)来监视WM_SYSCOMMAND消息。

答案 1 :(得分:1)

一旦你有另一个窗口的顶级句柄,你可以调用GetMenu()来检索Window的系统菜单,然后修改它,例如:

HMENU hMenu = GetMenu(hwndNext);

答案 2 :(得分:0)

您可以使用EnumWindows()枚举顶级Windows。

我对你问题的第二部分没有具体的答案,但是如果你将窗口子类化,我想你可以修改系统菜单。

编辑:或做克里斯所说的:打电话给GetMenu()

答案 3 :(得分:0)

Re:更新 - 请注意,即使Microsoft Windows也不要求窗口有系统菜单。 GetMenu()可能会返回0.您还需要拦截窗口创建,因为每个新的顶部窗口都可能需要它。

此外,您提出的建议是对其他应用程序的干扰。你如何确保在修改菜单时不会破坏?你如何确保你压制消息?特别是,您如何确保在其他人看到它们之前拦截它们?引用雷蒙德·陈(Raymond Chen)的话,想象一下如果有两个程序会尝试这样做会发生什么。