如何将NSString发送到另一个应用程序的当前焦点的UIElement?

时间:2013-01-13 08:03:24

标签: cocoa accessibility uielement

我有一个没有停靠图标或全局菜单的菜单栏应用程序,它只是一个StatusItem和一个Window。

我已将它连接到激活窗口的热键,在停用窗口后,我可以将焦点发送回先前激活的应用程序。

如何将NSString发送到其他应用程序中的活动textarea,就像用户直接键入它一样?

我认为可以使用accessibility features。我想尽可能避免使用AppleScript。

2 个答案:

答案 0 :(得分:1)

the focused UI element开始,您需要get两件事:

现在,直截了当的方法是获得这两个属性,但这实际上是错误的解决方案。

问题是value属性的值是一个普通字符串。如果元素是富文本视图,您将丢失用户可能具有的任何格式或嵌入对象。那会很糟糕。

因此,获取值的正确方法是获取元素number of characters,构造一个从零开始的范围,以该数字作为其长度,然后get attributed string for that range。如果失败,然后就会获得普通值。

一旦您同时拥有值(作为属性字符串或纯字符串)和所选范围replace the selected text range within the value with the text you want to insert。如果用户未选择任何内容,则范围将是插入点位置的空范围(长度为零),并且替换将实际上是插入。

然后,将元素的值设置为修改后的字符串。 (我只希望将它设置为属性字符串才能正常工作。)

答案 1 :(得分:0)

我最终使用了粘贴板和CGEventCreateKeyboardEvent()来模仿用于粘贴的[cmd+v]键盘快捷方式。

在激活我的窗口之前,我会记录上一个应用程序:

_previousApplication = [[notification userInfo] objectForKey:NSWorkspaceApplicationKey];

在我关闭窗口后,我激活了之前的应用程序:

[_previousApplication activateWithOptions:NSApplicationActivateIgnoringOtherApps];

然后粘贴NSString:

#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);
}

DCPostCommandAndKey(KEY_CODE_v);