Ubah Kode Kunci Virtual menjadi string unicode

Saya memiliki beberapa kode yang saya gunakan untuk mendapatkan tata letak keyboard saat ini dan mengubah kode kunci virtual menjadi string. Ini berfungsi dengan baik di sebagian besar situasi, tetapi saya mengalami masalah dengan beberapa kasus tertentu. Salah satu yang memperjelas hal ini adalah tombol aksen di sebelah tombol spasi mundur pada keyboard QWERTZ Jerman. http://en.wikipedia.org/wiki/File:KB_Germany.svg

Kunci itu menghasilkan kode VK yang saya harapkan kVK_ANSI_Equal tetapi ketika menggunakan tata letak keyboard QWERTZ saya tidak mendapatkan deskripsi apa pun. Ini berakhir sebagai kunci mati karena seharusnya dibuat dengan kunci lain. Apakah ada cara untuk mengetahui kasus ini dan melakukan konversi yang tepat?

Kode saya saat ini ada di bawah.

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

person Joshua Weinberg    schedule 24.11.2011    source sumber
comment
Sebaiknya Anda tidak menyetel kUCKeyTranslateNoDeadKeysMask alih-alih kUCKeyTranslateNoDeadKeysBit, karena kUCKeyTranslateNoDeadKeysBit didefinisikan sebagai 0 sedangkan kUCKeyTranslateNoDeadKeysBit didefinisikan sebagai 0 sedangkan kUCKeyTranslateNoDeadKeysBit adalah topeng dengan bit yang benar-benar diaktifkan?   -  person rdb    schedule 14.03.2014


Jawaban (1)


Kunci tersebut adalah kunci mati, seperti yang dapat Anda lihat jika Anda mencobanya sendiri atau melihat Penampil Keyboard dengan tata letak Jerman yang aktif.

Di Mac, cara memasukkan karakter sebenarnya dari kunci mati, tanpa menyusunnya dengan karakter lain, adalah dengan menekan spasi setelahnya. Jadi cobalah: Matikan kUCKeyTranslateNoDeadKeysBit, dan jika UCKeyTranslate menyetel status kunci mati, terjemahkan spasi setelahnya.

EDIT (ditambahkan oleh penanya)

Hanya untuk orang-orang di masa depan, berikut adalah kode tetap dengan solusi yang tepat.

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];
}
person Peter Hosey    schedule 25.11.2011
comment
Kode ini untuk terjemahan pengikatan kunci. Sehingga kunci tersebut dapat digunakan di luar pengetikan normal dalam konteks ini. Saya mengambilnya di level HID, tapi saya memerlukan cara untuk menunjukkan kepada pengguna kunci apa yang terikat. Bagaimana cara mengetahui bahwa untuk tata letak QWERTZ, kunci virtual itu adalah keycap itu? - person Joshua Weinberg; 25.11.2011
comment
Ini kode tetapnya, terima kasih banyak Peter, github.com/OpenEmu/OpenEmu/commit/ - person Joshua Weinberg; 25.11.2011
comment
@JoshuaWeinberg: Saya mengoreksi kode yang Anda tambahkan ke jawaban saya; Anda memasukkan panjangnya ke tipe yang salah. - person Peter Hosey; 25.11.2011
comment
Catatan: di postingan asli, kUCKeyTranslateNoDeadKeysBit tidak diaktifkan sejak awal, karena digunakan secara tidak benar. Tidak ada perbedaan antara meneruskan kUCKeyTranslateNoDeadKeysBit atau 0 karena yang pertama didefinisikan sebagai 0. Mask sebenarnya dengan kumpulan bit adalah kUCKeyTranslateNoDeadKeysMask. - person rdb; 14.03.2014
comment
Benar-benar luar biasa. Terima kasih Petrus! - person Terminality; 17.10.2016