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