cocoa - 我如何使用 Cocoa 的 Accessibility API 来检测窗口是否置于前面?

标签 cocoa accessibility-api

我使用辅助功能 API 来检测某个应用程序何时打开窗口、关闭窗口、何时移动或调整窗口大小,或者何时成为主窗口和/或聚焦窗口。然而,客户端应用程序似乎将窗口移动到前面,而没有辅助功能 API 通知 被解雇了。

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

我希望找到适用于 OS X 10.4 和 10.5 的解决方案

更多信息: 我现在正在使用这些陈述。当用户手动选择一个窗口并将其置于前面时,它们可以正常工作。但当应用程序本身将窗口置于前面时,它不起作用。

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

最佳答案

我无法订阅当前窗口更改,但您可以询问当前应用程序以及当前应用程序最前台窗口的辅助功能 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 的一个很好的资源。

关于cocoa - 我如何使用 Cocoa 的 Accessibility API 来检测窗口是否置于前面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/347396/

相关文章:

cocoa - 如何在没有 Accessibility API 的情况下在 Mac OS 中获取另一个应用程序窗口的标题、位置和大小?

objective-c - cocoa NSFileManager 文件大小错误

objective-c - Cocoa 按钮在应用程序外部启动

objective-c - 如何在沙盒应用程序中使用辅助功能?

Android 无法使用无障碍服务在少数设备上读取窗口内容

iphone - 是否有 iPhone API 允许我直接在我的应用程序中使用 VoiceOver?

macos - Apple TextEdit,它的工具栏从何而来?

cocoa - 在系统范围内更改 cocoa 单词补全 - 可能吗?

objective-c - 无法更改 NSTextField 文本

java - 通过辅助服务传递数据以查看 – Android