I got stuck.
Right now, I am using the following code to listen to hotkeys:
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd,
int id, int fsModifiers, int vlc);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312)
{
// whatever i need
}
base.WndProc(ref m);
}
and this function to register hotkey:
Form1.RegisterHotKey(this.Handle, this.GetType().GetHashCode(), 0, (int)chr);
it works perfectly.
my question is how do I register multiple hotkeys as the same combination, for example:
- A+B+C+D
- ALT+SHIFT+B
- CTRL+ALT+SHIFT+X
edit: I found out (like Zooba said) how to "decrypt" which hotkey was sent and here's the solution:
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312)
{
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF);
if ((modifier + "+" + key == "Alt+S"))
{
//do what ever I need.
}
}
base.WndProc(ref m);
}
From the documentation for WM_HOTKEY:
lParam The low-order word specifies the keys that were to be pressed in combination with the key specified by the high-order word to generate the WM_HOTKEY message. This word can be one or more of the following values. The high-order word specifies the virtual key code of the hot key.
So you can read the LParam
member of m
to determine the keys that were pressed (alternatively, if you assign more sensible identifiers than GetHashCode
you can check WParam
).
The 'high-order word' and 'low-order word' refer to parts of the integer (actually an IntPtr
) contained in LParam
, so you will need to extract these. The low-order word is i & 0xFFFF
, while the high-order word is (i >> 16) & 0xFFFF
.
To detect which key combination was pressed, check the lowest four bits of the low-order word for the modifiers (shift, alt, control) and compare the high-order word against the virtual key code - which for letters is equal to the character value of the capital (for example, the virtual key code for A is (int)'A', but not (int)'a').
Your 'A+B+C+D' combination is not valid, since WM_HOTKEY
hotkeys only support a single character. You will need to attach a keyboard hook to detect that combination from anywhere (or handle messages if you only want to detect it while your application is active).
I found the answer. Instead of using registerhotkey
, I used KeyState
and it solved all my problems. If anyone is interested, you can go here (backup on archive.org)