使用 C# 从另一个应用程序的 SysListView32 中的数据网格中读取单元格项
本文关键字:网格 数据网 读取 单元格 数据 SysListView32 另一个 应用程序 使用 | 更新日期: 2023-09-27 18:35:49
我正在尝试使用 C# .net ui-automation 和 winapi 读取另一个进程的 SysListView32 中的数据网格项
使用 UI 自动化
的 C# 代码 http://pastebin.com/6x7rXMiW
使用 winapi 的 C# 代码http://pastebin.com/61RjXZuK
使用此代码,您只需将鼠标指针放在屏幕上的 SysListView32 上,然后按 Enter 键。
现在,两个代码在具有以下属性的单元格项上都返回空
pastebin.com/Rw9FGkYC
但这两个代码都适用于以下属性
pastebin.com/L51T4PLu
唯一的区别是我注意到 name 属性包含与单元格中相同的数据,但当 name 属性为空时出现问题。
有没有其他方法可以读取单元格? 或我可以进行的任何更改,请详细说明。
我还建议使用检查工具。 如果您看到以下内容:
IsLegacyIAccessiblePatternAvailable: true
您可以使用 LegacyIAccessiblePattern。 其他帖子似乎表明它尚未在客户端UI 自动化 API 中,但它在核心中。 可以通过包装在 .NET 中使用核心。 我将其添加到我的构建中以开始使用它:
"%PROGRAMFILES%'Microsoft SDKs'Windows'v7.0A'bin'tlbimp.exe" %windir%'system32'UIAutomationCore.dll /out:..'interop.UIAutomationCore.dll"
如果确实支持此模式,我可以添加更多详细信息。
好吧,那你可能很好。
下面是一些示例代码:
// C:'Program Files'Microsoft SDKs'Windows'v7.1'Include'UIAutomationClient.h
public const int UIA_LegacyIAccessibleNamePropertyId = 30092;
public const int UIA_LegacyIAccessibleValuePropertyId = 30093;
public const int UIA_IsTextPatternAvailablePropertyId = 30040;
public const int UIA_IsItemContainerPatternAvailablePropertyId = 30108;
public const int UIA_AutomationIdPropertyId = 30011;
public const int UIA_NamePropertyId = 30005;
public const int UIA_IsInvokePatternAvailablePropertyId = 30031;
public const int UIA_ItemContainerPatternId = 10019;
public const int UIA_TextPatternId = 10014;
public const int UIA_LegacyIAccessiblePatternId = 10018;
public const int UIA_ValuePatternId = 10002;
public const int UIA_InvokePatternId = 10000;
public const int UIA_ButtonControlTypeId = 50000;
uiAutomationCore = new UiAutomationCore();
cacheRequest = UiAuto.CreateCacheRequest();
cacheRequest.AddPattern(WindowsConstants.UIA_LegacyIAccessiblePatternId);
cacheRequest.AddProperty(WindowsConstants.UIA_LegacyIAccessibleNamePropertyId);
cacheRequest.AddProperty(WindowsConstants.UIA_LegacyIAccessibleValuePropertyId);
cacheRequest.TreeFilter = UiAuto.ContentViewCondition;
trueCondition = UiAuto.CreateTrueCondition();
// A Pinvoke GetChildWindows call because it is
// the fastest way to traverse down to a handle
foreach (var child in GetChildWindows(someIUIAutomationElement.GetMainWindowHandle()))
{
var sb = new StringBuilder(100);
// get the name of each window & see if it is an ultragrid
// (get the name because the getchildwindows call only gets the handles
User32.GetClassName(child, sb, sb.Capacity);
var foundProperGrid = false;
if (Win32Utils.GetText(child) != "UltraGrid1")
continue;
// if this is an ultragrid, create a core automation object
var iuiae = UiCore.AutoElementFromHandle(child);
// get the children of the grid
var outerArayOfStuff =
iuiae.FindAllBuildCache(interop.UIAutomationCore.TreeScope.TreeScope_Children,
trueCondition,
cacheRequest.Clone());
var countOuter = outerArayOfStuff.Length;
// loop through the grid children
for (var counterOuter = 0; counterOuter < countOuter; counterOuter++)
{
// make a core automation object from each
var uiAutomationElement = outerArayOfStuff.GetElement(counterOuter);
// hacky - see if this grid has a GroupBy Box as first 'row'
// - if so, this is the proper grid
// - ignore other grids
if (!foundProperGrid && uiAutomationElement.CurrentName.Equals("GroupBy Box"))
{
foundProperGrid = true;
}
else if (foundProperGrid)
{
// 'cast' the object to a core 'legacy msaa' object
IUIAutomationLegacyIAccessiblePattern outerLegacyPattern =
uiAutomationElement.GetCachedPattern(WindowsConstants.UIA_LegacyIAccessiblePatternId);
Log.Info("OUTER, CachedName = " + outerLegacyPattern.CachedName);
try
{
// select the 'row' to give visual feedback
outerLegacyPattern.Select(3);
}
catch (Exception exc)
{
Log.Info(exc.Message);
}
// get the cells in a row
var arrayOfStuff =
uiAutomationElement.FindAllBuildCache(TreeScope.TreeScope_Children,
trueCondition,
cacheRequest.Clone());
// loop over the cells in a row
var count = arrayOfStuff.Length;
for (var counter = 0; counter < count; counter++)
{
// get a cell
var currIUIA = arrayOfStuff.GetElement(counter);
// 'cast' cell to a core 'legacy msaa' object
IUIAutomationLegacyIAccessiblePattern legacyPattern =
currIUIA.GetCachedPattern(WindowsConstants.UIA_LegacyIAccessiblePatternId);
// dump cell name & value for reference
var name = legacyPattern.CachedName;
Log.Info(counter + ") CachedName = " + name);
var value = legacyPattern.CachedValue;
Log.Info("CachedValue = " + value);
// check if cell name corresponds to what is being checked
if (name.Equals("Date"))
{
//if (!value.StartsWith("5/23/2012"))
if (!value.StartsWith("5/25/2012"))
errorList.AppendLine("Bad Date = " + value);
}
if (name.Equals("XXX"))
{
if (!(value.Equals("1") || value.Equals("2")))
errorList.AppendLine("Bad XXX= " + value);
}
if (name.Equals("YYY"))
{
if (!value.Equals("ZZZ"))
errorList.AppendLine("Bad YYY = " + value);
}
}
}
}
foundProperGrid = false;
}
var stopTime = DateTime.Now;
var duration = stopTime - startTime;
Log.Info("duration = " + duration);
if (!"".Equals(errorList.ToString()))
{
Log.Info("errorList = " + errorList);
Assert.Fail("Test errors");
}
}