2011-07-01 1 views
10

どのアプリケーションでも、CMD + CTRL + Dを押すと、選択したテキストのポップアップダイアログが次のように表示されます。私は 私のアプリがバックグラウンドで実行され、選択されたテキストのいくつかのホットキーを押す際の提案を表示する私のココアアプリのための同じ種類の機能を実装したい。アクセシビリティAPIを使用して現在選択されているテキストのグローバル画面座標を取得する方法。

Dictionary app hot key suggestion dialog

私はすでにホットキーキャプチャを実装している、私はちょうど画面上で選択したテキストの矩形領域を取得するためのコードを持っている必要がありますので、私は辞書アプリのようなダイアログを表示することができます。あなたが探しているもの

おかげ

+0

あなたのアプリの限界からどのようにポップオーバーが表示されましたか? –

答えて

14

アクセシビリティAPIを使用できます。 [システム環境設定/ユニバーサルアクセス]で[補助デバイスへのアクセスを有効にする]設定が選択されていることを確認します。

次のコードスニペットは、ほとんどのアプリケーションで選択されたテキストの境界線(画面座標)を決定します。残念ながら、MailやSafariではプライベートなアクセシビリティ属性を使用しているため、これは動作しません。おそらくそこでも動作するようにすることは可能ですが、より多くの作業が必要になり、プライベートAPI呼び出しが必要になる可能性があります。

AXUIElementRef systemWideElement = AXUIElementCreateSystemWide(); 
AXUIElementRef focussedElement = NULL; 
AXError error = AXUIElementCopyAttributeValue(systemWideElement, kAXFocusedUIElementAttribute, (CFTypeRef *)&focussedElement); 
if (error != kAXErrorSuccess) { 
    NSLog(@"Could not get focussed element"); 
} else { 
    AXValueRef selectedRangeValue = NULL; 
    AXError getSelectedRangeError = AXUIElementCopyAttributeValue(focussedElement, kAXSelectedTextRangeAttribute, (CFTypeRef *)&selectedRangeValue); 
    if (getSelectedRangeError == kAXErrorSuccess) { 
     CFRange selectedRange; 
     AXValueGetValue(selectedRangeValue, kAXValueCFRangeType, &selectedRange); 
     AXValueRef selectionBoundsValue = NULL; 
     AXError getSelectionBoundsError = AXUIElementCopyParameterizedAttributeValue(focussedElement, kAXBoundsForRangeParameterizedAttribute, selectedRangeValue, (CFTypeRef *)&selectionBoundsValue); 
     CFRelease(selectedRangeValue); 
     if (getSelectionBoundsError == kAXErrorSuccess) { 
      CGRect selectionBounds; 
      AXValueGetValue(selectionBoundsValue, kAXValueCGRectType, &selectionBounds); 
      NSLog(@"Selection bounds: %@", NSStringFromRect(NSRectFromCGRect(selectionBounds))); 
     } else { 
      NSLog(@"Could not get bounds for selected range"); 
     } 
     if (selectionBoundsValue != NULL) CFRelease(selectionBoundsValue); 
    } else { 
     NSLog(@"Could not get selected range"); 
    } 
} 
if (focussedElement != NULL) CFRelease(focussedElement); 
CFRelease(systemWideElement); 
+0

こんにちは、おかげでコードです。私はあなたのコードをチェックし、動作しているようだと私はテキストエディットで選択範囲を取得することができますが、問題は、私はその特定のrect上にポップアップダイアログを表示しようとすると、ポップアップが間違って表示されます。基本的に、そのx位置は正常に動作していますが、y位置は正常ではありません。私に教えてください、画面に対して相対的なxとyの正しい位置を取得するために変換を行う必要がありますか? – AmitSri

+0

座標が垂直に反転します。パネルのフレームを取得するには、 'selectionBounds.origin.y = [[NSScreen mainScreen] frame] .size.height - selectionBounds.origin.y - selectionBounds.sizeのように、y座標を変換する必要があります。 (あなたが1つの画面しか持っていないと仮定して、少し簡略化されています)。 – omz

+0

パーフェクト。私を助けてくれてありがとう。私は、選択矩形のように、同じコードを使用して挿入ポイントの位置を取得できるかどうか疑問に思っています。 – AmitSri

0

サービスです。 サービスでは、アプリケーションを実行していなくても、グローバルホットキーをキャプチャする必要はありません。

たとえば、あなたが説明した辞書アプリの機能はサービスメニューで観察、実際にサービスです。

Dictionary Service Menu

AppleのService Implementation Guideは、おそらくそこのサービスで最高の情報です。

+0

あなたの答えをありがとう。私はサービスについて知っており、既にテキスト選択を取得するために私のアプリで使用されています。しかし、辞書アプリが私のポストに表示されているように、画面上で選択/強調表示された辞書アプリのようなポップアップダイアログを表示する必要があります。私は、サービス代理人のスクリーンに関連して選択領域を取得したのですか?おかげで – AmitSri