zoukankan      html  css  js  c++  java
  • AutoHotkey 使用 UI Automation(UIA) 获取相关信息简易教程-20210210

    UI Automation 是微软用来替代 Microsoft Active Accessibility(msaa) 的接口,有服务端和客户端,对于脚本用户来说主要就是客户端相关功能,

    可以很大程度地帮助我们获取更多有效信息,能获取微信,QQ里的各种内容,还能设置网页里输入框内容并点击按钮。应用场景很多,对控件的操作应该也是很强悍的,还没研究透。

    AutoHotkey 的库,首先应该是国人 nepter 写的,核心问题都解决了,可惜后续似乎没有更新,

    网上应该没什么 AutoHotkey 关于 UIA 的中文教程(很多编程中文资料都比较欠缺),

    借着春节的放假时间,终于下定决心研究下,没有人指点的学习太难了。

    改成了 AutoHotkey V2的语法,库的部分设计思路也按自己想法调整了。

    整体思路和示例代码(包含 inspect.exe)都在附件里→ hyUIA.zip

    下载后运行 hyUIA.exe,按F9(谷歌浏览器打开百度首页,鼠标停留在微信消息上)有简易示例,F10 可获取鼠标下的控件信息,其他的请自行看代码。

    里面还有不少内容没研究清楚,用的还是比较浅的功能,对结构复杂的页面,应该用哪种方式能更加稳定地获取控件,还需要进一步学习

    有些功能还是不完善的,主要还是希望能帮助大家入门。有错误和意见也希望能留下您的评论,谢谢。

    NOTE NOTE NOTE 思路:
    说明:
        1. 窗口、控件、控件选项(比如 ComboBox 的每个选项)在 UIA 里全是 element, 获取方式是一样的,结构见 inspect.exe
        2. 主要类有
            IUIAutomation: 核心类,其他类都继承于此,element pattern condition 等创建的方法基本上都在此
            IUIAutomationElement: element 的相关方法
            IUIAutomationPattern: element 可进行的操作,比如 Invoke(Button) Value_SetValue(Edit) SelectionItem_Select
            IUIAutomationCondition: 用来查找控件的条件,主要用在非标准窗口,借 inspect 工具来查找
            IUIAutomationCacheRequest: 批量获取信息时用此缓存加速(不太了解)
            每个类都有个 __ 属性(用在 dllcall),其他基本上全是方法
        3. dllcall的函数入口是通过【地址】(每个类的 __ 属性)+【偏移】(IUIAutomation._vt)实现的
        4. 返回值如果是 variant 格式,用 _getVariantValue() 获取(注意参数)
    
    步骤:
        1.oUIA := new IUIAutomation()
        2.获取【窗口】或【控件】oAE(为 IUIAutomationElement 类的实例,获取方式见 IUIAutomationElement_instance 下面的方法)
            2.1简单的推荐直接用 ElementFromHandle() ElementFromPoint() GetFocusedElement()
            2.2如果是非标准窗口,一般先获取整个窗口控件 oAE_win := oUIA.ElementFromHandle(hwnd),再【搜索】特定的控件,搜索方法:
            NOTE 推荐用我封装的函数 oUIA.FindControl(WinGetID(), 控件名, 其他字段名, 值)
                比如Excel的【查找和替换】对话框,可用下面方法获取 Name="范围(H)": 的 ComboBox
                oAE := oUIA.FindControl(WinGetID("A"), "ComboBox", "Name", "范围(H):")
            ①指定匹配条件 condition
                单条件(用得少)
                    控件类型
                        condition := oUIA.CreatePropertyCondition("ControlType", oUIA._ct("Button"), VT_I4:=3)
                    控件文本 TODO 能否用包含来匹配,而不是精确
                        condition := oUIA.CreatePropertyCondition("Name", "确定", 8)
                    控件AutomationId
                        condition := oUIA.CreatePropertyCondition("AutomationId", "", 8)
                组合条件(And)
                    ;两个条件可用 And 组合
                        condition := oUIA.CreateAndCondition(oUIA.CreatePropertyCondition("ControlType", oUIA._ct("Button"), VT_I4:=3), oUIA.CreatePropertyCondition("Name", "确定", 8))
                    ;更多条件用 array 组合
                        condition := oUIA.CreateAndConditionFromArray([oUIA.CreatePropertyCondition("Name","范围(H):",8), oUIA.CreatePropertyCondition("ControlType",oUIA._ct("ComboBox"),VT_I4:=3)])
            ②搜索范围 scope 见 enum_TreeScope
            ③开始搜索
                查找单个
                    oAE_win.FindFirst(condition, TreeScope_Descendants:=0x4)
                查找全部
                    for _, oAE in oAE_win.FindAll(condition, TreeScope_Descendants:=0x4)
        4.获取控件的属性(查看控件所有属性见 IUIAutomation_p,获取方法,见 IUIAutomationElement_vt)
            常用属性 见 usefullProperty
            部分属性要用 GetCurrentPropertyValue,
                GetCurrentPropertyValue("ValueValue") ;主要用这个
                GetCurrentPropertyValue("BoundingRectangle")
                GetCurrentPropertyValue("LegacyIAccessibleName") ;大部分和上面的 CurrentName 返回值一样
                GetCurrentPropertyValue("LegacyIAccessibleValue") ;大部分和 GetCurrentPropertyValue("ValueValue") 返回值一样
        5.操作控件,见类 IUIAutomationPattern 上方相关说明,可操作列表见 IUIAutomationPattern_vt
            点击按钮
                oAE.GetCurrentPattern("Invoke").Invoke_Invoke()
            修改文字
                oAE.GetCurrentPattern("Value").Value_SetValue("hello")
            激活控件
                oAE.SetFocus()
            修改选择项,每个选择项都是个控件,需要先找到选项项的控件(比如 ComboBox 下的每个 ListItem) 未试
                oAE_ListItem.GetCurrentPattern("SelectionItem").SelectionItem_Select()
        6.遍历 IUIAutomation_TreeWalker(TODO 一般用 FindAll)
        7.事件监听 TODO
            oUIA.AddAutomationEventHandler("Text_TextChanged", oAE, TreeScope_Element:=1, rst, handler)

    官方说明,nepter 库和其他相关参考链接也都附上。

    NOTE 客户端程序员指南
    是 acc 的升级版,区别 https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-msaa
    https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/
    https://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/ui-automation-of-a-wpf-custom-control?redirectedfrom=MSDN&view=netframeworkdesktop-4.8

    https://github.com/neptercn/UIAutomation
    https://www.autohotkey.com/board/topic/94619-ahk-l-screen-reader-a-tool-to-get-text-anywhere

    https://github.com/jethrow/UIA_Interface
    https://github.com/sancarn/Inspect.exe_AHK

    https://www.cnblogs.com/ellie-test/p/4427323.html
    https://www.cnblogs.com/ellie-test/p/4430533.html

    https://www.autohotkey.com/boards/viewtopic.php?p=135520
    https://www.autohotkey.com/boards/viewtopic.php?p=300069

    https://v.youku.com/v_show/id_XNTcyNDM2NjA0.html?spm=a2h0c.8166622.PhoneSokuUgc_8.dtitle
    https://v.youku.com/v_show/id_XMTM2MjE3NTAwMA==.html?spm=a2h0c.8166622.PhoneSokuUgc_1.dtitle

    https://www.youtube.com/watch?v=yJmpNuic7bQ
    https://www.youtube.com/watch?v=tLoo707k0yI
    https://www.youtube.com/watch?v=V8iHQXq6kXA

  • 相关阅读:
    HDOJ1003 MaxSum【逆推】
    HDOJ1698 Just a hook【线段树成段更新lazy标志】武科大ACM暑期集训队选拔赛4题
    HDOJ1102 Constructing Roads【最小生成树】武科大ACM暑期集训队选拔赛1题
    POJ2828 Buy Tickets【线段树,逆序遍历】
    HDOJ1215 ( 七夕节 )【居然还可以这么解~】
    HDOJ1089HDOJ1096【格式练习】
    HDOJ1233 ( 还是畅通工程 ) 【最小生成树,kruscal】
    HDOJ1035 ( Robot Motion ) 【递归】
    POJ3468 A Simple Problem with Integers【线段树 成段更新+求和 lazy标志】
    HDOJ1216 Assistance Required【打表】武科大ACM暑期集训队选拔赛7题
  • 原文地址:https://www.cnblogs.com/hyaray/p/14396015.html
Copyright © 2011-2022 走看看