2011-11-24 13 views
7

Ho un codice che ho utilizzato per ottenere il layout corrente della tastiera e convertire un codice tasto virtuale in una stringa. Funziona alla grande nella maggior parte delle situazioni, ma ho problemi con alcuni casi specifici. Quello che ha portato alla luce questo è il tasto accento accanto al tasto backspace sulle tastiere tedesche QWERTZ. http://en.wikipedia.org/wiki/File:KB_Germany.svgConverti codice chiave virtuale in stringa unicode

Quella chiave genera il codice VK mi aspetto kVK_ANSI_Equal ma quando si utilizza un layout di tastiera QWERTZ ottengo nessuna descrizione indietro. È finito come una chiave morta perché dovrebbe essere composto con un'altra chiave. C'è un modo per catturare questi casi e fare la conversione corretta?

Il mio codice attuale è sotto.

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

non si dovrebbe impostare kUCKeyTranslateNoDeadKeysMask invece di kUCKeyTranslateNoDeadKeysBit, in quanto quest'ultima è definita come 0, mentre il primo è una maschera con quel po 'in realtà è abilitato? – rdb

risposta

13

Quella chiave è un tasto morto, come si può vedere se si tenta da soli o guardare il Visore tastiera con il layout tedesco attiva.

Sul Mac, il modo di immettere il carattere effettivo di una chiave morta, senza comporlo con un altro carattere, è di premere uno spazio dopo di esso. Quindi prova: Disattiva kUCKeyTranslateNoDeadKeysBit e se UCKeyTranslate imposta lo stato di chiave morta, traduci uno spazio dopo di esso.

EDIT (aggiunto per Richiedente)

solo per le persone future, ecco il codice fisso con la giusta soluzione.

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

Questo codice è per le traduzioni dei collegamenti chiave. Quindi quella chiave è utilizzabile al di fuori della normale digitazione in questo contesto. Lo sto prendendo al livello HID, ma ho bisogno di un modo per mostrare all'utente quale chiave è vincolata. Come faccio a sapere che per un layout QWERTZ, quella chiave virtuale è quella keycap? –

+0

Ecco il codice fisso, grazie mille Peter, https://github.com/OpenEmu/OpenEmu/commit/a59dddfa669ab0e2872f79a6443c45e2a2d87253 –

+0

@JoshuaWeinberg: ho corretto il codice che hai aggiunto alla mia risposta; lanci la lunghezza al tipo sbagliato. –