我正在制作一个程序来检测鼠标指向的窗口/控件(非常类似于spy ++)但是我遇到了一个问题:
最初我一直在使用WindowFromPoint来查找hWnd的控件,但发现禁用/隐藏的窗口没有显示。每个站点都说要使用ChildWindowFromPoint(或类似的winapi),但是这些都没有在windows中找到控件。
因此...
是否有任何winapi在找到禁用和隐藏的窗口的同时找到相同级别的WindowFromPoint的窗口/控件?
答案 0 :(得分:3)
带有CWP_ALL的ChildWindowFromPointEx(如果你想跳过透明窗口则为CWP_SKIPTRANSPARENT,如果你想跳过透明窗口),直到它返回NULL,我想,如果你只是在寻找窗口。
Aussay Marshal指出,控件没有通用定义,Internet Explorer中的控件没有窗口化,与WPF或Java Foundation Classes等其他框架中的控件无关。
如果您正在编写类似Spy ++的内容,请检查Spy++ Internals。如果您需要自动执行其他程序,请选中Windows Automation API。
答案 1 :(得分:1)
在C ++中对我有用:
HWND ChildFromPoint_recurse(HWND inHWND, POINT inPOINT)
{
HWND lHWND = ChildWindowFromPointEx(inHWND,inPOINT,CWP_ALL);
if (lHWND == 0) return inHWND;
if (lHWND != inHWND)
{
POINT lPOINT = inPOINT;
if (!ClientToScreen(inHWND,&lPOINT)) return lHWND;
if (!ScreenToClient(lHWND,&lPOINT)) return lHWND;
HWND lHWNDrecurse = ChildFromPoint_recurse(lHWND,lPOINT);
if (lHWNDrecurse) lHWND = lHWNDrecurse;
}
return lHWND;
}
答案 2 :(得分:0)
如果你真的想要隐藏窗户,你唯一真正的选择是自己走过HWND树;所有...... FromPoint完全跳过这些。 (请注意,隐藏的窗口可能会有一些位置最终阻止您进入它们下面的可见窗口 - 因此您可能想要考虑是否确实想要在所有情况下都隐藏窗口,或者仅作为后备窗口在某一点上没有其他最合适的可见窗口。)
使用GetDesktopWindow()从根开始,然后适当地下降;经过每个孩子,看看是否在其中,如果是,则遍历该分支并忽略其他兄弟姐妹。
要确定HWND的子级,可以使用EnumWindows,也可以使用GetWindow() - 但请注意,如果窗口在枚举时更改zorder,GetWindow可能会给出不一致的结果。
然后由您决定如何过滤掉hwnds;如果你只想要可见的窗口,那么跳过那些没有设置WS_VISIBLE位的窗口。
检查“点在此HWND中”是比较棘手的:检查窗口中的点是否为第一次测试;但是你可能还必须测试它没有响应HT_TRANSPARENT到WS_EX_TRANSPARENT - 这就是groupbox用来允许点击“遍历”到他们看起来包含的兄弟姐妹的地方。 (你可能还需要考虑形状的窗户 - 那些使用SetWindowRgn给它们一个不规则的形状;现在它们有点罕见,现在将窗口分层到相同的工作。)
-
顺便说一句,如果你不关心隐形窗口,那么考虑使用一个可访问性API:他们已经做了类似的工作。使用AutomationElement.FromPoint,您可以“在那时”获取UI元素。如果你特别关心UI而不是HWND,那就太棒了;它将返回一个表示列表框中项目的对象,而不是整个列表框HWND,以HWND为中心的方法将为您提供 - 但它不会帮助您隐藏窗口。
答案 3 :(得分:-1)
你不能。您无法获得Web浏览器中的Windows类文本框所属的内容。