แปลงรหัสคีย์เสมือนเป็นสตริงยูนิโค้ด

ฉันมีรหัสบางส่วนที่ใช้เพื่อรับรูปแบบแป้นพิมพ์ปัจจุบันและแปลงรหัสคีย์เสมือนเป็นสตริง วิธีนี้ใช้ได้ผลดีในสถานการณ์ส่วนใหญ่ แต่ฉันประสบปัญหากับบางกรณีโดยเฉพาะ สิ่งที่ทำให้สิ่งนี้ชัดเจนคือปุ่มเน้นเสียงที่อยู่ถัดจากปุ่ม 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];
}

person Joshua Weinberg    schedule 24.11.2011    source แหล่งที่มา
comment
คุณไม่ควรตั้งค่า kUCKeyTranslateNoDeadKeysMask แทน kUCKeyTranslateNoDeadKeysBit เนื่องจากอันหลังถูกกำหนดเป็น 0 ในขณะที่อันแรกเป็นมาสก์ที่เปิดใช้งานบิตนั้นจริง ๆ หรือไม่   -  person rdb    schedule 14.03.2014


คำตอบ (1)


คีย์นั้น เป็น คีย์ที่ไม่ทำงาน ดังที่คุณเห็นว่าคุณลองด้วยตัวเองหรือดูที่ Keyboard Viewer ที่ใช้งานรูปแบบภาษาเยอรมันอยู่

บน Mac วิธีป้อนอักขระที่แท้จริงของคีย์ที่ตายแล้วโดยไม่ต้องเขียนด้วยอักขระอื่นคือการกดช่องว่างหลังจากนั้น ลองทำดังนี้: ปิด kUCKeyTranslateNoDeadKeysBit และหาก UCKeyTranslate ตั้งค่าสถานะ dead-key ให้แปลช่องว่างหลังจากนั้น

แก้ไข (เพิ่มโดยผู้ถาม)

สำหรับคนในอนาคต นี่คือโค้ดถาวรพร้อมโซลูชันที่เหมาะสม

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
รหัสนี้ใช้สำหรับการแปลการผูกคีย์ ดังนั้นคีย์นั้นจึงสามารถใช้งานได้นอกการพิมพ์ปกติในบริบทนี้ ฉันกำลังคว้ามันในระดับ HID แต่ฉันต้องการวิธีที่จะแสดงให้ผู้ใช้เห็นว่าคีย์ใดถูกผูกไว้ ฉันจะบอกได้อย่างไรว่าสำหรับเค้าโครง QWERTZ คีย์เสมือนนั้นคือคีย์แคปนั้น - person Joshua Weinberg; 25.11.2011
comment
นี่คือรหัสที่แก้ไขแล้ว ขอบคุณมาก Peter github.com/OpenEmu/OpenEmu/commit/ - person Joshua Weinberg; 25.11.2011
comment
@JoshuaWeinberg: ฉันแก้ไขรหัสที่คุณเพิ่มในคำตอบของฉัน คุณโยนความยาวผิดประเภท - person Peter Hosey; 25.11.2011
comment
หมายเหตุ: ในโพสต์ต้นฉบับ kUCKeyTranslateNoDeadKeysBit ไม่ได้เปิดตั้งแต่แรก เนื่องจากมีการใช้อย่างไม่ถูกต้อง ไม่มีความแตกต่างระหว่างการส่ง kUCKeyTranslateNoDeadKeysBit หรือ 0 เนื่องจากอันแรกถูกกำหนดให้เป็น 0 มาสก์จริงที่มีชุดบิตคือ kUCKeyTranslateNoDeadKeysMask - person rdb; 14.03.2014
comment
สุดยอดไปเลย. ขอบคุณปีเตอร์! - person Terminality; 17.10.2016