gpt4 book ai didi

c# - 使用 C# 和 UI 自动化获取未知控件类型的内容

转载 作者:行者123 更新时间:2023-11-30 12:32:35 34 4
gpt4 key购买 nike

下图中有一个区域,其中有一个未知(自定义)类。这不是网格或表格。

enter image description here

我需要能够:

  • 选择该区域的行
  • 从每个单元格中获取一个值

问题是因为这不是一个常见的类型元素——我不知道如何用谷歌搜索这个问题或自己解决它。到目前为止,代码如下:

Process[] proc = Process.GetProcessesByName("programname");
AutomationElement window = AutomationElement.FromHandle(proc [0].MainWindowHandle);
PropertyCondition xEllist2 = new PropertyCondition(AutomationElement.ClassNameProperty, "CustomListClass", PropertyConditionFlags.IgnoreCase);
AutomationElement targetElement = window.FindFirst(TreeScope.Children, xEllist2);

我已经尝试过将此区域作为文本框、网格、组合框来威胁,但到目前为止没有解决我的问题。有人对如何从该区域获取数据并遍历行有任何建议吗?

编辑:对不起,我做了一个错误的假设。实际上,标题(第 1 列、第 2 列、第 3 列)和该区域的“下半部分”是不同的控件-类型!!

感谢 Wininspector,我能够挖掘更多关于这些控件类型的信息:

  • header 具有以下属性:HeaderControl 0x056407DC (90441692) Atom:#43288 0xFFFFFFFF (-1)
  • 下半部分有这些:ListControl 0x056408A4 (90441892) Atom:#43288 0x02A6FDA0 (44498336)

我之前展示的代码 - 仅检索“List”元素,因此这里是更新:

Process[] proc = Process.GetProcessesByName("programname");
AutomationElement window = AutomationElement.FromHandle(proc [0].MainWindowHandle);
//getting the header
PropertyCondition xEllist3 = new PropertyCondition(AutomationElement.ClassNameProperty, "CustomHeaderClass", PropertyConditionFlags.IgnoreCase);
AutomationElement headerEl = XElAE.FindFirst(TreeScope.Children, xEllist3);
//getting the list
PropertyCondition xEllist2 = new PropertyCondition(AutomationElement.ClassNameProperty, "CustomListClass", PropertyConditionFlags.IgnoreCase);
AutomationElement targetElement = window.FindFirst(TreeScope.Children, xEllist2);

在进一步考虑之后,我尝试获取所有列名:

AutomationElementCollection headerLines = headerEl.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.HeaderItem));
string headertest = headerLines[0].GetCurrentPropertyValue(AutomationElement.NameProperty) as string;
textBox2.AppendText("Header 1: " + headertest + Environment.NewLine);

不幸的是,在 Debug模式下,“headerLines”中的元素计数为 0,因此程序会抛出错误。

编辑 2:感谢下面的回答 - 我已经安装了 Unmanaged UI Automation,它比默认的 UIA 具有更好的可能性。 http://uiacomwrapper.codeplex.com/您如何使用遗留模式从未知控件类型中获取数据?

if((bool)datagrid.GetCurrentPropertyValue(AutomationElementIdentifiers.IsLegacyIAccessiblePatternAvailableProperty))
{
var pattern = ((LegacyIAccessiblePattern)datagrid.GetCurrentPattern(LegacyIAccessiblePattern.Pattern));
var state = pattern.Current.State;
}

编辑 3. IUIAutoamtion 方法(目前不起作用)

        _automation = new CUIAutomation();
cacheRequest = _automation.CreateCacheRequest();
cacheRequest.AddPattern(UiaConstants.UIA_LegacyIAccessiblePatternId);
cacheRequest.AddProperty(UiaConstants.UIA_LegacyIAccessibleNamePropertyId);
cacheRequest.TreeFilter = _automation.ContentViewCondition;
trueCondition = _automation.CreateTrueCondition();


Process[] ps = Process.GetProcessesByName("program");
IntPtr hwnd = ps[0].MainWindowHandle;
IUIAutomationElement elementMailAppWindow = _automation.ElementFromHandle(hwnd);


List<IntPtr> ls = new List<IntPtr>();

ls = GetChildWindows(hwnd);

foreach (var child in ls)
{
IUIAutomationElement iuiae = _automation.ElementFromHandle(child);
if (iuiae.CurrentClassName == "CustomListClass")
{
var outerArayOfStuff = iuiae.FindAllBuildCache(interop.UIAutomationCore.TreeScope.TreeScope_Children, trueCondition, cacheRequest.Clone());
var outerArayOfStuff2 = iuiae.FindAll(interop.UIAutomationCore.TreeScope.TreeScope_Children, trueCondition);

var countOuter = outerArayOfStuff.Length;
var countOuter2 = outerArayOfStuff2.Length;

var uiAutomationElement = outerArayOfStuff.GetElement(0); // error
var uiAutomationElement2 = outerArayOfStuff2.GetElement(0); // error
//...
//I've erased what's followed next because the code isn't working even now..
}
}

由于这个问题实现了代码:

Read cell Items from data grid in SysListView32 of another application using C#

结果:

  • countOuter 和 countOuter2 长度 = 0
  • 无法选择元素(列表中的行)
  • 不可能获得任何值(value)
  • 没有任何效果

最佳答案

您可能想尝试使用核心 UI 自动化类。它需要您导入 dll 才能在 C# 中使用它。将此添加到您的预构建事件(或只做一次等):

"%PROGRAMFILES%\Microsoft SDKs\Windows\v7.0A\bin\tlbimp.exe" %windir%\system32\UIAutomationCore.dll /out:..\interop.UIAutomationCore.dll"

然后您可以使用 IUIAutomationLegacyIAccessiblePattern。

获取调用所需的常量:

C:\Program Files\Microsoft SDKs\Windows\v7.1\Include\UIAutomationClient.h

我能够以这种方式阅读 Infragistics Ultragrids。

如果这太痛苦,请尝试使用 MSAA。在转换为所有 UIA Core 之前,我使用这个项目作为 MSAA 的起点:MSSA Sample Code

----- 编辑于 6/25/12 ------

我肯定会说,找到合适的“标识符”是使用 MS UIAutomation 东西最痛苦的部分。对我帮助很大的是创建一个简单的表单应用程序,我可以将其用作“位置记录器”。本质上,您只需要两件事:

  • 即使您离开表单窗口也能保持焦点的方法 Holding focus

  • 使用鼠标所在位置的 x,y 坐标调用 ElementFromPoint()。 CUIAutomation 类中有一个实现。

我使用 CTRL 按钮告诉我的应用程序获取鼠标坐标 (System.Windows.Forms.Cursor.Position)。然后我从该点获取元素并递归获取元素的父元素,直到到达桌面。

        var desktop = auto.GetRootElement();
var walker = GetRawTreeWalker();
while (true)
{
element = walker.GetParentElement(element);
if (auto.CompareElements(desktop, element) == 1){ break;}
}

----- 编辑于 6/26/12 -----

一旦您可以递归地找到自动化标识符和/或名称,您就可以相当轻松地修改此处的代码:http://blog.functionalfun.net/2009/06/introduction-to-ui-automation-with.html 以与核心 UI 自动化类一起使用。这将允许您在递归时构建一个字符串,该字符串可用于识别嵌套在具有 XPath 样式语法的应用程序中的控件。

关于c# - 使用 C# 和 UI 自动化获取未知控件类型的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11163293/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com