在特定应用程序上使用时,FindWindowEx返回0

时间:2013-12-11 03:47:29

标签: c# winapi

我正在尝试查找给定窗口的所有子控件。我可以使用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进行了测试,以确保只有一个窗口带有我正在寻找的标题,而且它是唯一的窗口。我真的无法解释为什么我无法获得任何控制。

我做错了什么,是否有另一种方法可以获得给定窗口的所有子窗口?

1 个答案:

答案 0 :(得分:2)

您正在致电:

zero = FindWindowEx(hwnd, zero, null, null);

这会返回0.由于您为类名和窗口名传递NULLFindWindowEx会考虑hwnd的所有子项。自从NULL传递hwndChildAfter后,文档会告诉您:

  

如果hwndChildAfter为NULL,则搜索从hwndParent的第一个子窗口开始。

换句话说,唯一可以得出的结论是:

  1. hwnd参数无效,或
  2. hwnd指定的窗口没有子窗口。
  3. 现在,对于第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能够分解这个应用程序的控件的方式,也必须这样做。