这是我的代码:
#include <iostream>
#include <windows.h>
int main()
{
POINT p;
char wndName[60];
while (true)
{
GetCursorPos(&p);
HWND hWnd = WindowFromPoint(p);
GetWindowText(hWnd, wndName, 59);
std::cout << p.x << " " << p.y << std::endl;
std::cout << wndName << " " << std::endl;
ScreenToClient(hWnd, &p);
HWND hWndChild = ChildWindowFromPoint(hWnd, p);
GetWindowText(hWndChild, wndName, 59);
std::cout << p.x << " " << p.y << std::endl;
std::cout << wndName << " " << std::endl;
Sleep(100);
}
return 0;
}
从父窗口打印名称可以正常工作,但是我无法使其在子窗口中正常工作。 子句柄的GetWindowText()与父句柄的打印效果相同。
我希望我的程序仅通过悬停鼠标光标来打印按钮文本,编辑字段中的文本等。
编辑:有任何提示可以帮助我解决此问题吗?
答案 0 :(得分:0)
您没有执行任何错误处理。最重要的是,第二个GetWindowText()
失败并且不会更新wndName
缓冲区,这就是为什么您看到第二遍打印父文本的原因。
您不能使用GetWindowText()
在另一个进程中获取子窗口的文本。 documentation甚至说:
如果指定的窗口是控件,则复制控件的文本。
GetWindowText
无法在另一个应用程序中检索控件的文本。
...
要在另一个进程中检索控件的文本,请直接发送WM_GETTEXT
消息而不是调用GetWindowText()
。
尝试以下方法:
#include <iostream>
#include <windows.h>
const int MAX_WND_TEXT = 60;
int main()
{
POINT p;
char wndName[MAX_WND_TEXT];
while (true)
{
GetCursorPos(&p);
HWND hWnd = WindowFromPoint(p);
if (hWnd)
{
if (!GetWindowTextA(hWnd, wndName, MAX_WND_TEXT))
wndName[0] = '\0';
std::cout << p.x << " " << p.y << std::endl;
std::cout << "'" << wndName << "'" << std::endl;
ScreenToClient(hWnd, &p);
HWND hWndChild = ChildWindowFromPoint(hWnd, p);
if (hWndChild)
{
if (!SendMessageA(hWndChild, WM_GETTEXT, MAX_WND_TEXT, (LPARAM)wndName))
wndName[0] = '\0';
std::cout << p.x << " " << p.y << std::endl;
std::cout << "'" << wndName << "'" << std::endl;
}
}
Sleep(100);
}
return 0;
}
更新:但是,根据Raymond Chen博客上的以下帖子:
WindowFromPoint, ChildWindowFromPoint, RealChildWindowFromPoint, when will it all end?
假设您有一个顶层窗口P和一个子窗口C。并假设您询问以上函数之一,“此点下方是哪个窗口?”当点正好位于窗口C上方时。 WindowFromPoint函数查找包含该点的嵌套程度最高的窗口,即窗口C 。另一方面,假设您以GetDesktopWindow作为起点,ChildWindowFromPoint函数将查找包含该点的嵌套最少的窗口,即窗口P。
因此,WindowFromPoint()
将在指定的屏幕坐标处返回最深的子窗口,因此ChildWindowFromPoint()
将没有其他子窗口可用来查找何时从{{1}获得指定的父窗口。 }。
如果该点在父窗口内,但不在任何子窗口内,则返回值是父窗口的句柄。
因此,以上代码将不会得到您想要的结果。您将需要以下类似的东西:
WindowFromPoint()
但是,此代码显示了 z排序的问题,即找到位于其他窗口后面而不是它们顶部的窗口。您可能需要这样的东西:
#include <iostream>
#include <windows.h>
const int MAX_WND_TEXT = 60;
int main()
{
POINT p;
char wndName[MAX_WND_TEXT];
while (true)
{
GetCursorPos(&p);
HWND hWnd = ChildWindowFromPoint(GetDesktopWindow(), p);
if (hWnd)
{
if (!GetWindowTextA(hWnd, wndName, MAX_WND_TEXT))
wndName[0] = '\0';
std::cout << p.x << " " << p.y << std::endl;
std::cout << "'" << wndName << "'" << std::endl;
ScreenToClient(hWnd, &p);
HWND hWndChild = ChildWindowFromPoint(hWnd, p);
if ((hWndChild) && (hWndChild != hWnd))
{
if (!SendMessageA(hWndChild, WM_GETTEXT, MAX_WND_TEXT, (LPARAM)wndName))
wndName[0] = '\0';
std::cout << p.x << " " << p.y << std::endl;
std::cout << "'" << wndName << "'" << std::endl;
}
}
Sleep(100);
}
return 0;
}
它仍然不完美,但是比以前的代码要好。
答案 1 :(得分:-2)
获取顶级窗口句柄后,使用ChildWindowFromPoint。