我正在使用辅助功能API来检测某个应用程序何时打开窗口,关闭窗口,何时移动窗口或调整窗口大小,或者进行主要和/或聚焦.但是,客户端应用程序似乎在没有触发Accessibility API通知的情况下将窗口移到前面.
我的应用程序如何检测另一个应用程序何时将窗口置于前面而不使其成为关键?
我希望找到适用于OS X 10.4和10.5的解决方案
更多信息:我现在正在使用这些声明.当用户手动选择窗口将其置于前面时,它们可以正常工作.但是,当应用程序本身将窗口移到前面时,它确实不起作用.
AXObserverAddNotification(observer, element, kAXMainWindowChangedNotification, 0); AXObserverAddNotification(observer, element, kAXFocusedWindowChangedNotification, 0);
Nick Haddad.. 8
我一直无法订阅当前的窗口更改,但您可以询问当前应用程序的可访问性API以及当前应用程序的最前景窗口.
想象一下,您有一个名为CurrentAppData的类,其中包含以下数据:
@interface CurrentAppData : NSObject { NSString* _title; AXUIElementRef _systemWide; AXUIElementRef _app; AXUIElementRef _window; }
查找当前应用程序的代码如下所示:
-(void) updateCurrentApplication { // get the currently active application _app = (AXUIElementRef)[CurrentAppData valueOfExistingAttribute:kAXFocusedApplicationAttribute ofUIElement:_systemWide]; // Get the window that has focus for this application _window = (AXUIElementRef)[CurrentAppData valueOfExistingAttribute:kAXFocusedWindowAttribute ofUIElement:_app]; NSString* appName = [CurrentAppData descriptionOfValue:_window beingVerbose:TRUE]; [self setTitle:appName]; }
在此示例中,_systemWide变量在类init函数中初始化为:_system = AXUIElementCreateSystemWide();
类函数valueOfExistingAttribute如下所示:
// ------------------------------------------------------------------------------- // valueOfExistingAttribute:attribute:element // // Given a uiElement and its attribute, return the value of an accessibility // object's attribute. // ------------------------------------------------------------------------------- + (id)valueOfExistingAttribute:(CFStringRef)attribute ofUIElement:(AXUIElementRef)element { id result = nil; NSArray *attrNames; if (AXUIElementCopyAttributeNames(element, (CFArrayRef *)&attrNames) == kAXErrorSuccess) { if ( [attrNames indexOfObject:(NSString *)attribute] != NSNotFound && AXUIElementCopyAttributeValue(element, attribute, (CFTypeRef *)&result) == kAXErrorSuccess ) { [result autorelease]; } [attrNames release]; } return result; }
上一个函数取自Apple UIElementInspector示例,该示例也是了解Accessibility API的绝佳资源.
我一直无法订阅当前的窗口更改,但您可以询问当前应用程序的可访问性API以及当前应用程序的最前景窗口.
想象一下,您有一个名为CurrentAppData的类,其中包含以下数据:
@interface CurrentAppData : NSObject { NSString* _title; AXUIElementRef _systemWide; AXUIElementRef _app; AXUIElementRef _window; }
查找当前应用程序的代码如下所示:
-(void) updateCurrentApplication { // get the currently active application _app = (AXUIElementRef)[CurrentAppData valueOfExistingAttribute:kAXFocusedApplicationAttribute ofUIElement:_systemWide]; // Get the window that has focus for this application _window = (AXUIElementRef)[CurrentAppData valueOfExistingAttribute:kAXFocusedWindowAttribute ofUIElement:_app]; NSString* appName = [CurrentAppData descriptionOfValue:_window beingVerbose:TRUE]; [self setTitle:appName]; }
在此示例中,_systemWide变量在类init函数中初始化为:_system = AXUIElementCreateSystemWide();
类函数valueOfExistingAttribute如下所示:
// ------------------------------------------------------------------------------- // valueOfExistingAttribute:attribute:element // // Given a uiElement and its attribute, return the value of an accessibility // object's attribute. // ------------------------------------------------------------------------------- + (id)valueOfExistingAttribute:(CFStringRef)attribute ofUIElement:(AXUIElementRef)element { id result = nil; NSArray *attrNames; if (AXUIElementCopyAttributeNames(element, (CFArrayRef *)&attrNames) == kAXErrorSuccess) { if ( [attrNames indexOfObject:(NSString *)attribute] != NSNotFound && AXUIElementCopyAttributeValue(element, attribute, (CFTypeRef *)&result) == kAXErrorSuccess ) { [result autorelease]; } [attrNames release]; } return result; }
上一个函数取自Apple UIElementInspector示例,该示例也是了解Accessibility API的绝佳资源.
在Mac OS X中,应用程序和窗口是完全独立的东西,应用程序包含窗口; 它们与以前的Microsoft Windows不同.您需要检测每个应用程序的激活和停用.
你会通过观察kAXApplicationActivatedNotification
和来做到这一点kAXApplicationDeactivatedNotification
.这些通知的对象是正在激活和停用的应用程序.您还需要检测启动和退出的应用程序; 您可以使用Process Manager或NSWorkspace执行此操作.这两个API都可以为您提供进程ID,您可以使用它来创建AXApplication对象.