我需要帮助才能找到,在任何应用程序上按CMD + CTRL + D时,Dictionary应用程序如何显示以下弹出对话框中的所选文本。我想实施 我的可可应用程序具有相同的功能,我的应用程序将在后台运行,并在所选文本的某些热键按下时显示建议。
我已经实现了热键捕获,我只需要使用代码来获取屏幕上所选文本的矩形区域,这样我就可以像字典应用一样显示对话框。
由于
答案 0 :(得分:15)
您可以使用辅助功能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);
答案 1 :(得分:1)
在这里您需要在Swift中获取@omz答案
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Setting BuildContext to null',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Setting BuildContext to null'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
AsyncClass _asyncClass = AsyncClass();
Duration duration = const Duration(seconds: 5);
void toggleContext(BuildContext context){
Timer.periodic(duration, (_){
print("Setting context to null");
context = null;
});
}
@override
Widget build(BuildContext context) {
toggleContext(context);
_asyncClass.asyncFunc(context);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(),
);
}
}
class AsyncClass{
void asyncFunc(BuildContext context){
const duration = const Duration(seconds: 1);
Timer.periodic(duration, (_){
if(context==null){
print("Context is null");
} else {
print("Context is not null");
}
});
}
}
答案 2 :(得分:0)
您正在寻找的是服务。 使用服务,您的应用甚至不必运行或捕获全局热键。
例如,您描述的词典应用程序的功能实际上是一种服务,可在服务菜单中观察到。
Apple的Service Implementation Guide可能是有关服务的最佳信息。