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+V keyboard event and want to interpret it in the context 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 as Windows XP and non-Home editions of Vista.

This suggests that the Home Editions of Vista supports keyboard queries 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 keyboard layout handle from thin air. While it is true that the format keyboard layout handles is documented, that doesn’t mean that you can just make one up and start using it.

It’s like saying, “I know that Contoso uses the email address format Firstname.Lastname@contoso.com, but I just tried to send email to Bob.Smith@contoso.com, and it bounced.”

Does Bob work at Contoso?

“No. Does that matter?”

The customer’s code blindly assumes that the US-English keyboard layout is loaded rather than calling Load­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 created from only from the functions and cannot be assigned a value?”

Um, yeah, it’s right there in the documentation of the hkl parameter to the To­Unicode­Ex function. (Emphasis mine.)

dwhkl [in, optional]

Type: HKL

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

Identical text appears in the documentation of the hkl parameter to the To­Ascii­Ex and Vk­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 happens to be using, US-English is not a preloaded keyboard layout.

0 comments

Discussion is closed.

Feedback usabilla icon