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