Keyboard layouts aren't like Beetlejuice – they won't appear just because you say their name
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 formatFirstname.Lastname@contoso.com, but I just tried to send email toBob.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 layoutis loaded rather than callingLoadKeyboardLayout
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 theToUnicodeEx
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 identifierpreviously returned by the LoadKeyboardLayout function.
Identical text appears in the documentation of thehkl
parameter to theToAsciiEx
andVkKeyScanEx
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.
0 comments