使用 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 属性为空时出现问题。

有没有其他方法可以读取单元格? 或我可以进行的任何更改,请详细说明。

使用 C# 从另一个应用程序的 SysListView32 中的数据网格中读取单元格项

我还建议使用检查工具。 如果您看到以下内容:

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");
        }
    }