剔除了一些用处不大的函数,提供了一些如遍历和等待功能
部分基础操作示例:
基本的元素获取:
ele := UIA.ElementFromHandle(WinExist("A")) ; 获取窗口元素
ele := UIA.ElementFromPoint(100 | 200 << 32) ; 获取屏幕坐标 100, 200 的元素
ele := UIA.GetFocusedElement() ; 获取当前具有键盘焦点的元素
基本属性的获取:
ele := UIA.ElementFromHandle(WinExist("A"))
MsgBox ele.Name
MsgBox ele.ClassName
pos := ele.BoundingRectangle
MsgBox pos.left " " pos.top " " pos.right " " pos.bottom
获取指定QQ聊天的最新消息:
DetectHiddenWindows(true)
qq := UIA.ElementFromHandle(WinExist("QQ ahk_class TXGuiFoundation"))
condi := UIA.CreatePropertyCondition(30005, "AutoHotkey(ahk) | 中文社区") ;创建一个条件,指定30005: Name
dialog := qq.FindFirst(condi)
MsgBox dialog.Value
获取Edge浏览器的当前URL内容:
chrome := UIA.ElementFromHandle(WinExist("ahk_exe msedge.exe"))
; 有时候通过FindFirst寻找元素可能会比较慢,可以用TreeWalker指定搜索条件
walker := UIA.CreateTreeWalker(UIA.CreatePropertyCondition(30006, "Ctrl+L")) ; 30006: AcceleratorKey
search_bar := walker.GetFirstChildElement(chrome)
MsgBox search_bar.Value
还可以简单地操作网页,打开bing并搜索指定内容:
Run "www.bing.com"
hwnd := WinWaitActive("必应")
page := UIA.ElementFromHandle(hwnd)
condi1 := UIA.CreatePropertyCondition(30005, "Enter your search term")
; 组合两个条件
condi2 := UIA.CreateAndCondition(UIA.CreatePropertyCondition(30005, "Search"), UIA.CreatePropertyCondition(30003, 50000))
if search_box := page.Wait(condi1, 3000) {
search_box.Value := "Autohotkey"
if search_button := page.Wait(condi2, 3000)
search_button.Invoke()
}
另外还有类似于钩子的机制可以异步监控不同种类的事件,这里展示焦点变化事件的监控:
Persistent
handler := UIA.AddFocusChangedEventHandler(HandleFocusChangedEvent)
; 解除监控
; UIA.RemoveFocusChangedEventHandler(handler)
; handler := ""
HandleFocusChangedEvent(this, sender){
ToolTip "焦点变化了"
}
人比较懒,上面只展示了一小部分功能,感兴趣可以在 Uiautomationclient.h header – Win32 apps | Microsoft Docs 上面学习研究其他应用,发现bug欢迎留言。
下面是类库:
;property_id: https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-automation-element-propids
;traversal_options: https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/ne-uiautomationclient-treetraversaloptions
class UIA {
static PropertyVarTypeMap := [0x2003, 0x2005, 0x3, 0x3, 0x8, 0x8, 0x8, 0x8, 0xB, 0xB, 0xB, 0x8, 0x8, 0x8, 0x2005, 0x3, 0xB, 0xB, 0xD, 0xB, 0x3, 0x8, 0xB, 0x3, 0x8, 0xB, 0x8, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, 0x8, 0xB, 0x5, 0xB, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0xB, 0xB, 0x200D, 0xB, 0xB, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0xD, 0x3, 0x3, 0x3, 0x2003, 0xB, 0xB, 0x3, 0x3, 0xB, 0xB, 0xB, 0xD, 0x200D, 0x200D, 0x3, 0x200D, 0x200D, 0x3, 0xB, 0xB, 0xB, 0xB, 0x3, 0x8, 0x8, 0x8, 0x3, 0x3, 0x8, 0x8, 0x200D, 0x8, 0x8, 0x8, 0xB, 0x200D, 0x200D, 0x200D, 0x8, 0xB, 0xB, 0xB, 0xB, 0xB, 0x3, 0x8, 0x8, 0x8, 0xD, 0xB, 0xB, 0x3, 0x8, 0x3, 0x8, 0x8, 0x3, 0x8, 0xB, 0xB, 0x8, 0x200D, 0x2003, 0xB, 0xB, 0xB, 0x3, 0xB, 0xB, 0xB, 0x8, 0x2008, 0xB, 0x8, 0x2008, 0x200D, 0x5, 0x5, 0x5, 0x200D, 0xB, 0xB, 0xB, 0x3, 0x3, 0x3, 0x2003, 0x2003, 0x3, 0x8, 0x8, 0x3, 0x2003, 0x3, 0x3, 0x2005, 0x2005, 0x5, 0x2005, 0x3, 0xB]
static ControlPatternMap := [IUIAutomationInvokePattern, IUIAutomationSelectionPattern, IUIAutomationValuePattern, IUIAutomationRangeValuePattern, IUIAutomationScrollPattern, IUIAutomationExpandCollapsePattern, IUIAutomationGridPattern, IUIAutomationGridItemPattern, , , IUIAutomationSelectionItemPattern, , , , IUIAutomationTextPattern, , , IUIAutomationScrollItemPattern, IUIAutomationLegacyIAccessiblePattern, , , , , , IUIAutomationTextPattern, , , , , IUIAutomationTextChildPattern, , , IUIAutomationTextEditPattern, ]
static Ptr := ComObjValue(this.Co := ComObject("{e22ad333-b25f-460c-83d0-0581107395c9}", "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}"))
static CompareElements(ele1, ele2) => (ComCall(3, this, "ptr", ele1, "ptr", ele2, "int*", &same := 0), same)
static CompareRuntimeIds(id1, id2) => (ComCall(4, this, "ptr", id1, "ptr", id2, "int*", &same := 0), same)
static GetRootElement() => (ComCall(5, this, "ptr*", &ele := 0), IUIAutomationElement(ele))
static ElementFromHandle(hwnd := unset) => (ComCall(6, this, "ptr", IsSet(hwnd) ? hwnd : WinExist("A"), "ptr*", &ele := 0), IUIAutomationElement(ele))
static ElementFromPoint(pt := unset) => (ComCall(7, this, "int64", IsSet(pt) ? pt : (DllCall("GetCursorPos", "Int64*", &pt := 0), pt), "ptr*", &ele := 0), IUIAutomationElement(ele))
static GetFocusedElement() => ComCall(8, this, "ptr*", &ele := 0) ? "" : IUIAutomationElement(ele)
static CreateTreeWalker(condition) => (ComCall(13, this, "ptr", condition, "ptr*", &walker := 0), IUIAutomationTreeWalker(walker))
static ControlViewWalker => (ComCall(14, this, "ptr*", &walker := 0), IUIAutomationTreeWalker(walker))
static ContentViewWalker => (ComCall(15, this, "ptr*", &walker := 0), IUIAutomationTreeWalker(walker))
static RawViewWalker => (ComCall(16, this, "ptr*", &walker := 0), IUIAutomationTreeWalker(walker))
static RawViewCondition => (ComCall(17, this, "ptr*", &condition := 0), IUIAutomationCondition(condition))
static ControlViewCondition => (ComCall(18, this, "ptr*", &condition := 0), IUIAutomationCondition(condition))
static ContentViewCondition => (ComCall(19, this, "ptr*", &condition := 0), IUIAutomationCondition(condition))
static CreateTrueCondition() => (ComCall(21, this, "ptr*", &condition := 0), IUIAutomationBoolCondition(condition))
static CreateFalseCondition() => (ComCall(22, this, "ptr*", &condition := 0), IUIAutomationBoolCondition(condition))
static CreatePropertyCondition(property_id, val) => (ComCall(23, this, "int", property_id, "ptr", Variant(UIA.PropertyVarTypeMap[property_id - 29999], val), "ptr*", &condition := 0), IUIAutomationPropertyCondition(condition))
static CreatePropertyConditionEx(property_id, val, flags) => (ComCall(24, this, "int", property_id, "ptr", Variant(UIA.PropertyVarTypeMap[property_id - 29999], val), "uint", flags, "ptr*", &condition := 0), IUIAutomationPropertyCondition(condition))
static CreateAndCondition(condition1, condition2) => (ComCall(25, this, "ptr", condition1, "ptr", condition2, "ptr*", &condition := 0), IUIAutomationAndCondition(condition))
static CreateAndConditionFromNativeArray(conditions) => (ComCall(27, this, "ptr", NativeArray("ptr", conditions), "int", conditions.Length, "ptr*", &conditon := 0), IUIAutomationAndCondition(conditon))
static CreateOrCondition(condition1, condition2) => (ComCall(28, this, "ptr", condition1, "ptr", condition2, "ptr*", &condition := 0), IUIAutomationOrCondition(condition))
static CreateOrConditionFromNativeArray(conditions) => (ComCall(30, this, "ptr", NativeArray("ptr", conditions), "ptr", conditions.Length, "ptr*", &condition := 0), IUIAutomationOrCondition(condition))
static CreateNotCondition(condition) => (ComCall(31, this, "ptr", condition, "ptr*", &new_condition := 0), IUIAutomationNotCondition(new_condition))
static AddAutomationEventHandler(event_id, element, callback, scope := 5) => (ComCall(32, this, "int", event_id, "ptr", element, "int", scope, "ptr", 0, "ptr", handler := EventHandler(callback, "{146C3C17-F12E-4E22-8C27-F894B9B79C69}")), handler)
static RemoveAutomationEventHandler(event_id, element, handler) => ComCall(33, this, "int", event_id, "ptr", element, "ptr", handler)
static AddPropertyChangedEventHandlerNativeArray(element, callback, property_array, scope := 5) => (ComCall(34, this, "ptr", element, "int", scope, "ptr", 0, "ptr", handler := EventHandler(callback, "{40CD37D4-C756-4B0C-8C6F-BDDFEEB13B50}"), "ptr", NativeArray("int", property_array), "int", property_array.Length), handler)
static RemovePropertyChangedEventHandler(element, handler) => ComCall(36, this, "ptr", element, "ptr", handler)
static AddStructureChangedEventHandler(element, callback, scope := 5) => (ComCall(37, this, "ptr", element, "int", scope, "ptr", 0, "ptr", handler := EventHandler(callback, "{E81D1B4E-11C5-42F8-9754-E7036C79F054}")), handler)
static RemoveStructureChangedEventHandler(element, handler) => ComCall(38, this, "ptr", element, "ptr", handler)
static AddFocusChangedEventHandler(callback) => (ComCall(39, this, "ptr", 0, "ptr", handler := EventHandler(callback, "{C270F6B5-5C69-4290-9745-7A7F97169468}")), handler)
static RemoveFocusChangedEventHandler(handler) => ComCall(40, this, "ptr", handler)
static RemoveAllEventHandlers() => ComCall(41, this)
}
class IUIAutomationElement extends Interface {
Wait(condition, time_limit := 0, traversal_options := 0, root := 0, scope := 4) {
time_start := A_TickCount
loop {
try {
return ele := this.FindFirstWithOptions(condition, traversal_options, root, scope)
} catch {
if (time_limit > 0) && (A_TickCount - time_start > time_limit)
break
else
continue
}
}
}
TraverseDescendants(callback){
try {
walker := UIA.ControlViewWalker
node := walker.GetFirstChildElement(this)
} catch {
return
}
loop {
callback(node)
node.TraverseDescendants(callback)
try
node := walker.GetNextSiblingElement(node)
catch
break
}
}
Invoke() => this.GetCurrentPattern(10000).Invoke()
SetFocus() => ComCall(3, this)
GetRuntimeId() => (ComCall(4, this, "ptr*", &id := 0), ComValue(0x2003, id))
FindFirst(condition, scope := 4) => (ComCall(5, this, "uint", scope, "ptr", condition, "ptr*", &ele := 0), IUIAutomationElement(ele))
FindAll(condition, scope := 4) => (ComCall(6, this, "uint", scope, "ptr", condition, "ptr*", &eles := 0), IUIAutomationElementArray(eles))
GetCurrentPropertyValue(property_id) => (ComCall(10, this, "int", property_id, "ptr", val := Variant()), val[])
GetCurrentPropertyValueEx(property_id, ignore_default_value) => (ComCall(11, this, "int", property_id, "int", ignore_default_value, "ptr", val := Variant()), val[])
GetCurrentPattern(pattern_id) => (ComCall(16, this, "int", pattern_id, "ptr*", &patternObject := 0), UIA.ControlPatternMap[pattern_id - 9999](patternObject))
CurrentProcessId => (ComCall(20, this, "int*", &ret_val := 0), ret_val)
CurrentControlType => (ComCall(21, this, "int*", &ret_val := 0), ret_val)
CurrentLocalizedControlType => (ComCall(22, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
Name => (ComCall(23, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
Value {
get => this.GetCurrentPropertyValue(30045)
set => this.GetCurrentPattern(10002).SetValue(Value)
}
AcceleratorKey => (ComCall(24, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
AccessKey => (ComCall(25, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
HasKeyboardFocus => (ComCall(26, this, "int*", &ret_val := 0), ret_val)
IsKeyboardFocusable => (ComCall(27, this, "int*", &ret_val := 0), ret_val)
IsEnabled => (ComCall(28, this, "int*", &ret_val := 0), ret_val)
AutomationId => (ComCall(29, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
ClassName => (ComCall(30, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
HelpText => (ComCall(31, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
Culture => (ComCall(32, this, "int*", &ret_val := 0), ret_val)
IsControlElement => (ComCall(33, this, "int*", &ret_val := 0), ret_val)
IsContentElement => (ComCall(34, this, "int*", &ret_val := 0), ret_val)
IsPassword => (ComCall(35, this, "int*", &ret_val := 0), ret_val)
NativeWindowHandle => (ComCall(36, this, "ptr*", &ret_val := 0), ret_val)
IsOffscreen => (ComCall(38, this, "int*", &ret_val := 0), ret_val)
BoundingRectangle => (ComCall(43, this, "ptr", ret_val := Buffer(16)), { Left: NumGet(ret_val, "int"), Top: NumGet(ret_val, 4, "int"), Right: NumGet(ret_val, 8, "int"), Bottom: NumGet(ret_val, 12, "int") })
ProviderDescription => (ComCall(51, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
GetClickablePoint(&clickable) => (ComCall(84, this, "int64*", &clickable := 0, "int*", &got_clickable := 0), got_clickable)
FindFirstWithOptions(condition, traversal_options, root := 0, scope := 4) => (ComCall(110, this, "int", scope, "ptr", condition, "int", traversal_options, "ptr", root, "ptr*", &found := 0), IUIAutomationElement(found))
FindAllWithOptions(condition, traversal_options, root := 0, scope := 4) => (ComCall(111, this, "int", scope, "ptr", condition, "int", traversal_options, "ptr", root, "ptr*", &found := 0), IUIAutomationElementArray(found))
}
class IUIAutomationElementArray extends Interface {
Length => (ComCall(3, this, "int*", &len := 1), len)
GetElement(index) => (ComCall(4, this, "int", index, "ptr*", &ele := 0), IUIAutomationElement(ele))
}
class IUIAutomationTreeWalker extends Interface {
; Parent 0x10000 FirstChild 0x20000 LastChild 0x30000 NextSibling 0x40000 PreviousSibling 0x50000
Navigate(ele, way) {
static action := [this.GetParentElement, this.GetFirstChildElement, this.GetLastChildElement, this.GetNextSiblingElement, this.GetPreviousSiblingElement]
for , v in way {
loop v & 0x0000ffff
ele := action[(v >> 16)](this, ele)
}
return ele
}
GetWayFromContainerWindow(ele, &container := 0) {
desktop := UIA.GetRootElement()
if UIA.CompareElements(desktop, ele)
throw Error("The element is a root element or container window.")
way := [0x20000]
loop {
parent := this.GetParentElement(ele)
if UIA.CompareElements(desktop, parent) {
container := ele
return way[way.Length] = 0x20000 ? (way.Pop(), way) : way
}
idx := 0
child := this.GetFirstChildElement(parent)
while !UIA.CompareElements(ele, child)
child := this.GetNextSiblingElement(child), idx++
if idx
way.InsertAt(1, 0x20001, 0x40000 | idx)
else
way[1]++
ele := parent
}
}
GetParentElement(ele) => (ComCall(3, this, "ptr", ele, "ptr*", &parent := 0), IUIAutomationElement(parent))
GetFirstChildElement(ele) => (ComCall(4, this, "ptr", ele, "ptr*", &first := 0), IUIAutomationElement(first))
GetLastChildElement(ele) => (ComCall(5, this, "ptr", ele, "ptr*", &last := 0), IUIAutomationElement(last))
GetNextSiblingElement(ele) => (ComCall(6, this, "ptr", ele, "ptr*", &next := 0), IUIAutomationElement(next))
GetPreviousSiblingElement(ele) => (ComCall(7, this, "ptr", ele, "ptr*", &previous := 0), IUIAutomationElement(previous))
}
class IUIAutomationInvokePattern extends Interface {
Invoke() => ComCall(3, this)
}
class IUIAutomationSelectionPattern extends Interface {
GetCurrentSelection() => (ComCall(3, this, "ptr*", &ret_val := 0), IUIAutomationElementArray(ret_val))
CurrentCanSelectMultiple => (ComCall(4, this, "int*", &ret_val := 0), ret_val)
CurrentIsSelectionRequired => (ComCall(5, this, "int*", &ret_val := 0), ret_val)
}
class IUIAutomationRangeValuePattern extends Interface {
SetValue(val) => ComCall(3, this, "double", val)
CurrentValue => (ComCall(4, this, "double*", &ret_val := 0), ret_val)
CurrentIsReadOnly => (ComCall(5, this, "int*", &ret_val := 0), ret_val)
CurrentMaximum => (ComCall(6, this, "double*", &ret_val := 0), ret_val)
CurrentMinimum => (ComCall(7, this, "double*", &ret_val := 0), ret_val)
CurrentLargeChange => (ComCall(8, this, "double*", &ret_val := 0), ret_val)
CurrentSmallChange => (ComCall(9, this, "double*", &ret_val := 0), ret_val)
}
class IUIAutomationScrollPattern extends Interface {
Scroll(horizontal_amount, vertical_amount) => ComCall(3, this, "int", horizontal_amount, "int", vertical_amount)
SetScrollPercent(horizontal_percent, vertical_percent) => ComCall(4, this, "double", horizontal_percent, "double", vertical_percent)
CurrentHorizontalScrollPercent => (ComCall(5, this, "double*", &ret_val := 0), ret_val)
CurrentVerticalScrollPercent => (ComCall(6, this, "double*", &ret_val := 0), ret_val)
CurrentHorizontalViewSize => (ComCall(7, this, "double*", &ret_val := 0), ret_val)
CurrentVerticalViewSize => (ComCall(8, this, "double*", &ret_val := 0), ret_val)
CurrentHorizontallyScrollable => (ComCall(9, this, "int*", &ret_val := 0), ret_val)
CurrentVerticallyScrollable => (ComCall(10, this, "int*", &ret_val := 0), ret_val)
}
class IUIAutomationScrollItemPattern extends Interface {
ScrollIntoView() => ComCall(3, this)
}
class IUIAutomationValuePattern extends Interface {
SetValue(val) => ComCall(3, this, "wstr", val)
CurrentValue => (ComCall(4, this, "ptr*", &ret_val := 0), BSTR2STR(ret_val))
CurrentIsReadOnly => (ComCall(5, this, "int*", &ret_val := 0), ret_val)
}
class IUIAutomationGridPattern extends Interface {
GetItem(row, column) => (ComCall(3, this, "int", row, "int", column, "ptr*", &element := 0), IUIAutomationGridItemPattern(element))
CurrentRowCount => (ComCall(4, this, "int*", &ret_val := 0), ret_val)
CurrentColumnCount => (ComCall(5, this, "int*", &ret_val := 0), ret_val)
}
class IUIAutomationGridItemPattern extends Interface {
CurrentContainingGrid => (ComCall(3, this, "ptr*", &ret_val := 0), IUIAutomationElement(ret_val))
CurrentRow => (ComCall(4, this, "int*", &ret_val := 0), ret_val)
CurrentColumn => (ComCall(5, this, "int*", &ret_val := 0), ret_val)
CurrentRowSpan => (ComCall(6, this, "int*", &ret_val := 0), ret_val)
CurrentColumnSpan => (ComCall(7, this, "int*", &ret_val := 0), ret_val)
}
class IUIAutomationTextChildPattern extends Interface {
TextContainer => (ComCall(3, this, "ptr*", &container := 0), IUIAutomationElement(container))
TextRange => (ComCall(4, this, "ptr*", &range := 0), IUIAutomationTextRange(range))
}
class IUIAutomationTextPattern extends Interface {
RangeFromPoint(pt) => (ComCall(3, this, "int64", pt, "ptr*", &range := 0), IUIAutomationTextRange(range))
RangeFromChild(child) => (ComCall(4, this, "ptr", child, "ptr*", &range := 0), IUIAutomationTextRange(range))
GetSelection() => (ComCall(5, this, "ptr*", &ranges := 0), IUIAutomationTextRangeArray(ranges))
GetVisibleRanges() => (ComCall(6, this, "ptr*", &ranges := 0), IUIAutomationTextRangeArray(ranges))
DocumentRange => (ComCall(7, this, "ptr*", &range := 0), IUIAutomationTextRange(range))
SupportedTextSelection => (ComCall(8, this, "int*", &supported_text_selection := 0), supported_text_selection)
RangeFromAnnotation(annotation) => (ComCall(9, this, "ptr" annotation, "ptr*", &range := 0), IUIAutomationTextRange(range))
GetCaretRange() => (ComCall(10, this, "int*", &is_active := 0, "ptr*", &range := 0), IUIAutomationTextRange(range))
}
class IUIAutomationTextRangeArray extends Interface {
Length => (ComCall(3, this, "int*", &length := 0), length)
GetElement(index) => (ComCall(4, this, "int", index, "ptr*", &element := 0), IUIAutomationTextRange(element))
}
class IUIAutomationLegacyIAccessiblePattern extends Interface {
Select(flags_select) => ComCall(3, this, "int", flags_select)
DoDefaultAction() => ComCall(4, this)
SetValue(value) => ComCall(5, this, "wstr", value)
CurrentChildId => (ComCall(6, this, "int*", &ret_val := 0), ret_val)
CurrentName => (ComCall(7, this, "ptr*", &name := 0), BSTR2STR(name))
CurrentValue => (ComCall(8, this, "ptr*", &value := 0), BSTR2STR(value))
CurrentDescription => (ComCall(9, this, "ptr*", &description := 0), BSTR2STR(description))
CurrentRole => (ComCall(10, this, "uint*", &role := 0), role)
CurrentState => (ComCall(11, this, "uint*", &state := 0), state)
CurrentHelp => (ComCall(12, this, "ptr*", &help := 0), BSTR2STR(help))
CurrentKeyboardShortcut => (ComCall(13, this, "ptr*", &keyboard_shortcut := 0), BSTR2STR(keyboard_shortcut))
GetCurrentSelection() => (ComCall(14, this, "ptr*", &selected_children := 0), IUIAutomationElementArray(selected_children))
CurrentDefaultAction => (ComCall(15, this, "ptr*", &default_action := 0), BSTR2STR(default_action))
GetIAccessible() => (ComCall(26, this, "ptr*", &accessible := 0), ComValue(0xd, accessible))
}
class IUIAutomationTextRange extends Interface {
CompareEndpoints(src_end_point, range, target_end_point) => (ComCall(5, this, "int", src_end_point, "ptr", range, "int", target_end_point, "int*", &comp_value := 0), comp_value)
GetAttributeValue(attr) => (ComCall(9, this, "int", attr, "ptr", val := Variant()), val[])
GetText(max_length := -1) => (ComCall(12, this, "int", max_length, "ptr*", &text := 0), BSTR2STR(text))
GetBoundingRectangles() {
ComCall(10, this, "ptr*", &bounding_rects := 0)
rect := ComValue(0x2005, bounding_rects)
if rect.MaxIndex(1) < 3
throw Error("Unsupported property")
return { Left: rect[0], Top: rect[1], Right: rect[2], Bottom: rect[3] }
}
Select() => ComCall(16, this)
}
class IUIAutomationExpandCollapsePattern extends Interface {
Expand() => ComCall(3, this)
Collapse() => ComCall(4, this)
CurrentExpandCollapseState => (ComCall(5, this, "int*", &ret_val := 0), ret_val)
}
class IUIAutomationSelectionItemPattern extends Interface {
Select() => ComCall(3, this)
AddToSelection() => ComCall(4, this)
RemoveFromSelection() => ComCall(5, this)
CurrentIsSelected => (ComCall(6, this, "int*", &ret_val := 0), ret_val)
CurrentSelectionContainer => (ComCall(7, this, "ptr*", &ret_val := 0), IUIAutomationElement(ret_val))
}
class IUIAutomationTextEditPattern extends Interface {
GetActiveComposition() => (ComCall(3, this, "ptr*", &range := 0), IUIAutomationTextRange(range))
GetConversionTarget() => (ComCall(4, this, "ptr*", &range := 0), IUIAutomationTextRange(range))
}
class IUIAutomationPropertyCondition extends Interface {
}
class IUIAutomationCondition extends Interface {
}
class IUIAutomationBoolCondition extends IUIAutomationCondition {
}
class IUIAutomationAndCondition extends IUIAutomationCondition {
}
class IUIAutomationOrCondition extends IUIAutomationCondition {
}
class IUIAutomationNotCondition extends IUIAutomationCondition {
}
class NativeArray {
__New(type, arr) {
static bytes_map := Map("char", 1, "uchar", 1, "short", 2, "ushort", 2, "int", 4, "uint", 4, "ptr", 8, "uptr", 8, "int64", 8, "uint64", 8, "folat", 4, "double", 8)
this.Length := arr.Length
this.BaseType := type
this.BaseSize := bytes_map[type]
this.Buffer := Buffer(this.BaseSize * this.Length)
this.Ptr := this.Buffer.Ptr
this.Size := this.Buffer.Size
if arr[1] is Object {
for v in arr
NumPut("ptr", v.Ptr, this.Buffer, (A_Index - 1) * 8)
} else {
for v in arr
NumPut(type, v, this.Buffer, (A_Index - 1) * this.BaseSize)
}
}
__Item[index] => NumGet(this, index * this.BaseSize, this.BaseType)
__Enum(*) => (&item) => (A_Index <= this.Length ? (item := this[A_Index - 1], true) : false)
}
/*
* HandleAutomationEvent(this, sender, event_id)
* HandleFocusChangedEvent(this, sender)
* HandlePropertyChangedEvent(this, sender, property_id, new_value)
* HandleStructureChangedEvent(this, sender, change_type, runtime_id)
*/
class EventHandler {
__New(fn, iid) {
this.Callback := CallbackCreate(fn, "F")
this.QueryInterfaceCallBack := CallbackCreate(this.__QueryInterface.Bind(, , , iid), "F", 3)
this.AddReleaseCallBack := CallbackCreate(this.__AddRelease, "F")
this.Interface := Buffer(40), this.Ptr := this.Interface.Ptr
NumPut("ptr", this.Interface.Ptr + 8, "ptr", this.QueryInterfaceCallBack, "ptr", this.AddReleaseCallBack, "ptr", this.AddReleaseCallBack, "ptr", this.Callback, this.Interface)
}
__Delete() => this.HasOwnProp("Callback") ? (CallbackFree(this.Callback), CallbackFree(this.QueryInterfaceCallBack), CallbackFree(this.AddReleaseCallBack)) : ""
__QueryInterface(riid, object, iid) {
static IID_IUnknown := "{00000000-0000-0000-C000-000000000046}"
iid_str := StringFromCLSID(riid)
if iid_str = iid || iid_str = IID_IUnknown {
return (NumPut("ptr", this, object), 0)
} else {
return 0x80004002
}
}
__AddRelease() {
}
}
class Interface {
__New(ptr) {
if !this.Ptr := ptr
throw Error("Null pointer Exception", -3)
}
__Delete() => this.Release()
AddRef() => ObjAddRef(this.Ptr)
Release() => this.Ptr ? ObjRelease(this.Ptr) : 0
}
class Variant {
static TypeMap := [, "short", "int", "float", "double", , , "ptr", "ptr", "int", "int", "ptr", "ptr", , , "char", "uchar", "ushort", "uint", "int64", "uint64"]
__New(vt := unset, val := unset) {
this.Buffer := Buffer(24, 0)
this.Ptr := this.Buffer.Ptr
if !IsSet(vt)
return
NumPut("ushort", vt, this.Buffer)
switch vt {
case 8: vt := "ptr", val := DllCall("OleAut32\SysAllocString", "str", val, "ptr")
case 11: vt := "int", val := val ? -1 : 0
default:
if vt & 0x2000 {
vt := vt & 0x00ff
this.SafeArray := ComObjArray(vt, val.Length)
ComObjFlags(this.SafeArray, -1)
for k, v in val
this.SafeArray[k - 1] := ComValue(vt, v)
vt := "ptr", val := this.SafeArray.Ptr
} else {
vt := Variant.TypeMap[vt]
}
}
NumPut(vt, val, this.Buffer, 8)
}
__Delete() => DllCall("OleAut32\VariantClear", "ptr", this)
__Item {
get {
switch vt := this.VarType {
case 0: return
case 8: return (arr := NumGet(this, 8, "ptr")) ? StrGet(arr) : ""
case 9, 13: return (ObjAddRef(arr := NumGet(this, 8, "ptr")), arr)
default:
if vt & 0x2000
return this.HasOwnProp("SafeArray") ? this.SafeArray : (ComObjFlags(sa := ComValue(vt, NumGet(this, 8, "ptr")), -1), sa.Clone())
return NumGet(this, 8, Variant.TypeMap[vt])
}
}
}
Size := 24
VarType => NumGet(this, "ushort")
class P extends Variant {
__New(ptr) {
if !ptr
throw Error("Null Pointer Exception")
this.Ptr := ptr
}
}
}
BSTR2STR(bstr) => (bstr ? (str := StrGet(bstr), DllCall("OleAut32\SysFreeString", "ptr", bstr), str) : "")
CLSIDFromString(str) => (DllCall("ole32\CLSIDFromString", "str", str, "ptr", pClsid := Buffer(16), "HRESULT"), pClsid)
StringFromCLSID(clsid) => (DllCall('ole32\StringFromGUID2', "ptr", clsid, "wstr", str := "{00000000-0000-0000-0000-000000000000}", "int", 39), str)
感谢老哥的拓展
感谢
报错了
版本不一致吗?有comcall()这个函数吗?
V2的标签应该有加上的
V2变化这么大啊, 语法都变了,有没有什么好办法迁移到V2?
没啥捷径,其实也就是一门语言,多写就行,相差也不大,习惯对象语言的话会上手很快
只能用v2版本吗