Измените NSEvent для отправки другого ключа, кроме того, который был нажат

Я пытаюсь создать крючок для клавиатуры OS X для вспомогательных технологий (т. Е. Не беспокойтесь, а не кейлоггер).

Когда пользователь нажимает клавишу, я хочу предотвратить реальное нажатие клавиши и отправить вместо этого поддельное нажатие (символ по моему выбору).

У меня есть следующий код:

- (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» для отправки другого символа. Благодарю.

Вы не можете сделать это с NSEvent API NSEvent , но вы можете сделать это с помощью CGEventTap . Вы можете создать активное событие и зарегистрировать обратный вызов, который получает CGEventRef и может его модифицировать (при необходимости) и вернуть его для изменения реального streamа событий.


РЕДАКТИРОВАТЬ

Вот простая программа, которая во время работы заменяет каждое «b» нажатие клавиши «v»:

 #import  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 »нажатие клавиши. Я был в замешательстве. Тогда я вспомнил, что Я еще не остановил приложение.)

Я столкнулся с этим ответом, нужно делать то же самое, но только для событий в моем собственном приложении, не являющихся глобальными. Существует гораздо более простое решение, поскольку эта гораздо более простая проблема, которую я здесь отмечаю, полезен для кого-то еще:

  • Я перехватил событие в окне, создав переопределение для sendEvent :. Затем я проверяю ключевые события (KeyUp или KeyDown), а затем просто создаю новое событие, используя почти все данные из предыдущего события, а затем вызываем суперclass classа NSWindow с этим событием.

Кажется, это отлично работает для меня, и мне не пришлось даже модифицировать часть keyCode, но, возможно, это может быть проблемой …

Пример в Swift:

 class KeyInterceptorWindow : NSWindow { override func sendEvent(theEvent: NSEvent) { if theEvent.type == .KeyDown || theEvent.type == .KeyUp { println(theEvent.description) let newEvent = NSEvent.keyEventWithType(theEvent.type, location: theEvent.locationInWindow, modifierFlags: theEvent.modifierFlags, timestamp: theEvent.timestamp, windowNumber: theEvent.windowNumber, context: theEvent.context, characters: "H", charactersIgnoringModifiers: theEvent.charactersIgnoringModifiers!, isARepeat: theEvent.ARepeat, keyCode: theEvent.keyCode) super.sendEvent(newEvent!) } else { super.sendEvent(theEvent) } } 

}

  • Заголовок Swift для Objective-C, не созданный в Xcode 6
  • Как обрабатывать дублируемую символьную ошибку от сторонних библиотек?
  • Звук не работает в iPhone Simulator?
  • Получение списка файлов в каталоге с глобусом
  • создать подclass uibutton
  • Ошибка сервера Bootstrap в Xcode IPHONE
  • Как установить получателей для UIActivityViewController в iOS 6?
  • Как добавить gradleиент к тексту UILabel, но не к фону?
  • Стилизация кнопки отмены в UISearchBar
  • Как я могу получить точное время, например, в миллисекундах в Objective-C?
  • как создать круглую кнопку?
  • Interesting Posts

    Как повернуть метки меток на домене числовой оси в JFreeChart?

    Как отлаживать эпически медленный Wi-Fi, но быстро

    Будут ли реализации malloc возвращать свободную память обратно в систему?

    this.getClass (). getClassLoader (). getResource (“…”) и NullPointerException

    Почему выбирают члены типа Scala с хешем вместо точки?

    Как разработать расширяемое программное обеспечение (архитектура плагина)?

    Сохранение быстрого запуска для Windows 8 в среде двойной загрузки Win / Linux?

    Скопировать полный путь к файлу в Windows XP

    Как преобразовать строку в UTF-8 в C #?

    Удаление символической ссылки папки Ubuntu удаляет содержимое целевой папки, когда выполняется через OSX & Samba

    Класс, соответствующий протоколу как параметр функции в Swift

    Как преобразовать jstring в wchar_t *

    Как предотвратить Windows Explorer от медленного чтения содержимого файла для создания метаданных?

    Как сохранить проанализированный и измененный документ DOM в XML-файле?

    Как разбить строку java на обратную косую черту

    Давайте будем гением компьютера.