15

Accessibility API を使用して、特定のアプリケーションがウィンドウを開いたり、ウィンドウを閉じたり、ウィンドウが移動またはサイズ変更されたり、メインになったり、フォーカスされたりしたことを検出しています。ただし、クライアント アプリは、アクセシビリティ API 通知が発生せずにウィンドウを前面に移動しているようです。

別のアプリケーションがウィンドウを前面に移動したことをアプリケーションがキーにせずに検出するにはどうすればよいですか?

OS X 10.4 および 10.5 で動作するソリューションを見つけたいと思っています。

詳細: 現在、これらのステートメントを使用しています。ユーザーがウィンドウを手動で選択して前面に表示すると、正常に機能します。ただし、アプリ自体がウィンドウを前面に表示している場合は機能しません。

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

4 に答える 4

9

現在のウィンドウの変更をサブスクライブできませんでしたが、現在のアプリケーション、および現在のアプリケーションの最前面ウィンドウについてはアクセシビリティ 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 関数で次のように初期化されます。

クラス関数 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の例から取られたもので、アクセシビリティ API について学習するための優れたリソースでもあります。

于 2009-03-09T02:53:45.770 に答える
5

開発者ドキュメントのiChatStatusFromApplicationの例を見てください。それはまさにあなたが必要とするものです:)

于 2011-02-16T11:17:54.553 に答える
2

NSAccessibilityFocusedUIElementChangedNotificationはどうですか?

于 2009-03-14T23:45:54.513 に答える