修改 NSEvent 以发送与按下的键不同的键 [英] Modify NSEvent to send a different key than the one that was pressed
问题描述
我正在尝试创建一个用于辅助技术目的的 OS X 键盘挂钩(即别担心,不是键盘记录器).
I'm trying to create an OS X keyboard hook for assistive technology purposes (i.e. don't worry, not a keylogger).
当用户按下某个键时,我想阻止真正的按键,并发送一个假按键(我选择的字符).
When a user presses a key, I want to prevent the real keypress and send a fake keypress (character of my choosing) instead.
我有以下代码:
- (void) hookTheKeyboard {
CGEventMask keyboardMask = CGEventMaskBit(kCGEventKeyDown);
id eventHandler = [NSEvent addGlobalMonitorForEventsMatchingMask:keyboardMask handler:^(NSEvent *keyboardEvent) {
NSLog(@"keyDown: %c", [[keyboardEvent characters] characterAtIndex:0]);
//Want to: Stop the keyboard input
//Want to: Send another key input instead
}];
}
对实现其中任何一个目标有帮助吗?基本上修改 NSEvent "keyboardEvent" 以发送不同的字符.谢谢.
Any help accomplishing either of those goals? Basically modifying the NSEvent "keyboardEvent" to send a different character. Thanks.
推荐答案
你不能用 NSEvent
API 做到这一点,但你可以用<代码>CGEventTap.您可以创建一个活动事件点击并注册 一个回调,它接收一个CGEventRef
并且可以修改它(如有必要)并返回它以修改实际的事件流.
You can't do this with the NSEvent
API, but you can do this with a CGEventTap
. You can create an active event tap and register a callback that receives a CGEventRef
and can modify it (if necessary) and return it to modify the actual event stream.
编辑
这是一个简单的程序,它在运行时将每个b"击键替换为v":
Here's a simple program that, while running, replaces every "b" keystroke with a "v":
#import <Cocoa/Cocoa.h>
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
//0x0b is the virtual keycode for "b"
//0x09 is the virtual keycode for "v"
if (CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode) == 0x0B) {
CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, 0x09);
}
return event;
}
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
CFRunLoopSourceRef runLoopSource;
CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, kCGEventMaskForAllEvents, myCGEventCallback, NULL);
if (!eventTap) {
NSLog(@"Couldn't create event tap!");
exit(1);
}
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
CFRunLoopRun();
CFRelease(eventTap);
CFRelease(runLoopSource);
[pool release];
exit(0);
}
(有趣的故事:当我在编辑这篇文章时,我一直试图写替换每个‘b’键击",但它一直以替换每个‘v’键击"的形式出现.我很困惑.然后我记得我还没有停止应用.)
(Funny story: as I was editing this post, I kept on trying to write "replaces every 'b' keystroke", but it kept on coming out as "replaces every 'v' keystroke". I was confused. Then I remembered that I hadn't stopped the app yet.)
这篇关于修改 NSEvent 以发送与按下的键不同的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!