将虚拟密钥代码转换为unicode字符串

时间:2011-11-24 23:59:18

标签: macos cocoa localization keyboard macos-carbon

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

该密钥生成我期望kVK_ANSI_Equal的VK代码,但在使用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];
}

1 个答案:

答案 0 :(得分:14)

该键 是一个死键,您可以看到自己是否尝试过,或者看看德语布局处于活动状态的键盘查看器。

在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];
}