Преобразовать код виртуального ключа в строку Unicode - PullRequest
8 голосов
/ 25 ноября 2011

У меня есть код, который я использовал, чтобы получить текущую раскладку клавиатуры и преобразовать код виртуальной клавиши в строку.Это прекрасно работает в большинстве ситуаций, но у меня возникают проблемы с некоторыми конкретными случаями.Тот, кто это осветил, - это клавиша акцента рядом с клавишей Backspace на немецких клавиатурах 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];
}

1 Ответ

14 голосов
/ 25 ноября 2011

Эта клавиша является мертвой клавишей, как вы можете видеть, если вы попробуете ее самостоятельно или посмотрите на Keyboard Viewer с активным немецким макетом.

На Mac способ ввода действительного символа мертвой клавиши, без добавления его к другому символу, заключается в нажатии пробела после него. Попробуйте: отключите kUCKeyTranslateNoDeadKeysBit, и если UCKeyTranslate устанавливает состояние мертвой клавиши, переведите пробел после него.

РЕДАКТИРОВАТЬ (добавлено asker)

Только для будущих людей, вот фиксированный код с правильным решением.

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