Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中使用全局热键捕获密钥#_C#_Keyboard Hook_Global Hotkey - Fatal编程技术网

C# 在C中使用全局热键捕获密钥#

C# 在C中使用全局热键捕获密钥#,c#,keyboard-hook,global-hotkey,C#,Keyboard Hook,Global Hotkey,我有一个在后台运行的应用程序,就像我可以将我的应用程序放在系统托盘中一样。如果它仍在系统托盘上,我的应用程序将完成它的工作。每当用户按F10或F9时,就会完成一些工作。我试过这个: public partial class Form1 : Form { public int a = 1; [DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, int

我有一个在后台运行的应用程序,就像我可以将我的应用程序放在系统托盘中一样。如果它仍在系统托盘上,我的应用程序将完成它的工作。每当用户按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);
    }

}

当我使用设置“this.ShowInTaskbar=false”这一行时,它不起作用。但如果我不设置这一行,它可以正常工作。对于我的应用程序,我必须使用这一行。我如何解决这个问题

据我所知,无论何时更改“ShowInTaskbar”状态,都需要重新注册热键


其他人也有类似的问题;请参阅。

您需要订阅操作系统通过本机函数调用(如
RegisterHotKey()
)发送的某些消息。调用此函数时,通过指定窗口的
句柄
,告诉操作系统要向哪个窗口发送消息,这可以被视为一个地址。当您设置
ShowInTaskbar=false
时,句柄会发生变化,因此操作系统将不知道从何处找到您

见第一段:

RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9);
为了解决您的问题,您可以创建一个派生自“提供窗口句柄和窗口过程的低级封装”的类。并且从该类中(或者至少使用该类的句柄,具体取决于您的实现),使用一个永远不会更改的句柄注册热键

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