我正在尝试查找给定窗口的所有子控件。我可以使用Inspect.exe
(来自Windows开发工具包)验证窗口的句柄。问题是当我调用FindWindowEx
时函数返回0(IntPtr.Zero
准确),而我可以找到Inspect.exe
的控件。
这是我的代码
[DllImport("user32.dll", SetLastError=true)]
private static extern IntPtr FindWindowEx(IntPtr parentHandle,
IntPtr childAfter, string className, string windowTitle);
public static List<IntPtr> EnumChildren(IntPtr hwnd)
{
IntPtr zero = IntPtr.Zero;
List<IntPtr> list = new List<IntPtr>();
do
{
zero = FindWindowEx(hwnd, zero, null, null); // Returns 0
if (zero != IntPtr.Zero)
{
list.Add(zero);
}
}
while (zero != IntPtr.Zero);
return list;
}
我尝试过使用以下内容,它们都返回0:
zero = FindWindowEx(hwnd, zero, "TextBox", null);
zero = FindWindowEx(hwnd, zero, "TextBox", "Text");
zero = FindWindowEx(hwnd, zero, String.Empty, String.Empty);
zero = FindWindowEx(hwnd, zero, "TextBox", String.Empty);
我知道有一种方法可以找到窗口的控件,因为Inspect.exe
正在这样做。我尝试过使用EnumChildWindows
,但获得了相同的结果,例如一个空列表。请注意,使用其他软件(我到目前为止已尝试过Thunderbird和KeePass)FindWindowEx
功能正常工作,而不是我必须使用的应用程序。
我已经使用EnumChildWindows
进行了测试,以确保只有一个窗口带有我正在寻找的标题,而且它是唯一的窗口。我真的无法解释为什么我无法获得任何控制。
我做错了什么,是否有另一种方法可以获得给定窗口的所有子窗口?
答案 0 :(得分:2)
您正在致电:
zero = FindWindowEx(hwnd, zero, null, null);
这会返回0.由于您为类名和窗口名传递NULL
,FindWindowEx
会考虑hwnd
的所有子项。自从NULL
传递hwndChildAfter
后,文档会告诉您:
如果hwndChildAfter为NULL,则搜索从hwndParent的第一个子窗口开始。
换句话说,唯一可以得出的结论是:
hwnd
参数无效,或hwnd
指定的窗口没有子窗口。现在,对于第1点,我们假设您能够提供有效的窗口句柄。在这种情况下,唯一剩下的可能性是hwnd
没有孩子。这很合情合理。许多GUI框架使用非窗口控件。这也符合EnumChildWindows
不返回窗口的事实。
您已使用Inspect工具查看该应用程序。让我们看看MSDN says about Inspect。
Inspect(Inspect.exe)是一个基于Windows的工具,可供您选择 任何UI元素并查看元素的辅助功能数据。你可以查看 Microsoft UI自动化属性和控件模式,以及 Microsoft Active Accessibility属性。 Inspect也可以让你 测试UI中自动化元素的导航结构 自动化树以及Microsoft Active中的可访问对象 辅助功能层次结构。
根本问题是你选择了错误的工具来解决这个问题。您应该使用自动化API来执行此任务,而不是使用窗口层次结构。这就是Inspect能够分解这个应用程序的控件的方式,也必须这样做。