【问题标题】:How to insert text at cursor position of another application on Mac OSX Application (like OSK)?如何在 Mac OSX 应用程序(如 OSK)上另一个应用程序的光标位置插入文本?
【发布时间】:2013-04-22 18:27:45
【问题描述】:

我正在尝试创建一个 OSX 应用程序,它是屏幕键盘的复制品。是否可以在另一个活动应用程序的光标位置插入一些文本?提前致谢!

【问题讨论】:

  • 仅供参考,以防万一:答案(无论细节如何,对不起,我不知道他们的意思)是合格是的 - 例如,辅助软件就是这样作品。 然而在沙盒下,因此在 App Store 中,一般的答案肯定是否定的 - 输入另一个应用程序可能是一个严重的安全问题。当然,如果您的应用程序不在沙箱中,那么它的限制就无关紧要了。
  • @CRD 沙盒是什么意思。你的意思是如果我将应用程序提交到应用程序商店它不会工作?但是作为一个苹果开发者,我可以在我的系统中运行这个应用程序吗?能否请您详细说明..谢谢。
  • App Sandbox 是一个安全系统,它限制应用程序可以做什么——它可以访问哪些文件,是否可以建立网络连接等等。所有 iOS 应用程序都是沙盒化的,对于 OS X 来说是可选的。但是,所有要在 Mac App Store 中销售的应用程序都必须经过沙盒处理。在 Apple 文档中查找 App Sandbox 以了解详细信息。

标签: macos cocoa on-screen-keyboard


【解决方案1】:

不确定这是否有帮助,但在 Applescript 中您可以执行类似的操作

tell application "System Events"
    keystroke "Stuff here"
end tell

所以也许你可以尝试在可可中使用NSApplescriptNSTask 调用它并运行

osascript -e 'tell application "System Events" to keystroke "Stuff here"'

【讨论】:

  • 这在 Mac App Store 上也不起作用,所以你最好澄清一下。
【解决方案2】:

这是可能的。辅助功能可以更改其他应用程序的内容,但您的应用程序不能被沙盒化,因此无法通过 AppStore 使用。

CFTypeRef focusedUI;
AXUIElementCopyAttributeValue(AXUIElementCreateSystemWide(), kAXFocusedUIElementAttribute, &focusedUI);

if (focusedUI) {
    CFTypeRef textValue, textRange;
    // get text content and range
    AXUIElementCopyAttributeValue(focusedUI, kAXValueAttribute, &textValue);
    AXUIElementCopyAttributeValue(focusedUI, kAXSelectedTextRangeAttribute, &textRange);

    NSRange range;
    AXValueGetValue(textRange, kAXValueCFRangeType, &range);
    // replace current range with new text
    NSString *newTextValue = [(__bridge NSString *)textValue stringByReplacingCharactersInRange:range withString:newText];
    AXUIElementSetAttributeValue(focusedUI, kAXValueAttribute, (__bridge CFStringRef)newTextValue);
    // set cursor to correct position
    range.length = 0;
    range.location += text.length;
    AXValueRef valueRef = AXValueCreate(kAXValueCFRangeType, (const void *)&range);
    AXUIElementSetAttributeValue(focusedUI, kAXSelectedTextRangeAttribute, valueRef);

    CFRelease(textValue);
    CFRelease(textRange);
    CFRelease(focusedUI);
}

此代码不检查错误并假设焦点元素是文本区域。

【讨论】:

  • 这种方式不适用于基于 Web 的应用程序 :( 例如:Safari、Slack (Electron) 或 Skype (React-Native)
  • 我在这里结束了,因为我已经达到了相同的解决方案,但是在我粘贴下一个和我移动插入符号之间,插入符号闪烁,这使得我的应用程序的用户体验很漂亮坏的。遗憾的是没有找到任何解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多