Andreas Jönsson
Andreas Jönsson

Reputation: 21

Setting device identifier using LoadKeyboardLayout()

The problem is this: I must set the user's language to Simplified Chinese and the keyboard to "Chinese (Simplified) - Microsoft Pinyin New Experience Input st".

By setting this combo manually in the Control Panel (Region -> Keyboards and languages) and then running a small test program which calls GetKeyboardLayoutName(), I've found out that the KLID is 00000804 (supposedly). If I remove Chinese from Keyboards and languages in the Control Panel and run this:

HKL hKeyboardLayout = ::LoadKeyboardLayout(_T("00000804"), KLF_ACTIVATE | KLF_SETFORPROCESS);

Then the language is indeed changed to Chinese, but the keyboard settings are wrong. The little "IME box" is missing when typing something.

The MSDN page for LoadKeyboardLayout() says this about the pwszKLID parameter:

The name of the input locale identifier to load. This name is a string composed of the hexadecimal value of the Language Identifier (low word) and a device identifier (high word). For example, U.S. English has a language identifier of 0x0409, so the primary U.S. English layout is named "00000409". Variants of U.S. English layout (such as the Dvorak layout) are named "00010409", "00020409", and so on.

So it appears as if GeyKeyboardLayout() only reports the language identifier (0x0804 for Chinese), but the "device identifier" is missing. How can I find out the device identifier for "Microsoft Pinyin New Experience Input st"?

Upvotes: 1

Views: 1442

Answers (1)

Andreas Jönsson
Andreas Jönsson

Reputation: 21

Found the solution. Apparently in Vista (and onwards) you must use InstallLayoutOrTip() with the correct GUID (not KLID) to install the proper language-keyboard combo. Then you can call LoadKeyboardLayout() to load it.

typedef HRESULT (WINAPI *PTF_INSTALLLAYOUTORTIP)(LPCWSTR psz, DWORD dwFlasg);

// Install.

HMODULE hInputDLL = LoadLibrary(_T("input.dll"));
BOOL bRet = FALSE;

if(hInputDLL == NULL)
{
    // Error
}
else
{
    PTF_INSTALLLAYOUTORTIP pfnInputLayoutOrTip;
    pfnInputLayoutOrTip = (PTF_INSTALLLAYOUTORTIP)GetProcAddress(hInputDLL, "InstallLayoutOrTip");

    if(pfnInputLayoutOrTip)
    {
        bRet = (*pfnInputLayoutOrTip)(_T("0804:{81D4E9C9-1D3B-41BC-9E6C-4B40BF79E35E}{F3BA9077-6C7E-11D4-97FA-0080C882687E}"), 0);
        if(! bRet)
        {
            // Error
        }
    }
    else
    {
        // Error
    }

    FreeLibrary(hInputDLL);
}

// Load.

HKL hKeyboardLayout = ::LoadKeyboardLayout(_T("00000804"), KLF_ACTIVATE | KLF_SETFORPROCESS);

References:

http://msdn.microsoft.com/library/bb847909.aspx

http://www.siao2.com/2007/12/01/6631463.aspx

Upvotes: 1

Related Questions