HalfKeyboard software emulation
The HalfKeyboard is a one-handed keyboard, made and sold by Matias Corporation. Basically you can access a key from the "missing" half, by combining the corresponding mirrored key in the left half with the space bar.
I wrote a windows software emulator for the HalfKeyboard, that gives you a similar functionality on a regular keyboard.
Update (April 22nd, 2003): having received a legal notice from Matias Corporation, I have removed my program from my site (http://cvs.monstuff.com) until I get the issue sorted out.
Update (April 23rd, 2003): the license offered by Matias Corporation doesn't seem to fit my program as it is restricted to non-system-wide applications. I am therefore removing all HalfKeyboard related functionality from my program and putting it back online (KeyCombo project). It's educational purpose remains as it shows the use of global system hooks in windows, but it's functionality is now limited to launching IE when the "space-1" keyboard combination is pressed and exit when "space-esc" is pressed, which I believe isn't covered by the HalfKeyboard patent. Other "space-<key>" combinations are now let through as <key> (instead of <mirrored-key>) so that it doesn't mimic the HalfKeyboard functionality. Adding that mapping or more sophisticated ones is easy.
Here is the new project source location. You can build it with VS.net.
The code and the UI are not very advanced but the part that does the job (the Hook) uses some pretty interesting APIs from windows.
Intercepting all keyboard events
Basically, using SetWindowsHookEx, a keyboard event hook or filter function is added in the windows event processing chain. It receives all the incoming keyboard events and may choose to either let the be processed by the remaining of the chain (with CallNextHookEx) or drop them.
A trick is that SetWindowsHookEx sets a callback function that has to be in a dll (because it is a global hook, per the msdn doc). This is why the code is split into a Hook dll and a Launcher that only instantiates the Hook.
I recently came onto this Code Project post that details a re-usable solution to implementing global system hooks. It will avoid you rewriting most of the hooking code like I did. It relies on a template trick to share the hooking code while having a different set of static callback per implementation. It also mentions other uses for windows hooks.
Emitting new keyboard events
Also to replace key combinations like SPACE-F (replaced by J), new keyboard events are emitted with keybd_event.
Artificial keyboard events (that don't actually come from the keyboard) can be let through with no processing as they have a special flag (LLKHF_INJECTED).
A similar event catching and event emitting can be done for the mouse events. I once wrote a little keyboard and mouse sharing prototype program based on this principle. The events are caught on one computer, serialized and sent through the network and replayed on the second computer.
Update: I bet ActiveWords is a global hook on the keyboard ;-)
Update: Another Code Project article on hooks: "An All-Purpose Keyboard Hooker".
Update (2006-02-20): After receiving a couple of requests by email, I dug up the source code for KeyCombo and got it to compile again. Here is the new zip file of the project.
Furthermore, Daniel Ra pointed out to another solution to achieve similar results using the AutoHotkey utility, as described on this forum. Thanks for the tip.
Another one-handed keyboard (for cellphones):
Nice example hook code. I tried it as it is but the space bar was not working. I can see there are / will be some tricks involved to keep the space bar responsive for normal typing while avoiding false key translations for faster typists. I find I have a tendancy to start pressing the next key before the spacebar is completly release.
JohnPosted by: John Marshall at September 7, 2003 04:34 PM
The code project just published an article on using windows hooks from C#.
Check it out at http://www.codeproject.com/csharp/NetWin32Hooks.asp
The MSDNMag article that it is based on goes into more details of the interop part. Unfortunately they don't do system-wide hooks, only local ones.