2011-11-24 5 views
7

J'ai du code que j'ai utilisé pour obtenir la disposition de clavier actuelle et convertir un code de clé virtuelle en une chaîne. Cela fonctionne très bien dans la plupart des situations, mais j'ai des problèmes avec certains cas spécifiques. Celui qui a mis cela en évidence est la touche d'accentuation à côté de la touche de retour arrière sur les claviers allemands QWERTZ. Cette clé génère le code VK auquel je m'attendrais kVK_ANSI_Equal mais lorsque j'utilise une disposition de clavier QWERTZ, je n'ai pas de description en retour. Il finit comme une clé morte car il est censé être composé avec une autre clé. Y at-il un moyen d'attraper ces cas et faire la conversion appropriée?Convertir le code de clé virtuelle en chaîne unicode

Mon code actuel est ci-dessous.

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

Si vous définissez pas kUCKeyTranslateNoDeadKeysMask au lieu de kUCKeyTranslateNoDeadKeysBit, puisque celui-ci est défini comme 0 alors que le premier est un masque avec ce bit réellement activé? – rdb

Répondre

13

Cette clé est une touche morte, comme vous pouvez le voir si vous essayez vous-même ou de regarder le Visualiseur de clavier avec la mise en page allemande active.

Sur Mac, la manière d'entrer le caractère réel d'une touche morte, sans la composer avec un autre caractère, consiste à appuyer sur un espace après celle-ci. Alors essayez ceci: Eteignez kUCKeyTranslateNoDeadKeysBit, et si UCKeyTranslate définit l'état de touche morte, traduisez un espace après celui-ci.

EDIT (ajouté par asker)

seulement pour les personnes à venir, voici le code fixe avec la bonne solution.

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]; 
} 
+0

Ce code est destiné aux traductions de liaison de clé. Donc cette clé est utilisable en dehors de la frappe normale dans ce contexte. Je l'attrape au niveau HID, mais j'ai besoin d'un moyen de montrer à l'utilisateur quelle touche est liée. Comment puis-je dire que pour une mise en page QWERTZ, cette clé virtuelle est ce keycap? –

+0

Voici le code fixe, merci beaucoup Peter, https://github.com/OpenEmu/OpenEmu/commit/a59dddfa669ab0e2872f79a6443c45e2a2d87253 –

+0

@JoshuaWeinberg: J'ai corrigé le code que vous avez ajouté à ma réponse; vous jetez la longueur au mauvais type. –

Questions connexes