Как получить глобальные экранные координаты выделенного в данный момент текста через API-интерфейсы специальных возможностей. - PullRequest
13 голосов
/ 01 июля 2011

Мне нужна помощь, чтобы узнать, как приложение «Словарь» показывает следующее всплывающее диалоговое окно для выделенного текста при нажатии клавиш CMD + CTRL + D в любом приложении.Я хочу реализовать такую ​​же функциональность для моего приложения с какао, где мое приложение будет работать в фоновом режиме и отображать предложения по нажатию горячей клавиши для выбранного текста.

Dictionary app hot key suggestion dialog

IЯ уже реализовал захват горячих клавиш, мне просто нужен код, чтобы получить область прямоугольника выделенного текста на экране, чтобы я мог показывать диалог, как приложение словаря.

Спасибо

Ответы [ 2 ]

16 голосов
/ 10 июля 2011

Для этого вы можете использовать специальные 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 голосов
/ 05 июля 2011

Вам нужен сервис . С сервисами ваше приложение даже не должно запускаться или захватывать глобальные горячие клавиши.

Например, функциональностьПриложение словаря, которое вы описали, на самом деле является службой, которую можно увидеть в меню Службы .

Dictionary Service Menu

Руководство по внедрению службы от Apple , вероятно, является лучшиминформация об услугах там.

...