【发布时间】:2011-09-14 20:36:46
【问题描述】:
我正在尝试修补 an application 以使用辅助功能 API 调整窗口大小。
我需要维护一个包含以前窗口大小的字典。密钥需要识别当前活动的窗口。目前,按下热键后通过NSAccessibilityFocusedWindowAttribute 检索此活动窗口。
但是,每次调用该方法,返回的标识窗口的AXUIElementRef都不一样!这当然意味着我不能将它用作字典键 - 字典不会找到相应的条目。
下面的代码重现了这个问题:
-(IBAction)testWindowIdentification:(id)sender{
AXUIElementRef focusedApp;
AXUIElementRef focusedWindow;
AXUIElementCopyAttributeValue(_systemWideElement,
(CFStringRef) kAXFocusedApplicationAttribute,
(CFTypeRef*) &focusedApp);
AXUIElementCopyAttributeValue((AXUIElementRef) focusedApp,
(CFStringRef) NSAccessibilityFocusedWindowAttribute,
(CFTypeRef*) &focusedWindow);
CFShow(focusedWindow);
}
_systemWideElement 已在 init 方法中使用对 AXUIElementCreateSystemWide() 的调用进行初始化。
CFShow 语句在每次调用方法时清楚地显示不同的 ID(即使同一个窗口处于活动状态),这对我来说没用:
<AXUIElement 0x47e850> {pid=42463}
<AXUIElement 0x47e890> {pid=42463}
<AXUIElement 0x47e2c0> {pid=42463}
…
documentation on AXUIElement 没有显示检索 UI 元素唯一属性的方法,that of the NSAccessibility protocol 也没有。
唯一的 PID 对我来说不够,因为一个进程可以有多个窗口。
如何在 Cocoa 中检索活动窗口的一些唯一标识符?
(顺便说一下,真正的代码是检查上述调用中的返回码;没有错误,调用成功。)
【问题讨论】:
-
@JeremyBanks 最初的回答者在这里有正确的想法。一旦你确定了焦点窗口,你确实可以使用 Quartz 来获得一个
CGWindowID,如果this answer 是可信的。这应该为您提供您希望的唯一窗口标识符,您可以在当前应用程序的上下文中不受惩罚地传递。如果您想要一个更连贯和完整的版本作为实际答案,请告诉我。 -
@MrGomez 当然,这样的答案会很棒。 :)
-
@JeremyBanks 会的。我今天有点超负荷,但我会在今晚晚些时候(太平洋标准时间)的某个时间尝试回答这个问题。 :)
-
@MrGomez 当然,不要着急,除非你担心其他人可能会抓住它。 :)
-
@JeremyBanks 赏金期已经结束,你想现在奖励它吗?否则它将在 22 小时内过期,并且将浪费一半的声誉。
标签: objective-c macos cocoa