我有一个没有停靠图标或全局菜单的菜单栏应用程序,它只是一个 StatusItem 和一个窗口。
我已经将它连接到激活窗口的热键,并且在停用窗口后,我可以将焦点发送回先前活动的应用程序。
如何将 NSString 发送到另一个应用程序中的活动文本区域,就好像用户直接键入它一样?
我认为使用辅助功能可能是可能的。如果可能的话,我想避免使用 AppleScript。
我有一个没有停靠图标或全局菜单的菜单栏应用程序,它只是一个 StatusItem 和一个窗口。
我已经将它连接到激活窗口的热键,并且在停用窗口后,我可以将焦点发送回先前活动的应用程序。
如何将 NSString 发送到另一个应用程序中的活动文本区域,就好像用户直接键入它一样?
我认为使用辅助功能可能是可能的。如果可能的话,我想避免使用 AppleScript。
现在,直接的方法是只获取这两个属性,但这实际上是错误的解决方案。
问题是 value 属性的值是一个纯字符串。如果元素是富文本视图,您将丢失用户可能拥有的任何格式或嵌入对象。那会很糟糕。
所以获取值的正确方法是获取元素的字符数,以该数字为长度构造一个从零开始的范围,然后获取该范围的属性字符串。如果失败,那么您将获得纯值。
获得值(作为属性字符串或纯字符串)和选定范围后,将值中的选定文本范围替换为要插入的文本。如果用户没有选择任何内容,则范围将是插入点位置处的空范围(长度为零),替换将有效地成为插入。
然后,将元素的值设置为修改后的字符串。(我只能希望将其设置为属性字符串会起作用。)
我最终使用了粘贴板并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);