在c#中使用全局热键捕获键

本文关键字:全局 | 更新日期: 2023-09-27 18:04:09

我有一个在后台运行的应用程序,我可能会把我的应用程序放在系统托盘中。如果它仍然在系统托盘上,我的应用程序将做它的工作。当用户按下F10或F9时,将完成一些工作。我试过了:

public partial class Form1 : Form
{
    public int a = 1;
    [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);

    [DllImport("User32.dll")]
    private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey);
    [DllImport("User32.dll")]
    private static extern short GetAsyncKeyState(System.Int32 vKey);
    const int MYACTION_HOTKEY_ID = 1;
    public Form1()
    {
        InitializeComponent();
        RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9);
        RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int)Keys.F10);
        this.ShowInTaskbar = false;
    }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F9) == -32767))
        {
            if ((a % 2) != 0)
            {
                a++;
                MessageBox.Show(a.ToString()+"not equal F9");
                label1.Text = "not equal F9";
            }
            if ((a % 2) == 0)
            {
                a++;
                MessageBox.Show(a.ToString()+"equal F9");
                label1.Text = " equal F9";
            }
        }
        else if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F10) == -32767))
        {
            if ((a % 2) != 0)
            {
                a++;
                MessageBox.Show(a.ToString() + "not equal F10");
                label1.Text = "not equal F10";
            }
            if ((a % 2) == 0)
            {
                a++;
                MessageBox.Show(a.ToString() + "equal F10");
                label1.Text = " equal F10";
            }
        }
        base.WndProc(ref m);
    }
}

当我使用set "this。ShowInTaskbar = false"这一行不起作用。但如果我不设置这个,它工作正常。对于我的应用程序,我必须使用这条线。我怎么解决这个????

在c#中使用全局热键捕获键

您需要订阅操作系统通过本地函数调用(如RegisterHotKey())发送的某些消息。当您调用这个函数时,您通过指定窗口的Handle来告诉操作系统将消息发送到哪个窗口,这可以被认为是一个地址。当你设置ShowInTaskbar = false手柄改变,所以操作系统将不知道在哪里到达你。

参见第一个参数:

RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9);

要解决您的问题,您可以创建一个派生自NativeWindow的类,该类"提供窗口句柄和窗口过程的低级封装"。"并且在该类中(或至少使用该类的句柄,取决于您的实现),使用永远不会更改的句柄注册热键。

public sealed class HotkeyManager : NativeWindow, IDisposable
{
    public HotkeyManager()
    {
        CreateHandle(new CreateParams());
    }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == Constants.WM_HOTKEY)
        {
             //handle hotkey message
        }
        base.WndProc(ref m);
    }
    public void Dispose()
    {
        DestroyHandle();
    }
}

据我所知,当你改变"ShowInTaskbar"状态时,你需要重新注册热键。

其他人也有类似的问题;