【FindWindow如何查找2个窗口名一样的句柄(并且识别句柄。及C)】在使用Windows API中的`FindWindow`函数时,开发者常常会遇到一个问题:当多个窗口具有相同的窗口名称时,`FindWindow`只能返回第一个匹配的句柄,无法直接获取所有相同名称的窗口句柄。本文将总结这一问题的解决方法,并提供实际示例。
一、问题概述
`FindWindow`函数用于根据窗口类名或窗口标题查找窗口句柄(HWND)。其原型如下:
```c
HWND FindWindow(LPCWSTR lpClassName, LPCWSTR lpWindowName);
```
- `lpClassName`:窗口类名(可为NULL)。
- `lpWindowName`:窗口标题(可为NULL)。
当多个窗口具有相同的标题时,`FindWindow`只会返回第一个匹配的句柄,无法直接获取所有匹配的窗口句柄。
二、解决方案总结
方法 | 描述 | 是否可行 | 说明 |
使用 `EnumWindows` 配合 `GetWindowText` | 遍历所有窗口,检查窗口标题是否匹配 | ✅ | 可以获取所有相同名称的窗口句柄 |
使用 `FindWindowEx` 递归查找 | 在已知父窗口中查找子窗口 | ✅ | 适用于有层级关系的窗口 |
使用 `GetWindowTextLength` 和 `GetWindowText` | 精确匹配窗口标题 | ✅ | 提高匹配准确性 |
使用 `SetWindowLong` 或 `SetProp` 添加自定义属性 | 为窗口添加唯一标识 | ✅ | 增强窗口识别能力 |
三、具体实现示例
示例1:使用 `EnumWindows` 查找所有同名窗口
```c
include
include
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
TCHAR windowTitle[256];
GetWindowText(hwnd, windowTitle, sizeof(windowTitle));
if (wcscmp(windowTitle, L"目标窗口标题") == 0) {
std::wcout << L"找到窗口句柄: " << hwnd << std::endl;
}
return TRUE;
}
int main() {
EnumWindows(EnumWindowsProc, 0);
return 0;
}
```
示例2:使用 `FindWindowEx` 查找子窗口
```c
HWND hParent = FindWindow(NULL, L"父窗口标题");
HWND hChild = FindWindowEx(hParent, NULL, NULL, L"子窗口标题");
if (hChild != NULL) {
std::cout << "找到子窗口句柄: " << hChild << std::endl;
}
```
四、注意事项
- `EnumWindows` 是最常用的方法,但效率较低,不适合频繁调用。
- 若需精确匹配,建议结合 `GetWindowTextLength` 检查窗口长度。
- 对于复杂应用,可以考虑为窗口设置自定义属性,如通过 `SetProp` 添加唯一标识。
五、总结
在C语言中,当多个窗口拥有相同的窗口标题时,`FindWindow`无法直接获取所有匹配的句柄。可以通过 `EnumWindows` 配合 `GetWindowText` 实现多窗口查找,或使用 `FindWindowEx` 查找父子窗口。此外,为窗口添加自定义属性也是一种增强识别能力的有效方式。