Keyboard layouts aren't like Beetlejuice – they won't appear just because you say their name

Raymond Chen

A customer reported a bug in Windows Vista Home Editions:

We are handling a Ctrl+Vkeyboard event and want to interpret it in thecontext of a US-English keyboard.

// This keyState represents no keys pressed except for Ctrl
BYTE keyState[256] = {0};
keyState[VK_CONTROL] = 0x80;
// This is the handle for the US-English keyboard
HKL hkl = (HKL) 0x04090409;
// output variables
wchar_t outChar[2];
WORD outWord;
ToUnicodeEx('V', 47, keyState, outChar, 2, 0, hkl);
ToAsciiEx('V', 47, keyState, &outWord, 0, hkl);
VkKeyScanEx('V', hkl);

On Windows XP and versions of Windows Vista other than Home editions,the three calls all succeed, whereas on Windows Vista Home Editions,the calls fail.On the other hand, if instead of using the US-English keyboard,we use the current keyboard layout:

HKL hkl = GetKeyboardLayout(GetCurrentThreadId());

then Windows Vista Home Editions behave the same asWindows XP and non-Home editions of Vista.

This suggests that the Home Editions of Vista supports keyboardqueries only for the currently active keyboard layout,which renders useless the last parameter to those three functions.

Notice how the customer’s sample code just synthesizes a keyboardlayout handle from thin air.While it is true thatthe format keyboard layout handles is documented,that doesn’t mean that you can just make one upand start using it.

It’s like saying,“I know that Contoso uses the email address, but I just tried to send email, and it bounced.”

Does Bob work at Contoso?

“No. Does that matter?”

The customer’s code blindly assumes that the US-English keyboard layoutis loaded rather than callingLoad­Keyboard­Layout to actually load it.As a result, if the keyboard layout is not loaded,the call will fail because you passed an invalid keyboard layout handle.

The customer liaison asked,“Is this documented somewhere that the HKL has to be createdfrom only from the functions and cannot be assigned a value?”

Um, yeah, it’s right therein the documentationof the hkl parameter to theTo­Unicode­Exfunction.(Emphasis mine.)

dwhkl [in, optional]

Type: HKL

The input locale identifier used to translate the specified code.This parameter can be any input locale identifierpreviously returned by the Load­Keyboard­Layout function.

Identical text appears in the documentation of thehkl parameter to theTo­Ascii­Ex andVk­Key­Scan­Ex functions as well.

The difference observed on Windows Vista Home Editions, then,is that on those systems, in the configurations the customer happensto be using, US-English is not a preloaded keyboard layout.