I'm working on a program that will do something whenever a certain key is pressed regardless of whether or not the form is in focus. Right now it works just fine, but only with one hotkey. I can't figure out how to make more hotkeys, and check for them in a if statement or so. The code is below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace DotA_2_Timer
{
public partial class Form1 : Form
{
private KeyHandler ghk;
private KeyHandler ghk2;
public Form1()
{
InitializeComponent();
ghk = new KeyHandler(Keys.A, this);
ghk2 = new KeyHandler(Keys.B, this);
ghk.Register();
ghk2.Register();
}
public class KeyHandler
{
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private int key;
private IntPtr hWnd;
private int id;
public KeyHandler(Keys key, Form form)
{
this.key = (int)key;
this.hWnd = form.Handle;
id = this.GetHashCode();
}
public override int GetHashCode()
{
return key ^ hWnd.ToInt32();
}
public bool Register()
{
return RegisterHotKey(hWnd, id, 0, key);
}
public bool Unregiser()
{
return UnregisterHotKey(hWnd, id);
}
}
public static class Constants
{
//windows message id for hotkey
public const int WM_HOTKEY_MSG_ID = 0x0312;
}
private void HandleHotkey()
{
if (ghk == Keys.A) {
MessageBox.Show("The Key A is pressed");
}
if (ghk2 == Keys.B) {
MessageBox.Show("The Key B is pressed");
}
}
protected override void WndProc(ref Message m)
{
if (m.Msg == Constants.WM_HOTKEY_MSG_ID)
HandleHotkey();
base.WndProc(ref m);
}
}
It won't accept the if statement at all with the "ghk" and "ghk2". Thank you in advance for helping.
Best regards
I wanted to do the same thing, and found the solution here . It states that the wParam stores the key identifier. So what you need to do (at WndProc) is:
//WndProc(ref Message m)
if (m.WParam.ToInt32() == ghk.GetHashCode())
//The key associated with ghk got pressed
if (m.WParam.ToInt32() == ghk2.GetHashCode())
//The key associated with ghk2 got pressed
Then you can simply pass the key to HandleHotkey() if you want or have two different methods.
Edit: Here's how to make it pass the Keys parameter to the handler method:
private List<KeyHandler> Handlers = new List<KeyHandler>();
public MainForm()
{
InitializeComponent();
Handlers.Add(new KeyHandler(Keys.Z, this));
Handlers.Last().Register();
Handlers.Add(new KeyHandler(Keys.H, this));
Handlers.Last().Register();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == Constants.WM_HOTKEY_MSG_ID)
{
int key = m.WParam.ToInt32();
HandleHotkey(Handlers.First(entry => entry.GetHashCode() == key).Key);
}
base.WndProc(ref m);
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
Handlers.ForEach(entry => entry.Unregiser());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.