如何获取键盘名称? 在视觉上区分特定语言的键盘

问题描述

例如,我安装了 2 种语言 - 英语和俄语。俄语有 2 个键盘 - 普通和助记符:

enter image description here

当我运行代码时:

UINT uLayouts;
HKL  *lpList = NULL;
wchar_t szBufLng[512],szBufCtry[512];

uLayouts = GetKeyboardLayoutList(0,NULL);
lpList   = (HKL*)LocalAlloc(LPTR,(uLayouts * sizeof(HKL)));
uLayouts = GetKeyboardLayoutList(uLayouts,lpList);

for(int i = 0; i < uLayouts; ++i)
{
    GetLocaleInfo(MAKELCID(((UINT)lpList[i] & 0xffffffff),SORT_DEFAULT),LOCALE_SISO639LANGNAME,szBufLng,512);
    GetLocaleInfo(MAKELCID(((UINT)lpList[i] & 0xffffffff),LOCALE_SISO3166CTRYNAME,szBufCtry,512);
    wprintf(L"%s-%s,%x\n",(UINT)lpList[i]);
    memset(szBufLng,512);
    memset(szBufCtry,512);
}

if(lpList)
    LocalFree(lpList);

我得到以下结果:

en-US,04090409
ru-RU,04190419
ru-RU,f0330419

我的问题是如何区分助记符? 至少要显示这样的内容

en-US,04190419
rum-RU,f0330419

如何获取键盘名称

这里讨论了同样的问题(没有解决方案): https://forums.codeguru.com/showthread.php?492287-Keyboard-Layout-Name

http://web.archive.org/web/20081025132249/http://blogs.msdn.com/michkap/archive/2004/12/05/275231.aspx

http://web.archive.org/web/20100330193933/http://blogs.msdn.com/michkap/archive/2008/09/29/8968315.aspx

解决方法

我从 Windows 10 中的注册表 (\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts) 导出数据,并基于它创建了一个表。并在 SHLoadIndirectString 的帮助下得到了键盘的本地化名称。

struct LAYOUT_KEYBOARD_INFO {
    LCID layout_id;
    short display_name_id;
    wchar_t default_keyboard_name[64];
};

LAYOUT_KEYBOARD_INFO LAYOUT_KEYBOARDS[] = {
    {0x0401,5084,L"Arabic (101)"},{0x0402,5053,L"Bulgarian (Typewriter)"},{0x0404,5065,L"Chinese (Traditional) - US Keyboard"},{0x0405,5031,L"Czech"},{0x0406,5007,L"Danish"},{0x0407,5011,L"German"},{0x0408,5046,L"Greek"},{0x0409,5000,L"US"},{0x040A,5020,L"Spanish"},{0x040B,5009,L"Finnish"},{0x040C,5010,L"French"},{0x040D,5083,L"Hebrew"},{0x040E,5033,L"Hungarian"},{0x040F,5013,L"Icelandic"},{0x0410,5015,L"Italian"},{0x0411,5061,L"Japanese"},{0x0412,5063,L"Korean"},{0x0413,5008,L"Dutch"},{0x0414,5018,L"Norwegian"},{0x0415,5035,L"Polish (Programmers)"},{0x0416,5003,L"Portuguese (Brazilian ABNT)"},{0x0418,5037,L"Romanian (Legacy)"},{0x0419,5055,L"Russian"},{0x041A,5030,L"Standard"},{0x041B,5039,L"Slovak"},{0x041C,5029,L"Albanian"},{0x041D,5022,L"Swedish"},{0x041E,5079,L"Thai Kedmanee"},{0x041F,5060,L"Turkish Q"},{0x0420,5129,L"Urdu"},{0x0422,5058,L"Ukrainian"},{0x0423,5052,L"Belarusian"},{0x0424,5041,L"Slovenian"},{0x0425,5042,L"Estonian"},{0x0426,5043,L"Latvian"},{0x0427,5045,L"Lithuanian IBM"},{0x0428,5151,L"Tajik"},{0x0429,5124,L"Persian"},{0x042A,5118,L"Vietnamese"},{0x042B,5120,L"Armenian Eastern"},{0x042C,5117,L"Azeri Latin"},{0x042E,5163,L"Sorbian Standard (Legacy)"},{0x042F,5109,L"Macedonian (FYROM)"},{0x0432,5191,L"Setswana"},{0x0437,5119,L"Georgian"},{0x0438,5108,L"Faeroese"},{0x0439,5096,L"Devanagari - INSCRIPT"},{0x043A,5140,L"Maltese 47-Key"},{0x043B,5138,L"Norwegian with Sami"},{0x043F,5113,L"Kazakh"},{0x0440,5128,L"Kyrgyz Cyrillic"},{0x0442,5150,L"Turkmen"},{0x0444,5116,L"Tatar (Legacy)"},{0x0445,5135,L"Bengali"},{0x0446,5101,L"Punjabi"},{0x0447,5097,L"Gujarati"},{0x0448,5100,L"Oriya"},{0x0449,5102,L"Tamil"},{0x044A,5103,L"Telugu"},{0x044B,5098,L"Kannada"},{0x044C,5139,L"Malayalam"},{0x044D,5177,L"Assamese - INSCRIPT"},{0x044E,5104,L"Marathi"},{0x0450,5127,L"Mongolian Cyrillic"},{0x0451,5154,L"Tibetan (PRC)"},{0x0452,5145,L"United Kingdom Extended"},{0x0453,5161,L"Khmer"},{0x0454,5162,L"Lao"},{0x045A,5130,L"Syriac"},{0x045B,5166,L"Sinhala"},{0x045C,5209,L"Cherokee Nation"},{0x0461,5169,L"Nepali"},{0x0463,5159,L"Pashto (Afghanistan)"},{0x0465,5132,L"Divehi Phonetic"},{0x0468,5187,L"Hausa"},{0x046A,5189,L"Yoruba"},{0x046C,5186,L"Sesotho sa Leboa"},{0x046D,5148,L"Bashkir"},{0x046E,5168,L"Luxembourgish"},{0x046F,5170,L"Greenlandic"},{0x0470,5188,L"Igbo"},{0x0474,5231,L"Guarani"},{0x0475,5198,L"Hawaiian"},{0x0480,5165,L"Uyghur (Legacy)"},{0x0481,5146,L"Maori"},{0x0485,5160,L"Sakha"},{0x0488,5190,L"Wolof"},{0x0492,5199,L"Central Kurdish"},{0x0804,5072,L"Chinese (Simplified) - US Keyboard"},{0x0807,5024,L"Swiss German"},{0x0809,5025,L"United Kingdom"},{0x080A,5017,L"Latin American"},{0x080C,5002,L"Belgian French"},{0x0813,5001,L"Belgian (Period)"},{0x0816,5019,L"Portuguese"},{0x081A,5038,L"Serbian (Latin)"},{0x082C,5115,L"Azeri Cyrillic"},{0x083B,5144,L"Swedish with Sami"},{0x0843,5114,L"Uzbek Cyrillic"},{0x0850,5158,L"Mongolian (Mongolian Script)"},{0x085D,5156,L"Inuktitut - Latin"},{0x085F,5229,L"Central Atlas Tamazight"},{0x0C04,5192,L"Chinese (Traditional,Hong Kong S.A.R.) - US Keyboard"},{0x0C0C,5005,L"Canadian French (Legacy)"},{0x0C1A,5057,L"Serbian (Cyrillic)"},{0x0C51,5235,L"Dzongkha"},{0x1004,5193,L"Chinese (Simplified,Singapore) - US Keyboard"},{0x1009,5004,L"Canadian French"},{0x100C,5023,L"Swiss French"},{0x105F,5207,L"Tifinagh (Basic)"},{0x1404,5194,Macao S.A.R.) - US Keyboard"},{0x1809,5014,L"Irish"},{0x201A,5155,L"Bosnian (Cyrillic)"},{0x4009,5196,L"India"},// Added F to "Layout Id"
    {0xF028,5085,L"Arabic (102)"},{0xF004,5054,L"Bulgarian (Latin)"},{0xF005,5032,L"Czech (QWERTY)"},{0xF012,5012,L"German (IBM)"},{0xF016,5048,L"Greek (220)"},{0xF002,5092,L"United States-Dvorak"},{0xF086,5021,L"Spanish Variation"},{0xF006,5034,L"Hungarian 101-key"},{0xF003,5016,L"Italian (142)"},{0xF007,5036,L"Polish (214)"},{0xF010,5126,L"Portuguese (Brazilian ABNT2)"},{0xF0A5,5175,L"Romanian (Standard)"},{0xF008,5056,L"Russian (Typewriter)"},{0xF013,5040,L"Slovak (QWERTY)"},{0xF021,5080,L"Thai Pattachote"},{0xF014,5059,L"Turkish F"},{0xF015,5044,L"Latvian (QWERTY)"},{0xF027,5088,L"Lithuanian"},{0xF025,5121,L"Armenian Western"},{0xF0BD,5234,L"Azerbaijani (Standard)"},{0xF09F,5164,L"Sorbian Extended"},{0xF0A4,5174,L"Macedonian (FYROM) - Standard"},{0xF0AB,5182,L"Georgian (QWERTY)"},{0xF00C,5105,L"Hindi Traditional"},{0xF02B,5141,L"Maltese 48-Key"},{0xF02C,5143,L"Sami Extended Norway"},{0xF0BC,5233,L"Tatar"},{0xF02A,5136,L"Bengali - INSCRIPT (Legacy)"},{0xF0B5,5222,L"Tibetan (PRC) - Updated"},{0xF02F,5200,L"Khmer (NIDA)"},{0xF00E,5131,L"Syriac Phonetic"},{0xF0A0,5167,L"Sinhala - Wij 9"},{0xF037,5201,L"Cherokee Nation Phonetic"},{0xF0A7,5171,L"Inuktitut - Naqittaut"},{0xF00D,5133,L"Divehi Typewriter"},{0xF0AD,5185,L"Uyghur"},{0xF01E,5089,L"Belgian (Comma)"},{0xF02D,5137,L"Finnish with Sami"},{0xF0B2,5225,L"Traditional Mongolian (Standard)"},{0xF030,5249,L"Myanmar (Phonetic order)"},{0xF020,5110,L"Canadian Multilingual Standard"},{0xF036,5208,L"Tifinagh (Full)"},{0xF026,5125,L"Gaelic"},{0xF029,5086,L"Arabic (102) AZERTY"},{0xF0A3,5173,L"Bulgarian (Phonetic)"},{0xF00A,5087,L"Czech Programmers"},{0xF018,5049,L"Greek (319)"},{0xF001,5026,L"United States-International"},{0xF03D,5214,L"Hebrew (Standard)"},{0xF0A6,5176,L"Romanian (Programmers)"},{0xF033,5203,L"Russian - Mnemonic"},{0xF022,5081,L"Thai Kedmanee (non-ShiftLock)"},{0xF0A8,5179,L"Ukrainian (Enhanced)"},{0xF0B1,5224,L"Latvian (Standard)"},{0xF0A1,5172,L"Lithuanian Standard"},{0xF038,5217,L"Armenian Phonetic"},{0xF0AE,5184,L"Sorbian Standard"},{0xF0AC,5181,L"Georgian (Ergonomic)"},{0xF0A9,5178,L"Bengali - INSCRIPT"},{0xF0C8,5246,L"Tamil 99"},{0xF02E,5142,L"Sami Extended Finland-Sweden"},{0xF031,5204,L"New Tai Lue"},{0xF0AA,5180,L"Bulgarian"},{0xF017,5050,L"Greek (220) Latin"},{0xF01A,5027,L"United States-Dvorak for left hand"},{0xF023,5082,L"Thai Pattachote (non-ShiftLock)"},{0xF039,5218,L"Armenian Typewriter"},{0xF03B,5215,L"Georgian Ministry of Education and Science Schools"},{0xF034,5205,L"Tai Le"},{0xF0AF,5195,L"Bulgarian (Phonetic Traditional)"},{0xF011,5051,L"Greek (319) Latin"},{0xF01B,5028,L"United States-Dvorak for right hand"},{0xF03C,5216,L"Georgian (Old Alphabets)"},{0xF032,5206,L"Ogham"},{0xF019,5047,L"Greek Latin"},{0xF00B,5123,L"US English Table for IBM Arabic 238_L"},{0xF03A,5213,L"Persian (Standard)"},{0xF01F,5122,L"Greek Polytonic"},{0xF03E,5210,L"Lisu (Basic)"},{0xF03F,5211,L"Lisu (Standard)"},{0xF040,5212,L"N’Ko"},{0xF041,5219,L"Phags-pa"},{0xF0B3,5220,L"Buginese"},{0xF0B4,5221,L"Gothic"},{0xF0B6,5223,L"Ol Chiki"},{0xF0B7,5226,L"Osmanya"},{0xF0B8,5227,L"Old Italic"},{0xF0B9,5228,L"Sora"},{0xF0BA,5230,L"Javanese"},{0xF0BB,5232,L"Futhark"},{0xF0CB,5250,L"Myanmar (Visual Order)"},{0xF0CC,5251,L"ADLaM"},{0xF0CD,5252,L"Osage"}
};

CString GetLayoutKeyboardDisplayName(DWORD layout,bool fLocalized = true) {
    DWORD layout_id = layout >> 16;
    CString keyboard_name = L"";    
    int number_of_elements = sizeof(LAYOUT_KEYBOARDS)/sizeof(LAYOUT_KEYBOARDS[0]);
    for (int i = 0; i < number_of_elements; i++)
        if (LAYOUT_KEYBOARDS[i].layout_id == layout_id) {
            wchar_t szBuf[512];
            if (fLocalized && SHLoadIndirectString(L"@%SystemRoot%\\system32\\input.dll,-" + IntToStr(LAYOUT_KEYBOARDS[i].display_name_id),szBuf,512,NULL) == S_OK)
                keyboard_name.Format(L"%s",szBuf);
            else
                keyboard_name = LAYOUT_KEYBOARDS[i].default_keyboard_name;
            memset(szBuf,512);
            return keyboard_name;
        }

    keyboard_name.Format(L"%X",layout_id);
    keyboard_name.TrimLeft(L"0");
    return keyboard_name;
}    
//...
wprintf(L"%X,%s\n",(UINT)lpList[i],GetLayoutKeyboardDisplayName((UINT)lpList[i]));