Can't simulate backspace button on some applic

2019-07-30 10:17发布

问题:

I'm trying to simulate some key presses on Mac OS. This code is supposed to delete one previous character if the 'h' key is pressed (e.g. if user types 'tigh' it will become 'ti') by modifying keyboard events. However it only works with some applications; others totally refuse my events. Is there any problem with this code ?

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    CFMachPortRef      eventTap;
    CGEventMask        eventMask;
    CFRunLoopSourceRef runLoopSource;

    eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));

    eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
                                eventMask, KeyHandler, NULL);
    if (!eventTap) {
        fprintf(stderr, "failed to create event tap\n");
        exit(1);
    }

    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);    
    CGEventTapEnable(eventTap, true);
    CFRunLoopRun();
}

CGEventRef KeyHandler(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
    UniCharCount actualStringLength;
    UniCharCount maxStringLength = 1;    
    UniChar chars[3];

    CGEventKeyboardGetUnicodeString(event, maxStringLength, &actualStringLength, chars);

    if (chars[0] == 'h') {
        chars[0] = '\b';
        CGEventKeyboardSetUnicodeString(event, 1, chars);
        return event;        
    }

    return event;
}

回答1:

Some applications find what is being typed based on the key code from the event (CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode)), rather than the event's UnicodeString.

That is, you will need to update the event's kCGKeyboardEventKeycode value from the 4 supplied by "h" to 51 or (0x33) for Backspace.