2012-01-17 10 views
3

Objective-CでMac OSXアクセシビリティAPIを使用して、実行中の別のアプリケーションのウィンドウを再配置する方法を知っています。アクセシビリティAPIを使用して別のアプリケーションのすべてのウィンドウを閉じる

もう1つの実行中のアプリケーションの開いているすべてのウィンドウを閉じるには、この同じアクセシビリティAPIを(もう一度、スクリプトブリッジなしで)使用したいと思います。

私はこのAppleScriptのコードと同じことを行う必要があるObjective-Cで書きたいコード:

tell application "TheApplication" 
close every window 
end tell 

私はそれがAppleScriptの中に許可されていますので、これは、可能であることを推測します。

+0

PS。私はAXUIElementCopyAttributeValueと関連する呼び出しを使用してnon-applescriptベースのウィンドウの再配置を行っていましたが、AXUI APIを使用してウィンドウの削除を行う方法を理解することはできません。この質問がNSApplescriptや他の同様のApplescript送信呼び出しなしで実行できるかどうかを確認することが目的です。ありがとう。 – HippoMan

答えて

5

ここに私の解決策だ...

+(void)closeWindowsOfApp:(NSString*)appName { 

    boolean_t result = false; 

    if (appName == nil) { 
     return; 
    } 

    ProcessSerialNumber psn; 
    psn.highLongOfPSN = 0; 
    psn.lowLongOfPSN = kNoProcess; 

    while (GetNextProcess(&psn) == noErr) { 

     pid_t pid = 0; 

     if (GetProcessPID(&psn, &pid) != noErr) { 
      continue; 
     } 

     AXUIElementRef elementRef = AXUIElementCreateApplication(pid); 
     NSString* title = nil; 
     AXUIElementCopyAttributeValue(elementRef, kAXTitleAttribute, (CFTypeRef *)&title); 
     if (title == nil) { 
      continue; 
     } 
     if ([title compare:appName] != NSOrderedSame) { 
      CFRelease(title); 
      continue;  
     } 
     CFRelease(title); 

     CFArrayRef windowArray = nil; 
     AXUIElementCopyAttributeValue(elementRef, kAXWindowsAttribute, (CFTypeRef*)&windowArray); 
     if (windowArray == nil) { 
      CFRelease(elementRef); 
      continue; 
     } 
     CFRelease(elementRef); 

     CFIndex nItems = CFArrayGetCount(windowArray); 
     if (nItems < 1) { 
      CFRelease(windowArray); 
      continue; 
     } 

     for (int i = 0; i < nItems; i++) { 
      AXUIElementRef itemRef = (AXUIElementRef) CFArrayGetValueAtIndex(windowArray, i); 
      AXUIElementRef buttonRef = nil; 
      AXUIElementCopyAttributeValue(itemRef, kAXCloseButtonAttribute, (CFTypeRef*)&buttonRef); 
      AXUIElementPerformAction(buttonRef, kAXPressAction); 
      CFRelease(buttonRef); 
     } 

     CFRelease(windowArray); 
     break; 
    } 
} 
+1

あなたの作品を共有してくれてありがとう! –

+0

閉じるボタンが定義されていない場合、ボタンNSAccessibilityCancelButtonAttributeを押すと便利な場合もあります。また、アクションkAXCancelActionを送信すると役立つことがあります。 –

2

ObjCコード内からApplescriptをコンパイルして実行できるようにするココアクラスNSApplescriptがあります。なぜあなたはASを使いたくないのか、あなたは本当に言わなかった。あなたはすでにあなたが欲しいものを行うスクリプトを持っているので、あなたが今、あなたのプログラムを動作させることができ、それを使用します。イデオロギー純度やパフォーマンスに関する

NSApplescript * as = [[NSApplescript alloc] initWithSource:@"tell application \"TheApplication\"\nclose every window\nend tell"]; 
NSDictionary * errInfo; 
NSAppleEventDescriptor * res = [as executeAndReturnError:&err]; 
if(!res){ 
    // An error occurred. Inspect errInfo and perform necessary actions 
} 

[as release]; 

心配後で。 "任意のスクリプトブリッジのない" 私が言う、私は意味NSApplescriptなしで呼び出します:

+0

どうもありがとうございますが、私はそれをそのようにすることができます。スクリプティングブリッジを使用したくないと言ったとき、私はこれを達成するための非NSApplescriptの方法を探していました。ウィンドウ再配置の方法はAXUIElementCopyAttributeValueの呼び出しが必要ですが、このAXUI APIを使用してウィンドウの削除を行う方法はわかりません。何か案は?ありがとう。 – HippoMan

+0

私はあなたの言ったことを理解していますが、あなたはASを使いたくない理由は何も提示していません。私はその要望に疑問を呈しています。 –

+0

私の望みは、これらの種類のタスクを達成するための非AppleScript関連のフレームワークを書くことです。これは部分的には学習の経験です。私はすでにAXUI APIを使用してウィンドウの位置を変更するための素敵なルーチンを含むパッケージを作成しました。このパッケージにウィンドウの削除を行うために追加したいと思います。 – HippoMan

関連する問題