1

我正在尝试使用下面的代码从 SysListView32 对象中检索数据,但它返回一个空字符串。

ControlType.ListItem根据 Inspector 的打印 ,我需要检索的元素是那些以红色突出显示的元素,以及其他元素中包含的其他元素。

有人可以检查我的代码有什么问题吗?

督察

Msgbox("Position the mouse cursor on the screen and press ENTER.")

Dim pt As POINTAPI
GetCursorPos(pt)

Dim hwnd As IntPtr = WindowFromPoint(pt)

Dim hwnd As IntPtr = 67202
Dim el As AutomationElement = AutomationElement.FromHandle(hwnd)
Dim walker As TreeWalker = TreeWalker.ContentViewWalker
Dim i As Integer = 0
Dim child As AutomationElement = walker.GetFirstChild(el)

While child IsNot Nothing
    '
    Dim k As Integer = 0
    Dim child2 As AutomationElement = walker.GetFirstChild(child)

    While child2 IsNot Nothing
        Console.WriteLine(child2.Current.ToString)
        child2 = walker.GetNextSibling(child2)
    End While

    child = walker.GetNextSibling(child)
End While
4

1 回答 1

1

如果当前视图状态不是 SysListView32 可能无法提供请求的信息LV_VIEW_DETAILS,因此我们应该暂时(如果当前视图状态不同)使用其 AutomationElement 的MultipleViewPattern来验证视图状态,并在必要时使用MultipleViewPattern 进行更改。 SetCurrentView()方法。

SetCurrentView()方法使用 Win32 控件的相同值。

然后使用 AutomationElement FindAll()方法查找ControlType.DataItemControlType.ListItem(使用OrCondition)类型的所有子元素。

对于它们中的每一个,获取类型ControlType.EditControlType.Text(使用另一个OrCondition)的所有子项。

使用 Item 的GridItemPattern检索列表中每个 Item 的位置,以访问 Item 的Row属性。

最后,如果我们必须更改它,我们将恢复之前的视图状态。


示例中的代码填充了一个Dictionary(Of Integer, ListViewItem)( sysListViewItems),其中包含从 SysListView32 中提取的所有项目。

  • Integer Key表示一个Item在原始ListView中的位置
  • ListViewItem 是从每个项目中提取的值数组(作为字符串)生成的 .Net 对象。

如果您不需要 ListViewItem 对象,您可以只存储List(Of String)由该itemsText对象表示的 ,而不是在此处创建 ListViewItem :

sysListViewItems.Add(gridPattern.Current.Row, New ListViewItem(itemsText.ToArray())).  

SysListView32 的句柄也可以通过枚举其顶级窗口的子级来获取ClassName
AutomationElement.RootElement提供当前的桌面元素:

Dim parentWindow = AutomationElement.RootElement.FindFirst(
    TreeScope.Children, New PropertyCondition(AutomationElement.NameProperty, "[Window Caption]"))
Dim sysListView32 = parentWindow.FindAll(
    TreeScope.Subtree, New PropertyCondition(AutomationElement.ClassNameProperty, "SysListView32"))

如果找到多个 SysListView32,请按 Header 内容、直接父项ControlTypeClassName任何其他允许将其单独列出的内容进行过滤。

UI 自动化需要对UIAutomationClientUIAutomationTypes程序集的引用。


Imports System.Windows.Automation

Dim sysListViewHandle = [GetSysListView32Handle()]

Dim sysListViewElement = AutomationElement.FromHandle(sysListViewHandle)
If sysListViewElement Is Nothing Then Return

Dim sysListViewItems = New Dictionary(Of Integer, ListViewItem)()
Dim mulView As MultipleViewPattern = Nothing
Dim pattern As Object = Nothing
Dim currentView As Integer = -1

If sysListViewElement.TryGetCurrentPattern(MultipleViewPattern.Pattern, pattern) Then
    mulView = DirectCast(pattern, MultipleViewPattern)
    currentView = mulView.Current.CurrentView
    If currentView <> ListViewWState.LV_VIEW_DETAILS Then
        mulView.SetCurrentView(ListViewWState.LV_VIEW_DETAILS)
    End If
End If

Dim childItemsCondition = New OrCondition(
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem),
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem))

Dim childItems = sysListViewElement.FindAll(TreeScope.Children, childItemsCondition)
If childItems.Count = 0 Then Return

Dim subItemsCondition = New OrCondition(
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit),
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text))

For Each item As AutomationElement In childItems
    Dim itemsText = New List(Of String)()
    Dim subItems = item.FindAll(TreeScope.Children, subItemsCondition)
    For Each subItem As AutomationElement In subItems
        itemsText.Add(subItem.Current.Name)
    Next
    Dim gridPattern = DirectCast(subItems(0).GetCurrentPattern(GridItemPattern.Pattern), GridItemPattern)
    sysListViewItems.Add(gridPattern.Current.Row, New ListViewItem(itemsText.ToArray()))
Next

If mulView IsNot Nothing Then
    mulView.SetCurrentView(currentView)
End If

Friend Enum ListViewWState
    LV_VIEW_ICON = &H0
    LV_VIEW_DETAILS = &H1
    LV_VIEW_SMALLICON = &H2
    LV_VIEW_LIST = &H3
    LV_VIEW_TILE = &H4
End Enum
于 2020-04-16T00:00:55.393 回答