7

我需要将组合键 ^⌘C 发送到带有捆绑标识符的后台应用程序com.company.app。然后,组合键应激活该应用程序中的菜单项。

不幸的是,我不知道该怎么做。一些研究指出我使用 NSEvent 和 CGEvent API CGEventPostToPSN(),但我无法让它正常工作,因为我不知道如何设置组合键。CGEventPost()似乎不适用于我创建的事件,即使所需的应用程序是活动的。

这是我最终想出的代码,但这不起作用:

CGWindowID windowNumber;
NSEvent *event = [NSEvent keyEventWithType:NSKeyUp
                                  location:NSZeroPoint
                             modifierFlags:(NSControlKeyMask | NSCommandKeyMask)
                                 timestamp:[[NSProcessInfo processInfo] systemUptime]
                              windowNumber:windowNumber
                                   context:[NSGraphicsContext currentContext]
                                characters:@"c"
               charactersIgnoringModifiers:@"c"
                                 isARepeat:NO
                                   keyCode:8];
CGEventRef eventRef = [event CGEvent];

我现在应该怎么处理那个事件?为什么没有NSEvent等价物CGEventPost()?有没有比发布事件更简单的方法来激活该菜单项?我可以轻松获得 的实例NSRunningApplication,但没有合适的 API 来完成我的任务。

更新: 我得到了它的工作:

- (void) postFakedKeyboardEventForCopyScreenToPasteboardToPSN:(ProcessSerialNumber)psn {
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
    CGEventRef keyDownEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, true);
    CGEventSetFlags(keyDownEvent, (kCGEventFlagMaskControl | kCGEventFlagMaskCommand));
    CGEventRef keyUpEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, false);
    CGEventSetFlags(keyUpEvent, (kCGEventFlagMaskControl | kCGEventFlagMaskCommand));
    CFRelease(source);

    CGEventPostToPSN(&psn, keyDownEvent);
    CFRelease(keyDownEvent);
    CGEventPostToPSN(&psn, keyUpEvent);
    CFRelease(keyUpEvent);
}

...

OSStatus err = noErr;
ProcessSerialNumber psn;
err = GetProcessForPID([simulator processIdentifier], &psn);
if (err == noErr)
    [self postFakedKeyboardEventForCopyScreenToPasteboardToPSN:psn];
4

1 回答 1

1

几点注意事项:

  1. 也发送一个 keyDown 事件,而不仅仅是 keyUp。这样,它将更像是一个真正的按键。

  2. 您需要使用该 CGEvent 调用 CGEventPostToPSN,或者至少需要一些发布事件的调用。

  3. 您是否尝试过调用 CGPostKeyboardEvent() 代替?
于 2011-09-15T15:12:44.893 回答