您将需要使用辅助功能 API 来执行此操作。
这是很多丑陋的代码,并且可能并不总是有效,具体取决于这些应用程序视图中的视图层次结构和可访问性支持程度。
非 Cocoa 应用程序可能会出现问题并且无法运行。
使用 WebKit 进行渲染的视图也带来了整个 html 可访问性的挑战! :)
我从 Dash 的制作者 Bogdan Popescu 那里得到了这个片段。
不要直接复制并粘贴此代码。
研究它,查看 API 文档对每个函数和类型的说明,并从中慢慢构建一些东西。
了解 AX API 并使用它们需要花费大量时间。以通用方式很好地使用它们需要更长的时间。
它是 Core Foundation 风格的 C,与您可能习惯的直接 Cocoa Objective-C 有很大不同。
CFTypeRef system = nil;
system = AXUIElementCreateSystemWide();
CFTypeRef application = nil;
CFTypeRef focusedElement = nil;
CFRange cfrange;
AXValueRef rangeValue = nil;
// Find the currently focused application
if(AXUIElementCopyAttributeValue(system, kAXFocusedApplicationAttribute, &application) == kAXErrorSuccess)
{
// Find the currently focused UI Element
if(AXUIElementCopyAttributeValue(application, kAXFocusedUIElementAttribute, &focusedElement) == kAXErrorSuccess)
{
// Get the range attribute of the selected text (i.e. the cursor position)
if(AXUIElementCopyAttributeValue(focusedElement, kAXSelectedTextRangeAttribute, (CFTypeRef *)&rangeValue) == kAXErrorSuccess)
{
// Get the actual range from the range attribute
if(AXValueGetValue(rangeValue, kAXValueCFRangeType, (void *)&cfrange))
{
CFTypeRef bounds = nil;
textRect = NSZeroRect;
if(AXUIElementCopyParameterizedAttributeValue(focusedElement, kAXBoundsForRangeParameterizedAttribute, rangeValue, (CFTypeRef *)&bounds) == kAXErrorSuccess)
{
CGRect screenRect;
AXValueGetValue(bounds, kAXValueCGRectType, &screenRect);
if(bounds)
{
textRect = [DHAbbreviationManager cocoaRectFromCarbonScreenRect:screenRect];
CFRelease(bounds);
}
}
}
if(rangeValue)
{
CFRelease(rangeValue);
}
}
}
if(focusedElement)
{
CFRelease(focusedElement);
}
}
if(application)
{
CFRelease(application);
}
if(system)
{
CFRelease(system);
}
将 AX 点从 Carbon 转换为 Cocoa Screen 点。
+ (NSPoint)cocoaScreenPointFromCarbonScreenPoint:(NSPoint)carbonPoint
{
return NSMakePoint(carbonPoint.x, [[[NSScreen screens] objectAtIndex:0] frame].size.height - carbonPoint.y);
}
研究这些位。
您还想深入研究辅助功能检查器应用程序随 Xcode 一起提供,以及来自 Apple 的类似示例代码,称为UI元素检查器