如何在没有NSTextView的情况下从关键事件中捕获Unicode



我想从应用程序中的任何窗口捕获关键事件,并将它们解释为Unicode。例如,如果用户输入Option-e-e(在默认配置的美式英语键盘上),我希望将其识别为""。

我尝试捕获按键事件并调用-[NSEvent characters]。但是,正如文档中所说,"此方法对于死键返回空字符串,例如Option-e。"如果我输入Option-e-e,则第一个Option-e不显示任何内容,第二个e则显示纯"e"。

是否有一种方法将一系列键码(从-[NSEvent keyCode])组合成Unicode字符?

或者一种接收每个Unicode字符类型的事件的方法(像Java的键类型事件)?

这是一种获取一系列按键事件并获得它们键入的Unicode字符的方法。

基本上,对于收到的每个按键事件调用UCKeyTranslate()。使用它的deadKeyState参数捕获死键并将其传递给后续调用。

的例子:

  • 接收选项e的按键事件。
  • 使用虚拟键代码(对于e)、修饰键状态(对于Option)和存储死键状态的变量调用UCKeyTranslate()
    • UCKeyTranslate()输出空字符串并更新死键状态。
  • 接收e的按键事件。
  • 使用虚拟键代码(e)和保存死键状态的变量调用UCKeyTranlate()
    • UCKeyTranslate()输出""。

示例代码(每次按键事件调用的函数):

/**
 * Returns the Unicode characters that would be typed by a key press.
 *
 * @param event A key press event.
 * @param deadKeyState To capture multi-keystroke characters (e.g. Option-E-E for "é"), pass a reference to the same
 *      variable on consecutive calls to this function. Before the first call, you should initialize the variable to 0.
 * @return One or more Unicode characters.
 */
CFStringRef getCharactersForKeyPress(NSEvent *event, UInt32 *deadKeyState)
{
    // http://stackoverflow.com/questions/12547007/convert-key-code-into-key-equivalent-string
    // http://stackoverflow.com/questions/8263618/convert-virtual-key-code-to-unicode-string
    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
    CFDataRef layoutData = TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
    const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
    CGEventFlags flags = [event modifierFlags];
    UInt32 modifierKeyState = (flags >> 16) & 0xFF;
    const size_t unicodeStringLength = 4;
    UniChar unicodeString[unicodeStringLength];
    UniCharCount realLength;
    UCKeyTranslate(keyboardLayout,
                   [event keyCode],
                   kUCKeyActionDown,
                   modifierKeyState,
                   LMGetKbdType(),
                   0,
                   deadKeyState,
                   unicodeStringLength,
                   &realLength,
                   unicodeString);
    CFRelease(currentKeyboard);
    return CFStringCreateWithCharacters(kCFAllocatorDefault, unicodeString, realLength);
}

子类化您想要捕获" "事件的视图/窗口,并添加这个实例变量

BOOL optionE_Pressed;

然后,用这个

重写keyDown:
-(void) keyDown:(NSEvent *)theEvent {
    NSString *chars = theEvent.charactersIgnoringModifiers;
    unichar aChar = [chars characterAtIndex: 0];
    if (aChar==101 && [theEvent modifierFlags]&NSAlternateKeyMask) {
        optionE_Pressed=YES;
    }
    else if (aChar==101 && optionE_Pressed) {
        NSLog(@"spanish é pressed");
    }
    else {
        optionE_Pressed=NO;
    }
    [super keyDown:theEvent];
}

当用户按住option和e键时,布尔变量"optionE_Pressed"被激活。如果下一个按下的键是e,这意味着他们已经有效地创建了一个西班牙语,那么它将记录"按下的西班牙语"。否则,布尔值将切换回NO。最后的"super"调用允许用户仍然能够正常地键入所有事件

相关内容

  • 没有找到相关文章

最新更新