C# UI自动化FindAll(TreeScope.substands)未到达子代

C# UI自动化FindAll(TreeScope.substands)未到达子代,c#,ui-automation,C#,Ui Automation,我有一个程序不是我写的(封闭源代码),我需要从看起来像一个多行文本编辑读取文本 该程序在最高级别有一个TabControl,共有15个选项卡。在第15个选项卡中,我需要进行文本编辑 AutomationElement aeEntireApplication = AutomationElement.FromHandle(hwd); AutomationElementCollection aeEditCollection = aeEntireApplication.FindAll(TreeScope

我有一个程序不是我写的(封闭源代码),我需要从看起来像一个多行文本编辑读取文本

该程序在最高级别有一个TabControl,共有15个选项卡。在第15个选项卡中,我需要进行文本编辑

AutomationElement aeEntireApplication = AutomationElement.FromHandle(hwd);
AutomationElementCollection aeEditCollection = aeEntireApplication.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ClassNameProperty,"Edit"));
foreach (AutomationElement aeEdit in aeEditCollection )
{
     object patternObj;
     if (edit.TryGetCurrentPattern(TextPattern.Pattern, out patternObj))
     {
          var textPattern = (TextPattern)patternObj;
          Console.WriteLine(textPattern.DocumentRange.GetText(-1).TrimEnd('\r')); // often there is an extra '\r' hanging off the end.
     }
}

使用此代码,它只会打印我当前所在选项卡的文本编辑内容。是否可以在不必打开选项卡的情况下访问选项卡15的内容?

一个解决方案可以使用它

internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
我枚举了整个程序的所有子项,然后在编辑旁边找到一个按钮,它有一个唯一的名称。然后我用

uint GW_HWNDPREV = 3;
logTextBoxHandle = GetWindow(hwnd, GW_HWNDPREV);
这使我获得了所需文本编辑的句柄


虽然不优雅,但它似乎可以工作。

将Inspect SDK工具指向您的UI,并检查通过UIA原始视图显示的内容始终是值得的。原始视图包含通过UI的UIA公开的所有内容。(可以从Inspect的选项菜单中选择Inspect中显示的视图。)如果Inspect没有显示您感兴趣的UI,则应用程序(或应用程序使用的UI框架)不会显示该UI,并且您自己的UIA客户端代码也无法访问它

我刚刚用TabControl创建了一个测试WinForm应用程序。TabControl有两个选项卡,每个选项卡有一个文本框。Inspect告诉我,在任何给定的时间,只有活动选项卡页面中包含的UI通过UIA公开。因此,您将无法使用UIA访问其他选项卡上的UI

谢谢

家伙


AutomationElement只能用于可见元素。显然,您需要使用Win32 API来处理隐藏控件或一些用于本机应用程序(如pywinauto或AutoIt)的UI自动化工具。谢谢。在决定使用UIA还是winapi时,我会记住这一点!