将虚拟键码转换为 unicode 字符串

Posted

技术标签:

【中文标题】将虚拟键码转换为 unicode 字符串【英文标题】:Convert Virtual Key Code to unicode string 【发布时间】:2012-01-06 00:14:20 【问题描述】:

我有一些代码用于获取当前键盘布局并将虚拟键代码转换为字符串。这在大多数情况下都很好用,但我在某些特定情况下遇到了麻烦。使这一点曝光的是德国 QWERTZ 键盘上退格键旁边的重音键。 http://en.wikipedia.org/wiki/File:KB_Germany.svg

该键会生成我期望的 VK 代码kVK_ANSI_Equal,但是当使用 QWERTZ 键盘布局时,我没有得到任何描述。它最终成为死键,因为它应该与另一个键组成。有什么办法可以捕捉到这些情况并进行适当的转换?

我当前的代码如下。

TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);

if(keyboardLayout)

    UInt32 deadKeyState = 0;
    UniCharCount maxStringLength = 255;
    UniCharCount actualStringLength = 0;
    UniChar unicodeString[maxStringLength];

    OSStatus status = UCKeyTranslate(keyboardLayout,
                                     keyCode, kUCKeyActionDown, 0,
                                     LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
                                     &deadKeyState,
                                     maxStringLength,
                                     &actualStringLength, unicodeString);

    if(actualStringLength > 0 && status == noErr)
        return [[NSString stringWithCharacters:unicodeString length:(NSInteger)actualStringLength] uppercaseString];

【问题讨论】:

您是否应该不设置 kUCKeyTranslateNoDeadKeysMask 而不是 kUCKeyTranslateNoDeadKeysBit,因为后者被定义为 0 而前者是实际启用该位的掩码? 【参考方案1】:

那个键一个死键,如果你自己尝试一下,或者查看激活德语布局的键盘查看器,你可以看到。

在 Mac 上,输入死键的实际字符而不与另一个字符组合的方法是在其后按一个空格。所以尝试一下:关闭kUCKeyTranslateNoDeadKeysBit,如果UCKeyTranslate 设置了死键状态,则在其后转换一个空格。

编辑(由提问者添加)

只是为了未来的人,这里是带有正确解决方案的固定代码。

TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);

if(keyboardLayout)

    UInt32 deadKeyState = 0;
    UniCharCount maxStringLength = 255;
    UniCharCount actualStringLength = 0;
    UniChar unicodeString[maxStringLength];

    OSStatus status = UCKeyTranslate(keyboardLayout,
                                     keyCode, kUCKeyActionDown, 0,
                                     LMGetKbdType(), 0,
                                     &deadKeyState,
                                     maxStringLength,
                                     &actualStringLength, unicodeString);

    if (actualStringLength == 0 && deadKeyState)
    
        status = UCKeyTranslate(keyboardLayout,
                                         kVK_Space, kUCKeyActionDown, 0,
                                         LMGetKbdType(), 0,
                                         &deadKeyState,
                                         maxStringLength,
                                         &actualStringLength, unicodeString);   
    
    if(actualStringLength > 0 && status == noErr)
        return [[NSString stringWithCharacters:unicodeString length:(NSUInteger)actualStringLength] uppercaseString];

【讨论】:

此代码用于键绑定翻译。因此,在这种情况下,该键可以在正常输入之外使用。我在 HID 级别抓取它,但我需要一种方法来向用户显示绑定了什么键。对于 QWERTZ 布局,我怎么知道那个虚拟键就是那个键帽? 这里是固定代码,非常感谢彼得,github.com/OpenEmu/OpenEmu/commit/… @JoshuaWeinberg:我更正了您添加到我的答案中的代码;您将长度转换为错误的类型。 注意:在原帖中,kUCKeyTranslateNoDeadKeysBit 没有打开,因为它使用不正确。传递 kUCKeyTranslateNoDeadKeysBit 或 0 没有区别,因为前者定义为 0。设置位的实际掩码是 kUCKeyTranslateNoDeadKeysMask。 太棒了。谢谢彼得!

以上是关于将虚拟键码转换为 unicode 字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何将虚拟键码转换为字符码?

C#如何将虚拟键码转换为字符?

如何将 unicode 字符串转换为其 unicode 转义?

如何将unicode转换为字符串?

将 Unicode 字符串转换为 Python 中的字符串(包含额外符号)

javascript - 如何将unicode字符串转换为ascii [重复]