如何用Win32 API查找一个三级子窗口的子窗口的子窗口的HWND?

5
假设我有一个进程的窗口层次结构:

假设我有一个进程的窗口层次结构:

Main Window               (class name: XYZ_Widget_1)
`- Child Window           (class name: XYZ_Widget_0)
  `- Child-Child Window    (class name: XYZ_Renderer)

我该如何找到“子-子窗口”的HWND?
我尝试在XYZ_Renderer类上使用FindWindow Win32 API函数,但FindWindow函数无法查找子窗口。
然后我尝试使用FindWindow查找“主窗口”,成功了,但是之后使用FindWindowEx只能找到Child Window,而“子-子窗口”不是“主窗口”的子级。
我想也许我可以深入一层,在找到“Child Window”后调用FindWindowEx。
但在这之前,我想知道是否有一种简单的方法来找到“子-子窗口”?
2个回答

14

你需要为每个想要进入的子级调用FindWindowEx(),并将在前一级中找到的HWND作为父级指定,例如:

HWND hWnd = FindWindow("XYZ_Widget_1", NULL);
if (hWnd != NULL)
{
    hWnd = FindWindowEx(hWnd, NULL, "XYZ_Widget_0", NULL);
    if (hWnd != NULL)
    {
        hWnd = FindWindowEx(hWnd, NULL, "XYZ_Renderer", NULL);
        // and so on... 
    }
}

没有更简单的方法。为了简化您的代码,您可以编写自己的函数,接受一个类/窗口名称路径作为输入,循环调用FindWindow/Ex()以根据需要调用每个步骤。


6

将父窗口作为 hwndParent 参数调用 EnumChildWindows。具有类名等于 XYZ_Renderer 的窗口是您的窗口。

文档 指出:

如果一个子窗口创建了自己的子窗口,则 EnumChildWindows 也会枚举这些窗口。


我已经获取了顶层窗口。如果我在顶层窗口上使用EnumChildWindows,它将无法找到XYZ_Renderer,因为XYZ_Renderer不是顶层窗口的子级。它是XYZ_Widget_0的子级...(请参见我的图表) - bodacydo
好的,我错过了那个注释。EnumChildWindows 递归地遍历子窗口。它会找到所有子窗口,它们的子窗口等等。我再重申一遍,EnumChildWindows 找到的是所有子窗口,而不仅仅是直接的子窗口。Raymond 在这篇文章中讨论了这个问题:http://blogs.msdn.com/b/oldnewthing/archive/2007/01/16/1478717.aspx - David Heffernan
哦,是吗?在我的测试中,它似乎只遍历了一个子窗口层。让我重新测试一下。谢谢你的耐心等待。 - bodacydo
你一定做错了某些事情。API确实按照广告宣传的那样工作。但没关系,你有解决方案。 - David Heffernan
1
我可以证实EnumChildWindows()确实像宣传的那样工作,至少在Win7上是这样。它真正枚举了直接子窗口和后代窗口。我创建了一个带有一堆嵌套控件的VCL表单,然后只调用一次带有表单Handle作为父窗口的EnumChildWindows()函数。它确实递归遍历了所有嵌套控件。 - Remy Lebeau
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接