关于macOS Accessibility API,是否仍要创建与NSView或NSWindow对应的AXUIElementRef?
在Carbon时代,似乎有一种使用AXUIElementCreateWithHIObjectAndIdentifier进行此操作的方法,但是该功能不再可用。
我知道的唯一方法是使用Accessibility API递归搜索应用程序的UI元素的整个层次结构,以查找与NSView或NSWindow匹配的元素。但是除了繁重的解决方案外,它甚至无法保证成功,因为可能没有办法仅通过使用AXUIElementRef的可用属性来肯定地对应AXUIElementRef和Cocoa对象。
我愿意考虑有助于实现此目的的未公开的API。
最佳答案
我找到了在iOS中执行相同操作的方法。
我知道这不是您问题的直接答案,但是我将尽力解释我在iOS中找到它所要做的事情,希望您能够在macOS中做到这一点。另外,这可能对其他读者很有用...
我首先猜测该进程本身正在创建AXUIElementRef
,所以当我请求具有AXUIElementRef
值的可访问性属性(例如kAXUIElementAttributeChildren
)时,它必须创建它们。
然后,我创建了一个应用程序,并对_AXUIElementCreateAppElementWithPid(int pid)
进行了dlsym调用,并使用[[NSProcessInfo processInfo] processIdentifier]
对其进行了调用。
我收到了根AXUIElementRef
,然后将其传递给AXError AXUIElementCopyMultipleAttributeValues(AXUIElementRef element, CFArrayRef attributes, AXCopyMultipleAttributeOptions options, CFArrayRef _Nullable *values)
,并请求kAXUIElementAttributeChildren
,它已起作用(应在主线程上运行)!
我开始将AXUIElementCopyMultipleAttributeValues
调用仔细调试到汇编代码中,该过程非常像这样(这是非常伪的代码,当然是……):
// serialize the arguments for MIG call
if (axUIElementRef->pid == self pid) {
// that's good that we are calling our own process, we can easily keep debugging!
_MIGXAAXUIElementCopyMultipleAttributeValues(serialized arguments) {
// Get the original element from the AXUIElementRef:
UIView* view = _AXElementForAXUIElementUniqueId(id);
[view accessibilityAttributeValue:kAXUIElementAttributeChildren] {
[view _accessibilityUserTestingChildren] {
// since this is the UIApplication element, it just gets the windows:
NSArray*<UIWindow*> winArr = [(UIApplication*)view _accessibilityWindows];
// for each value in result, convert to AX value:
...
AXConvertOutgoingValue(winArr) {
// For each UIView, convert to AXUIElementRef:
AXUIElementRef e = _AXCreateAXUIElementWithElement(winArr[i]);
}
}
}
}
} else {
// Do the same only if we are entitled, and outside our process
}
因此,在iOS中,只需调用
AXUIElementRef _AXCreateAXUIElementWithElement(UIView*);
将UI从UI转换为可访问性元素,然后将UIView* _AXElementForAXUIElementUniqueId(AXUIElementRefGetUniqueID(AXUIElementRef));
沿相反的方向转换。所有符号均来自
AXRuntime.framework
。在Mac中,您需要链接
ApplicationServices.framework
并尝试类似的方法。希望这可以帮助...