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, but I just tried to send email to, 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
(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.


Comments are closed.