-
Notifications
You must be signed in to change notification settings - Fork 0
Links & Notes
This page holds various links which may be of interest to anyone who wants to develop keyboard layouts for Windows and/or considers moving away from MSKLC and/or wants to reuse the installer generated by MSKLC in a customized build process.
I tried to organize them somewhat, but essentially they're just a dump of the list of my currently opened browser tabs, so some of them might be less relevant than others.
- Keyboard Layout Info has information about all Windows layouts, and some extra.
-
MSKLC 1.4 download page. Curiously, while this version was originally released in 2007, Microsoft seems to have updated it silently in 2020, because that's when most installed files are "last edited" and signed (perhaps re-signing them was the only change though).
- If you're curious, the 2007 version of MSKLC can still be downloaded from MajorGeeks
- And the older 1.3 release can be downloaded from Andrzej Wijas' website.
- MSKLC Guide
- Commands and arguments used by MSKLC 1.4 to build the layouts
-
Visual Studio download page has all supported versions of VS, but they're all HUGE and I don't like that at all.
- Although there is a separate download of "Build Tools for Visual Studio" available on the same page. Maybe that one is smaller.
- Stackoverflow thread about avoiding the Visual Studio bloat and downloading just the compiler (spoiler alert: doesn't really seem possible with latest versions of VS).
- A potential workaround mentioned in the thread above.
- Another Stackoverflow thread about avoiding Visual Studio when building drivers (again, even if it is possible, it isn't explained there).
- blindtiger's MiniSDK and MSVC repositories might be of interest (although I'm not sure about their legality). They don't seem to have ARM64 support though.
- Potential alternatives to VS:
- ReactOS Keyboard layouts seem to be built using CMake AND support using non-Microsoft toolchain! ReactOS people also have an incomplete reimplementation of kbd(u)tool in their repository, which should really help wean off the MSKLC distribution (assuming somebody bothers to implement the pieces that are missing in it).
- Igor Levicki's blog post about building keyboard layouts for amd64 explains how MSKLC's kbdutool works/what it does. Should be useful if you want to overcome some MSKLC's limitations in your layout, and/or just build C source files instead of klc ones.
- Davide Beatrici's PR which illustrates one could employ CMake for building layouts as well as how KLI (see below) should be used.
- Roland Kaufmann has been building his Programmer Dvorak layout in a completely custom way since before MSKLC was released. He does use Microsoft's developer kits for building, but his makefile and other infrastructure files can certainly be useful as examples to learn and copy from. As a sidenote, Roland is actually the person who told me how I could override how numeric keypad works outside of MSKLC (which resulted in two extra variations of my layout (the ones with the
fn
suffix)). - Michael Scott Kaplan's blog archive has a lot of internal knowledge about MSKLC (he was its author) and keyboard layouts in Windows in general. Alternative archive on GitHub here.
- My notes on keyboard layouts in ARM64 Windows
- Davide Beatrici's wiki and the K(eyboard)L(ayout)I(nstaller) project. KLI was created to address the problem of MSKLC being abandoned and not supporting ARM64. It's not a replacement for the MSKLC GUI editor or kbdtool though – just an installer for compliled layouts. The wiki has notes and links to official MS documentation about installing and enabling keyboard layouts.
-
WiX Toolset allows building MSI installers with custom UI, custom logic and whatnot. I used its version 3 to "decompile" the MSI installer generated by MSKLC and modify it how I wanted (see the commits in the new-installer branch, this is not in master yet) and rebuilt it anew. Note that the default dialog sets supplied by WiX look quite dated, so I decided not to use them and instead polished the dialogs that MSKLC provides.
- Note that v4 (not yet released) is probabaly what makes more sense to use, since it will support architecture-specific custom action DLLs, which doesn't seem to be the case in v3.
- Translatehouse localization guide's chapter on keyboards which encouraged me to bother with decompilation in the first place. Just following that instruction blidly didn't work for me though.
- Creating WiX Custom Actions (MSKLC uses custom action
KbdMsi.dll
to install and enable keyboard layouts):- Stackoverflow thread with some links. Most links further in this list are from there.
- Steven Bone's blog post series.
- Alex Shevchuk's blog post (it looks like some text formatting was lost along the way though, but the example is available for download at the end of the article).
- Firegiant blog post.
- Another Firegiant blog post (possibly irrelevant in our case though).
- Custom Action return values.
- Another CA example.
- A bunch of MIT-licensed WiX examples (including two Custom Actions) on GitHub.
- A collection of EPL-licensed WiX extensions, including a ton of Custom Actions.
- Creating multilingual installers using WiX (note, it didn't really seem to work for me):
- StackOverflow thread.
- Geektieguy's blog post.
- Firegiant blog post.
- Stock translated strings in WiX (I'm reusing some of them in my MSI dialogs).
- Note that you cannot have multiplatform MSI files.
- Wrapping (bootstrapping) MSI files in an exe (probably not a good idea since x86 executables might not be supported by some installations anymore):
- John Robbins' blog post (references some really old version of WiX; the process doesn't really work with its latest versions).
- StackOverflow thread about showing original MSI dialogs when using the bootstrapper.
- Heiswayi Nrird's blog post.
All keyboard layouts on Windows are registered as subkeys under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\
. When I mention registry subkeys and values below, I'm talking about subkeys of this key and values under those subkeys. Here are examples of registry subkeys for stock layouts:
and here's one for my custom layout:
MSKLC installer adds some extra keys (Custom Language Display Name
, Custom Language Name
and Layout Product Code
). I'm not sure what the purpose of the two Custom *
entries is, but the Layout Product Code
entry seems to be required and used by the (un)installer's CA02
, CA03
and CA04
custom actions, which are passed no custom action data during (un)installation.
As can also be seen in the screenshot, subkey names for custom layouts registered by the KbdMsi
installer custom action start with a000****
and grow upwards in the same fashion the stock ones do (last four characters indicate the language/locale, and the first four must be unique for each layout within that locale).
Layout Id
values for custom layouts start with 00c0
and are increased for each layout. I haven't checked though if this is just the first available id, or some predetermined value. For what it's worth, some stock layouts also have Id's in 00C*
range
Begginning with at least Windows 8, stock Windows keyboard layouts spot additional functionality. Sadly, neither the MSKLC-generated layouts, nor any Microsoft examples or other open-source layouts seem to support them yet (at least I'm not aware of that). I've noticed at least three such new features so far. Below are my findings about them.
This refers to two to four characters, shown in the keyboard switcher/indicator when more than one layout is enabled for a particular language (e.g. DV
, DVR
, DVL
for the three different English Dvorak layouts or LT
, LTI
, LTS
for the three Lithuanian layouts).
I found all of these strings in C:\Windows\System32\en-US\InputSwitch.dll.mui
, so InputSwitch.dll
is the actual library that provides them, but it is not documented and only has two (seemingly generic) exported functions.
These abbreviated names seem directly linked to each layout's Layout Id
value. If I edit the registry and change the Layout Id
of my layout to one of those used by the stock layouts, then my layout will use that stock layout's name and abbreviated name. But it has unwanted side effects: it seems that then I can no longer use the original layout, and the whole setup becomes kind of unstable. Probably not worth it, if can't be done properly.
This string is shown in the keyboard list in language options in the Settings app. Here's a (stolen) screenshot from Win8, but same indicator is also visible in Win 11. I haven't found where these strings are even stored yet:
The on-screen keyboard ships with touch-optimized layouts based on the physical keyboard layouts. It seems that these are implemented in TipRes.dll
(e.g. C:\Windows\WinSxS\amd64_microsoft-windows-tabletpc-inputpanel_31bf3856ad364e35_10.0.22000.65_none_f3a35be8937453f0\TipRes.dll
). The list of mappings from physical layouts to on-screen layouts is an XML structure stored in the KEYBOARDLIST
HTML resource, and works somewhat like this:
- Each layout has an ID, and each Layout ID is mapped to a Group ID. Multiple layout IDs might be mapped to the same Group ID.
- For layouts with registry subkey names which match the
0000****
mask, the ID is that subkey name, but truncated to the last 4 characters (e.g. subkey name00000427
(Lithuanian IBM layout) becomes ID0427
). - For all other layouts, the ID is the value of
Layout Id
string value plusF000
(e.g., the layout registered as00010427
(Lithuanian) has theLayout Id
string value of0027
and thus it's ID isF027
).
- Each Group specifies several Views (typically three, but CJK groups have more) via
View
child elements.
- Each View element has
Type
,Layout
andData
attributes. -
Type
is a string (probably one of several constants, which map to an icon or something like that). -
Layout
is a string which references a different HTML/XML resource within the sameTipRes.dll
file. Each such Layout resource describes how keys are laid out in the on-screen keyboard. -
Data
is also a string which references a different HTML/XML resource within the sameTipRes.dll
file. Each such resource describes what characters each key described inLayout
will input in each relevant shift state, as well as which keys have which pop-up characters (if any).
This kinda makes me wonder why all of this XML-based configuration was embedded in the DLL instead of being stored as plain XML files (with the ability to add new files to the set or even modify existing ones after disabling SFC).
Anyways, like mentioned above, if I install my ltenh layout, it gets a Layout Id
of 00c0
and up. There is no mapping for a layout with an ID of F0C0
in TipRes.dll
, so I suppose that's why my layout only gets the default the on-screen layout (and I just noticed that that default doesn't even spot an AltGr key on Windows 11). Again, changing layout ID and rebooting switches the on-screen keyboard to the desired one, but causes other issues (and the OSK can't be customized!), so I don't think it's worth all that trouble. Until and unless it can be done properly, I think it's better to just let Windows generate the full OSK for those who need it.