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
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
HKLthat you can obtain from
LoadKeyboardLayoutor some such. Instead it needs to be a
KLID, a keyboard layout ID, such as
0x00010409for 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
RegisterProfilefunction does not check the validity of the parameter and happily tells you that the profile registered OK.
GetSubstituteKeyboardLayoutreturns the exact value that you registered,
hklSubstitutemember unless you meet the preconditions described above. Furthermore,
hklSubstitute, when available, is not a
- 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).
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
GetProfile for your invalid or unsupported
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.