【问题标题】:Control any SAVE button (or other) in VBA with IUIAutomation使用 IUIAutomation 控制 VBA 中的任何 SAVE 按钮(或其他按钮)
【发布时间】:2017-08-10 03:56:01
【问题描述】:

在这个论坛中有一些使用IUIAutomationVBA 的意图。但是所有这些都依赖于您知道类的名称以在FindWindowEx 中使用它的事实。其中最受欢迎的是:

Controlling IE11 "Do you want to Open/Save" dialogue window buttons in VBA

hWnd = FindWindowEx(hWnd, 0, "Frame Notification Bar", vbNullString)

本网站中的代码可以帮助您了解 PARENTS 和 CHILDRENS 处理程序之间的关系 http://www.vbaexpress.com/kb/getarticle.php?kb_id=52

Autoit -> AutoIt Window Info) https://www.autoitscript.com/site/autoit/ 允许您单击窗口并获取处理程序/类/名称详细信息。

很难缩小到我们想要点击的元素。此代码允许您这样做

Sub test2()

Dim h1, h2 As Long
Dim sWindowName As String

    Dim AutomationObj As IUIAutomation
    Dim WindowElement As IUIAutomationElement
    Dim Button As IUIAutomationElement
    Dim hWnd As LongPtr

sWindowName = vbNullString

Set AutomationObj = New CUIAutomation

h1 = FindWindow("#32770", "Internet Explorer")

Debug.Print h1

While h1 <> 0

    h2 = FindWindowEx(h1, 0, vbNullString, sWindowName)

    If h2 <> 0 Then


       Set WindowElement = AutomationObj.ElementFromHandle(ByVal h2)
       Dim iCnd As IUIAutomationCondition
       Set iCnd = AutomationObj.CreatePropertyCondition(UIA_NamePropertyId, "Save")

       Set Button = WindowElement.FindFirst(TreeScope_Subtree, iCnd)
       Dim InvokePattern As IUIAutomationInvokePattern

       If Button.CurrentName = "Save" Then
            Set InvokePattern = Button.GetCurrentPattern(UIA_InvokePatternId)
            InvokePattern.Invoke
            h1 = 0

     Else

        h1 = h2
       End If


    Else
        h1 = 0
    End If

    Debug.Print h2

Wend

End Sub

h1FindWindow 允许您缩小范围以获取 IE 窗口的句柄(以及 SAVE 按钮)

有没有人有比这更好的方法?.. 因为在这里我只是循环通过 #32770 下的处理程序等待获取 SAVE 按钮。它确实有效,但我希望它应该是一种系统/有效的方式来了解如何在IUIAutomation 中使用正确的处理程序

【问题讨论】:

    标签: vba excel ui-automation hwnd


    【解决方案1】:

    您可以通过 inspect.exe 看到多种方法来确定您的元素。在示例部分的 autoit 中,您可以找到许多有关如何处理 ms uia 的示例。您可以使用 createtruecondition 从 getrootelement 开始过滤,该条件也适用于 vba。然后,您将获得桌面根元素的所有主窗口。

    编辑 2021 使用 Powershell 5.1 和 ISE,您可以根据鼠标位置和定义的热键进行非常基本的间谍活动,然后您可以在 ISE 中使用不同的 UIA 模式进行一些操作。无需安装额外的工具。

    1. 打开 powershell ISE(5.1 可以)
    2. 运行脚本,它将扩展 带有新菜单(但更重要的是热键)的 ISE 环境
    3. 将鼠标悬停在您感兴趣的对象上
    4. 按 ctrl+shift+w
    5. 您应该会在 ISE 窗口中看到一些输出
    6. 玩弄你的 $ae 来自 cmdline 的自动化元素 扩展 get-elementInfo 根据您自己的想法运行(仅运行函数,因为它会重新加载 直接)

    clear-host 
    #region load the most important GUI assemblies
    Add-Type –AssemblyName UIAutomationClient
    Add-Type –AssemblyName UIAutomationTypes
    Add-Type –AssemblyName UIAutomationProvider
    Add-Type –AssemblyName UIAutomationClientsideProviders
    
    Add-Type -AssemblyName System.Windows.Forms
    [void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
    #endregion
    
    #region addons
    $spyName='Spy'
    
    $MyEntry = $psISE.CurrentPowerShellTab.AddOnsMenu.Submenus | ?{$_.DisplayName -eq $spyName}
    
    if ($myEntry -ne $null) {$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Remove($MyEntry)}
    
    $psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add($spyName,{ get-elementInfo },"CTRL+SHIFT+W") | out-null
    
    #endregion
    
    function get-elementInfo() {
        $Mouse = [System.Windows.Forms.Cursor]::Position
        $global:ae = [System.Windows.Automation.AutomationElement]::FromPoint([system.windows.point]::new($mouse.x,$mouse.y))
        $ae.current
    }
    
    get-elementInfo
    
    # Stuff you could type in your blue part of ISE
    # $ae.getcurrentpattern([Windows.Automation.ValuePattern]::Pattern).setvalue("Hello world")
    # $ae.GetCurrentPattern([Windows.Automation.InvokePattern]::Pattern).Invoke()

    【讨论】:

      猜你喜欢
      • 2019-08-01
      • 2012-06-23
      • 2012-06-02
      • 2015-05-11
      • 2015-08-05
      • 1970-01-01
      • 2017-06-11
      • 2018-04-11
      • 1970-01-01
      相关资源
      最近更新 更多