getforegroundwindow()无法获取主窗口标题,应枚举本进程顶级窗口并用getwindowtextw读取unicode标题,且需在ui线程中安全调用。

GetForegroundWindow() 不能直接拿到主窗口标题
很多人第一反应是调用 GetForegroundWindow(),但这个函数只返回当前**最前层**的窗口句柄(可能是个弹窗、任务管理器、甚至别的程序),和你的主窗口完全无关。真正要找的是你自己的进程启动的那个主窗口——它通常在 WinMain() 或 main() 启动后创建,且没有父窗口(GetParent(hwnd) == nullptr)。
用 EnumWindows 遍历并筛选属于本进程的顶级窗口
可靠的做法是枚举所有顶层窗口,逐个检查其所属进程 ID 是否匹配当前进程。关键步骤如下:
- 调用
GetCurrentProcessId()获取当前 PID - 用
EnumWindows()遍历所有顶层窗口(lpfnEnumProc回调中处理每个HWND) - 对每个
HWND,调用GetWindowThreadProcessId(hwnd, &dwPid)获取其所属 PID - 若 PID 匹配,再用
IsWindowVisible(hwnd)和GetWindowTextLength(hwnd) > 0排除不可见或空标题的窗口
注意:一个进程可能有多个顶级窗口(比如主窗口 + 对话框),一般取第一个满足条件的即可,或按创建时间排序(需额外用 GetWindowLong(hwnd, GWL_EXSTYLE) 结合 WS_EX_TOPMOST 判断优先级)。
GetWindowText 读取标题时容易截断或乱码
GetWindowText() 默认使用 ANSI 编码,如果窗口标题含中文或 Unicode 字符(现代 Windows 默认如此),必须用宽字符版本 GetWindowTextW(),否则返回空字符串或乱码。示例片段:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
wchar_t title[256] = {};
if (GetWindowTextW(hwnd, title, _countof(title)) > 0) {
// title 现在是正确的 Unicode 字符串
}
另外,缓冲区大小必须足够;GetWindowTextLengthW(hwnd) 可先查长度,动态分配内存更稳妥。别硬写 256 —— 标题超长时会被静默截断,不报错也不提示。
多线程或 DLL 注入环境下 HWND 可能失效
如果你的代码不在主线程执行(比如在 DLL 的 DllMain 或后台线程里调用),EnumWindows 仍能工作,但获取到的 HWND 若在非创建线程中调用 GetWindowTextW,可能触发跨线程 UI 访问问题(尤其在启用了 UIPI 的系统上)。安全做法是:
- 确保调用发生在主线程(UI 线程)
- 或改用
PostMessage()向主窗口发送自定义消息,在窗口过程里同步读取标题 - 避免在
DllMain中做任何 UI 操作 —— 这里调用GetWindowTextW极易死锁
真正的难点不在“怎么拿”,而在“什么时候拿、在哪条线程拿、拿完怎么安全传出去”——这些细节漏掉一个,程序就可能偶发崩溃或返回空字符串。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










