This project is unmaintained. Feel free to clone and continue development as you see fit.
Custom keyboard layouts are an option to those who want to expand the functionality of their keyboards, whether to type uncommon symbols or to define custom macros.
Many applications for creating custom layouts exist, such as AutoHotKey and Microsoft's Keyboard Layout Creator, with varying capabilities and learning curves. However, they are not capable of remapping more than one keyboard simultaneously.
On the other hand, the software LuaMacros, by Petr Medek, allows for using multiple keyboards in Windows, but does not offer custom layout functionality. It is instead focused on executing macros written in the Lua language.
Windows does not allow more than one layout to be used at once. If more than one keyboard is connected to the computer, they all share certain states (such as CapsLock), and their layout. Additionally, a Windows program (normally) has no way of identifying which keyboard device a keystroke message came from.
Typically, keystrokes can be intercepted using either a Keyboard Hook or the RawInput API, both from the Windows API. Through a Keyboard Hook, it is possible to modify or even block a message generated by a keystroke, but the program cannot extract information about which device originated that message.
The RawInput API, on the other hand, does provide low-level information that includes the device's name but does not allow for manipulating the messages received this way.
This article by Vít Blecha describes how to selectively block keyboard keystrokes based on which device the signal came from, showing that it should be possible for an application to treat keystrokes differently for different keyboards. That, combined with an internal model of a keyboard layout, should enable a user to effectively remap multiple keyboards to simulate using multiple layouts.
This application aims at providing such a solution, to allow the user to create and use multiple keyboard layouts at once in the Windows Operating System.
The user interface for this program is a Layout Editor, written in C# (with WPF), targeting the .NET framework version 4.5. You can use the editor to read and edit, as well as start and stop the execution of the main program.
This is a Visual Studio 2019 project targeting Windows 7 or higher. The core project in Visual C++ interacts with the Windows API to intercept and substitute keystrokes according to a configuration file in XML. The Layout Editor is written in C# WPF, and is used to edit configuration files that contain the layouts for the different registered keyboards; it also writes the XML configuration files and starts and stops the core application.
Buiding the solution should be simple, but be sure to build the C++ projects in Release mode (and 32-bit) before building and running the Layout Editor. There are post-build actions that copy the outputs around.
You can use the sample file at multikeys/XML/Sample.xml, either by calling the background executable with it as parameter, or by using the editor.
The code is essentially feature-complete, but I never got around to properly touching it up (being able to minimize to the system tray or auto-starting with Windows would be nice, for example). If you want to try it out, there's a portable 32-bit installation in the v0.1
folder (you'll need the whole folder, not just the executable).
Be mindful that one of the biggest limitations of Multikeys is that it's only capable of separating different devices by looking at the port.
I also never tested this program on games, which I think would be the use case for many people looking for a program like this.
Features that would be nice to have but I never got around to actually implementing them, roughly in decreasing order of importance
- Add internationalization (all strings already come from a file, but there's only one of it);
- Minimizing to system tray;
- Delays in macro executions (instead of keypresses only), would need an implementation in the core;
- Letting the user record macros instead of picking from a list of keys;
- Include premade layout files for common existing layouts (of different languages);
- Starting with Windows, and also starting minimized;
- Redo the status bar at the bottom because it's too ugly;
I actually like the code in the core better, but there isn't much to do there anymore. And the C code for reading xml is terrible.
I also thought of a better name for quite some time, but gave up. This is fine.