2014-09-01 69 views
2

我正在开发适用于Mac OS的应用程序,我想查找当前应用程序的文本光标(光标导航)的位置? 到目前为止,我已经要求它的可访问性权限,我也可以监控keyEvents,但我如何找到闪烁的光标位置?如何查找任何活动应用程序的闪烁光标位置?

(我不是在寻找的鼠标光标的位置,我想text cursor/caret navigation

+0

“闪烁的光标”?你的意思是当你在计算机中输入时,有一个小的垂直线闪烁,以显示你在哪里打字,这个元素有firstResponder(NSTextField f.e.?) – Jasper 2014-09-02 13:43:08

+0

@JasperPol。几乎在任何地方都可以看到打字。 – NSGodMode 2014-09-02 17:57:27

+0

是的,它叫firstResponder – Jasper 2014-09-03 08:00:27

回答

1

你会需要使用辅助功能API来做到这一点。 这是丑陋的丑陋代码,它可能并不总是有效,这取决于这些应用程序视图中的视图层次和可访问性支持程度。 非可可应用程序可能会有问题,只是不工作。 使用WebKit进行渲染的视图也呈现整个html可访问性挑战! :)

我从波什丹Popescu得到这个片断谁使DASH。 请勿直接复制并粘贴此代码。 研究它,看看API文档对每个函数和类型所说的话,并从中慢慢构建一些东西。 了解AX API并使用它们需要很长时间。以通用的方式使用它们需要更长的时间。 它是核心基础风格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以及来自苹果类似的样本代码叫做UIElementInspector

+0

非常感谢!我会研究这个并回到你身边。祝你今天愉快! – NSGodMode 2014-09-06 11:06:00

+0

你可以请解释在哪里可以找到“DHAbbreviationManager cocoaRectFromCarbonScreenRect:” – NSGodMode 2014-09-06 22:01:36

+0

这将只是发件人把所有这些内容的类名称。第二部分是他编写的转换点系统的便利功能。 – uchuugaka 2014-09-07 00:37:02