There is a tantalising parameter in the ITfInputProcessorProfileMgr::RegisterProfile
function called hklSubstitute
. The description (used to) read “The substitute keyboard layout of this profile. When this profile is active, the keyboard will use this keyboard layout instead of the default keyboard layout. This can be NULL
if your text service doesn’t change the keyboard layout.”
This functionality also surfaces in ITfInputProcessorProfileSubstituteLayout::GetSubstituteKeyboardLayout
and ITfInputProcessorProfiles::SubstituteKeyboardLayout
.
From the minimal description in MSDN, this sounds like a feature that we want to use in Keyman Desktop (allowing us to, for instance, use kbdus.dll
as a base layout for some Keyman keyboard layouts). However, we have been unable to get it to work.
- It seems the parameter type in the documentation is not quite right. This parameter is not a
HKL
that you can obtain fromLoadKeyboardLayout
or some such. Instead it needs to be aKLID
, a keyboard layout ID, such as0x00010409
for US Dvorak. - The base layout is limited to one linked to the language the TIP is being installed for. This means you cannot, for instance, substitute German QWERTZ for a French TIP, even if you wanted to. (And we want to!)
- Despite these restrictions, the
RegisterProfile
function does not check the validity of the parameter and happily tells you that the profile registered OK. - While
GetSubstituteKeyboardLayout
returns the exact value that you registered,ITfInputProcessorProfileMgr::GetProfile
returns0
for thehklSubstitute
member unless you meet the preconditions described above. Furthermore,hklSubstitute
, when available, is not aHKL
but aKLID
. - Finally, even after all this, it seems that the substitute keyboard layout does not apply.
I received some clarification from Microsoft (edited slightly, thank you Vladimir Smirnov):
In fact, the feature is not that generic as you apparently expect. Its whole purpose was to enable smooth deprecation of IMM32 IMEs and their replacement (substitution) with TSF IMEs (aka TIPs). It doesn’t support substituting an arbitrary plain keyboard layout with another layout or IME (let alone of a different language).
The hklSubstitute
is supposed to be a real HKL
, but for IMM32 IMEs it actually matches the IME’s KLID
. There’s old verification code there which looks for a matching KLID
in HKLM for a given hklSubstitute
and ignores the latter if there’s no match. That’s why you get 0
from GetProfile
for your invalid or unsupported hklSubstitute
.
Generic substitution was just never meant to be supported in TSF.
It’s a shame, but we work with what we’ve got. So for Keyman Desktop 9, we wrote a mnemonic layout recompiler that recompiles a Keyman mnemonic layout keyboard, merging it with a given Windows system base layout, at keyboard installation time in Keyman Desktop.