User32.dll exposes a
RegisterHotKey function, to register, well, hotkeys:
[DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool RegisterHotKey(IntPtr hWnd, IntPtr id, uint fsModifiers, uint vk);
Using this API, we can register hotkeys like Ctrl+R or whatever modifier+key combination we want to use, and then we can handle
WM_HOTKEY messages to run the associated application command, and then we can use
UnregisterHotKey to un-hook the key combination.
In Visual Studio, we have "composite", 2-step "chords" hotkeys:
- Ctrl+R, Ctrl+R triggers refactor / rename
- Ctrl+R, Ctrl+M triggers refactor / extract method
I'm trying to think of a good way of doing exactly this, and I thought of several approaches:
- Register Ctrl+R as a hotkey, then use a low-level key hook to capture (and swallow) the next keypress.
- Register Ctrl+R as a hotkey, and then handle
WM_HOTKEYmessages by registering all possible 2nd keys for that hotkey; unregister them upon the next keypress. This has the advantage of processing everything as
- Don't register any hotkeys. Use a low-level key hook to capture everything, and basically implement the hotkey-messaging logic manually.
What's the better approach, and why? Could I run into stability issues if I go with #2 and start continuously hooking and un-hooking stuff? Is there another way I haven't thought of? How are Visual Studio and ReSharper doing it?