如何从UIAutomation获取隐藏的/私有的UI元素,我可以在Spy ++中看到它,但不能在代码中看到它,只有它的父母和兄弟姐妹

时间:2019-03-28 21:04:02

标签: windows vb.net ui-automation spy++

我正在尝试使用System.Windows.Automation来访问VLC媒体播放器中的UI元素(特别是最左角的状态框,其中显示了当前正在播放的视频的文件名)。我可以获取父元素和同级元素,但是在Spy ++中,所有它们旁边带有暗淡图标的元素我都无法在代码中到达...我假设暗淡的图标表示它们是私有的或隐藏的或类似的东西。这是一张图片,显示我的意思:

enter image description here

请注意,我有一个对句柄为0x30826的父对象的引用,并且我从中进行了FindAll()*运算,最后只得到一个结果,即对一个对子句柄为0x30858的引用。您可以在Spy ++中看到5个0x30826子级,但是只有一个,我在执行FindAll时得到的一个,有一个全黑的图标,其他有一个灰色的图标,我无法接触它们。还要注意,我想要的是0x20908,它有一个灰色图标...

如何通过代码实现?

*这是我用来尝试获取0x30826的所有子代的代码:

    Dim aeDesktop As AutomationElement
    Dim aeVLC As AutomationElement
    Dim c As AutomationElementCollection
    Dim cd As New AndCondition(New PropertyCondition(AutomationElement.IsEnabledProperty, True), New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.StatusBar))

    aeVLC = aeDesktop.FindFirst(TreeScope.Children, New PropertyCondition(AutomationElement.NameProperty, "got s01e01.avi - VLC media player"))

    c = aeVLC.FindAll(TreeScope.Children, cd)

    c = c(0).FindAll(TreeScope.Children, Condition.TrueCondition)

第一个FindAll()仅给我0x30826,这很好,因为那是我想要的,但是第二个FindAll(未指定条件)仅给我提供0x30858,我可以看到它加上Spy ++中的其他4个,包括那个我想要。

1 个答案:

答案 0 :(得分:1)

使用Spy ++而不是Inspect Program确实使您的工作受阻。使用Inspect,您可以轻松地看到目标元素是作为 status bar 元素的父元素的 text 元素,而 window 主元素的父元素

VLC in Inspect

使用该信息,直接引用目标 text 元素。首先获取主窗口,然后获取其状态栏,最后是状态栏的第一个文本元素。

' find the VLC process 
Dim targets As Process() = Process.GetProcessesByName("vlc")

If targets.Length > 0 Then

    ' assume its the 1st process 
    Dim vlcMainWindowHandle As IntPtr = targets(0).MainWindowHandle

    ' release all processes obtained
    For Each p As Process In targets
        p.Dispose()
    Next

    ' use vlcMainWindowHandle to get application window element
    Dim vlcMain As AutomationElement = AutomationElement.FromHandle(vlcMainWindowHandle)

    ' get the statusbar
    Dim getStatusBarCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.StatusBar)
    Dim statusBar As AutomationElement = vlcMain.FindFirst(TreeScope.Children, getStatusBarCondition)

    ' get the 1st textbox in the statusbar
    Dim getTextBoxCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text)
    Dim targetTextBox As AutomationElement = statusBar.FindFirst(TreeScope.Children, getTextBoxCondition)

    ' normally you use either a TextPattern.Pattern or ValuePattern.Pattern
    ' to obtain the text, but this textbox exposes neither and it uses the
    ' the Name property for the text.

    Dim textYouWant As String = targetTextBox.Current.Name

End If