繁体   English   中英

当表单不清晰时,注册按下的多个键

[英]Register multiple keys pressed, when form is not in focus

我正在开发一个程序,该程序将在每次按下某个键时执行某项操作,而不管表单是否处于焦点状态。 现在它可以正常工作,但是只有一个热键。 我不知道如何制作更多的热键,并在if语句中检查它们。 代码如下:

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);
    }
}

它将完全不接受带有“ ghk”和“ ghk2”的if语句。 预先感谢您的帮助。

最好的祝福

我想做同样的事情,并在这里找到了解决方案。 它声明wParam存储密钥标识符。 因此,您需要做的(在WndProc上)是:

//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

然后,您可以简单地将密钥传递给HandleHotkey(),如果需要或有两种不同的方法。

编辑:这是如何使其将Keys参数传递给处理程序方法:

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());
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM