【问题标题】:How to paste text from one app to another using Cocoa?如何使用 Cocoa 将文本从一个应用程序粘贴到另一个应用程序?
【发布时间】:2011-02-10 11:11:24
【问题描述】:

我在 Apple 文档中阅读了有关 NSPasteBoard 的信息,以及它如何允许应用程序写入 PasteBoard 并允许其他应用程序读取该文本并使用它。

有人能告诉我如何将来自 am 应用程序(位于状态栏中)的文本粘贴到另一个应用程序内的 NSTextField 中。

我正在尝试做的事情类似于SnippetSnippetsApp 所做的事情。

如果我完全愚蠢并且错过了 Apple Docs 中的明显内容,请您指出正确的路径:)

谢谢!

【问题讨论】:

    标签: cocoa macos copy paste nspasteboard


    【解决方案1】:

    谁能告诉我如何将文本从应用程序(位于状态栏中)粘贴到另一个应用程序内的 NSTextField 中。

    粘贴是在接收应用程序中发生的。写入粘贴板就是复制。

    此外,您不能假设用户想要粘贴到 NSTextField 中。它可能是 NSTextView,或 WebView 中的 textarea,或 Carbon EditText 或 MLTE 控件,或其他一些文本编辑器,例如 Qt 或 wxWidgets 文本编辑器。他们甚至可能正在使用带有列表视图的应用程序,让他们可以将文本直接粘贴到其中。

    因此,没有编程方式可以直接告诉应用程序“这里有一些文本 — 请粘贴”。您必须将其复制到通用粘贴板,然后伪造一个通常会导致最前面的应用程序粘贴的事件。 Charlie 对 ⌘V 的建议是一种方式,虽然很棘手; Dvorak 布局将 V 放在另一个键上,而“Dvorak QWERTY ⌘”布局将 V-with-⌘(相对于 V-without-⌘)放在与 QWERTY 的 V 相同的键上。

    要伪造 ⌘V 事件,请查看 CGEventTap。您需要使用the CGEventCreateKeyboardEvent function 来创建事件本身,并且由于该函数需要一个键码,因此您需要为 ⌘V 组合的 V 部分查找正确的键码,这将需要通过Text Input Source ServicesKeyboard Layout Services,取决于布局。

    此时您可能会考虑使用辅助功能在“编辑”菜单中找到“粘贴”菜单项并向其发送 AXPress 消息,但“粘贴”和“编辑”只是这些概念的英文单词;如果您这样做,您的应用程序将无法以任何其他语言运行。您可以按顺序(第三个菜单,第六个菜单项),但是您的应用程序将无法在没有文件菜单、没有重做菜单项或两个撤消菜单项 (Photoshop) 的应用程序中运行。打造一个⌘V事件真的是要走的路。

    【讨论】:

    • CGEventSourceRef 在我对我的应用程序进行沙盒处理时不起作用。有什么办法可以解决这个问题?
    • @iPhoneDv:你应该问一个单独的问题,提供更多关于你在做什么和遇到什么问题的信息。
    • 这是 KeyboardLayoutServices 文档的完整链接:developer.apple.com/legacy/library/documentation/Carbon/…(当然,如果用户禁用或更改了粘贴的键盘快捷键,这不会仍然失败吗?)
    • 所有旧链接现在都已断开。是否有任何新的 Cocoa API 可以在最前端的应用程序上实现这些粘贴?
    【解决方案2】:

    以下是发布 ⌘+key 事件的一些工作代码(假设已知键码):

    // some common keycodes
    #define KEY_CODE_x ((CGKeyCode)7)
    #define KEY_CODE_c ((CGKeyCode)8)
    #define KEY_CODE_v ((CGKeyCode)9)
    
    void DCPostCommandAndKey(CGKeyCode key)
    {
        CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
    
        CGEventRef keyDown = CGEventCreateKeyboardEvent(source, key, TRUE);
        CGEventSetFlags(keyDown, kCGEventFlagMaskCommand);
        CGEventRef keyUp = CGEventCreateKeyboardEvent(source, key, FALSE);
    
        CGEventPost(kCGAnnotatedSessionEventTap, keyDown);
        CGEventPost(kCGAnnotatedSessionEventTap, keyUp);
    
        CFRelease(keyUp);
        CFRelease(keyDown);
        CFRelease(source);  
    }
    

    【讨论】:

    • 应用商店中有一些应用实际上可以通过点击表格中的项目将数据粘贴到另一个应用。想知道他们是怎么做到的..
    • @cocoa coder 他们可能没有被沙盒化。今年 7 月之前在商店中的应用程序可以保持未沙盒状态。
    【解决方案3】:

    通常唯一的方法是将其写入 NSPasteboard,然后切换到另一个应用程序并使用一些 Carbon 功能按“Command-V”...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 2015-11-05
      • 2016-02-03
      • 2021-04-28
      • 1970-01-01
      相关资源
      最近更新 更多