修改 NSEvent 以发送与按下的键不同的键 [英] Modify NSEvent to send a different key than the one that was pressed

查看:16
本文介绍了修改 NSEvent 以发送与按下的键不同的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个用于辅助技术目的的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆