HotKey – Global shortcuts
Hotkeys allow you to associate a key combination with an action. For example, Alt+F4 closes the current application. This action is not set in each application but is set in Windows. I needed to do the same thing in my WindowManager application. Indeed, the application runs in the background and has to react to certain key combinations to move the current window.
As you can imagine this function is quite tricky and therefore requires a minimum of interop. Here are the 2 functions used:
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, ModifierKeys modifiers, Keys keys);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[Flags]
public enum Modifiers
{
None = 0x0000,
Alt = 0x0001,
Ctrl = 0x0002,
Shift = 0x0004,
Win = 0x0008
}
hWnd
corresponds to the handle of the window:- WinForm :
myWindow.Handle
- WPF :
new WindowInteropHelper(myWindow).Handle
- WinForm :
id
is a number that will allows you to know which hotkey is triggeredModifierKeys
matches keys Control, Alt, Shift and Windows.Keys
matches all other keys. In WPF you must add a reference toSystem.Window.Forms
, or recreate the enumeration.
You can declare a shortcut using RegisterHotKey
:
RegisterHotKey(Handle, id: 1, ModifierKeys.Control, Keys.A);
RegisterHotKey(Handle, id: 2, ModifierKeys.Control | ModifierKeys.Alt, Keys.B);
Now that the hotkeys are declared, it must be associated with a method. To do this, you must interact with the Windows message loop:
ComponentDispatcher.ThreadPreprocessMessage += ThreadPreprocessMessageMethod;
private void ThreadPreprocessMessageMethod(ref MSG msg, ref bool handled)
{
const int WmHotKey = 786;
if (handled || msg.message != WmHotKey)
return;
var id = (int)msg.wParam;
if (id == 1) // Ctrl + A
{
// TODO
handled = true;
}
else if (id == 2) // Ctrl + Alt + B
{
// TODO
handled = true;
}
}
The only thing left to do is to unregister the shortcut when closing the application:
UnregisterHotKey(Handle, id: 1);
All the code is available in the application WindowManager.
Do you have a question or a suggestion about this post? Contact me!