2

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

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

如何将 NSString 发送到另一个应用程序中的活动文本区域,就好像用户直接键入它一样?

我认为使用辅助功能可能是可能的。如果可能的话,我想避免使用 AppleScript。

4

2 回答 2

1

焦点 UI 元素中,您需要得到两件事:

现在,直接的方法是只获取这两个属性,但这实际上是错误的解决方案。

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

所以获取值的正确方法是获取元素的字符数,以该数字为长度构造一个从零开始的范围,然后获取范围的属性字符串。如果失败,那么您将获得纯值。

获得值(作为属性字符串或纯字符串)和选定范围后,将值中的选定文本范围替换为要插入的文本。如果用户没有选择任何内容,则范围将是插入点位置处的空范围(长度为零),替换将有效地成为插入。

然后,将元素的值设置为修改后的字符串。(我只能希望将其设置为属性字符串会起作用。)

于 2013-01-13T10:02:15.993 回答
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);
于 2013-02-24T00:39:38.420 回答