gpt4 book ai didi

macos - 如何从 NSView 或 NSWindow 创建 AXUIElementRef?

转载 作者:行者123 更新时间:2023-12-03 16:40:22 26 4
gpt4 key购买 nike

关于 macOS Accessibility API,是否可以创建对应于 NSView 或 NSWindow 的 AXUIElementRef?

在 Carbon 时代,似乎有一种方法可以使用 AXUIElementCreateWithHIObjectAndIdentifier 来执行此操作,但该功能不再可用。

我知道的唯一方法是使用 Accessibility API 递归搜索应用程序的 UI 元素的整个层次结构,以查找与 NSView 或 NSWindow 匹配的元素。但除了是一个繁重的解决方案之外,它甚至不能保证成功,因为可能没有办法仅使用 AXUIElementRef 的可用属性来积极对应 AXUIElementRef 和 Cocoa 对象。

我愿意考虑使用未记录的 API 来帮助实现这一目标。

最佳答案

我找到了在 iOS 中做同样事情的方法。

我知道这不是对你的问题的直接答案,但我会尝试解释我在 iOS 中找到它的方法,并希望你能够在 macOS 中做同样的事情。另外,这可能对其他读者有用......

我首先猜测进程本身正在创建 AXUIElementRef ,因此当我请求具有 AXUIElementRef 的辅助功能属性时,它必须创建它们值,例如 kAXUIElementAttributeChildren .

然后我创建了一个应用程序,并 dlsym'ed _AXUIElementCreateAppElementWithPid(int pid) ,用 [[NSProcessInfo processInfo] processIdentifier] 调用它。我收到root 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 转换为辅助功能元素,并且 UIView* _AXElementForAXUIElementUniqueId(AXUIElementRefGetUniqueID(AXUIElementRef));反方向。

所有符号均来自AXRuntime.framework .

在 Mac 中,您需要链接 ApplicationServices.framework并尝试类似的事情。

希望这有帮助...

关于macos - 如何从 NSView 或 NSWindow 创建 AXUIElementRef?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39906540/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com