2008-12-07 56 views
9

我使用Accessibility API来检测某个应用程序何时打开窗口,关闭窗口,何时移动窗口或调整窗口大小,还是主要和/或重点关注。然而,客户端应用程序似乎将窗口移动到前面,但没有发出可访问性API通知 。我如何使用Cocoa的Accessibility API来检测窗口是否在前面?

我的应用程序如何检测另一个应用程序何时将窗口置于前面而不使其成为关键?

我希望能找到在OS X 10.4和10.5

更多信息有效的解决方案: 我使用这些语句的时刻。当用户手动选择一个窗口将其放在前面时,它们工作正常。但当应用程序本身将窗口放在前面时,它不起作用。

AXObserverAddNotification(observer, element, kAXMainWindowChangedNotification, 0); 
AXObserverAddNotification(observer, element, kAXFocusedWindowChangedNotification, 0); 

回答

7

我一直无法订阅当前窗口的变化,但你可以问无障碍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变量初始化在类初始化函数为: _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; 
} 

先前的功能是从苹果UIElementInspector例子,这也是学习的辅助功能API一个很好的资源拍摄。

5

在Mac OS X中,应用程序和窗口是完全独立的东西,应用程序包含窗口;它们不像以前的Microsoft Windows那样。您需要检测每个应用程序的激活和停用。

您将通过观察kAXApplicationActivatedNotificationkAXApplicationDeactivatedNotification来做到这一点。这些通知的目的是激活和停用应用程序。您还需要检测应用程序启动和退出;您可以使用Process Manager或NSWorkspace执行此操作。这两种API都可以为您提供进程ID,您可以使用它来创建AXApplication对象。

相关问题