【问题标题】:key capture using global hotkey in C#在 C# 中使用全局热键捕获键
【发布时间】:2013-03-15 14:07:52
【问题描述】:

我有一个在后台运行的应用程序,就像我可以将我的应用程序保留在系统托盘中一样。如果它保留在系统托盘上,我的应用程序将完成它的工作。每当用户按 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# keyboard-hook global-hotkey


    【解决方案1】:

    您需要订阅操作系统通过本机函数调用(如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();
        }
    }
    

    【讨论】:

      【解决方案2】:

      据我所知,每当您更改“ShowInTaskbar”状态时,您都需要重新注册热键。

      其他人也有类似的问题;见this thread

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-12
        • 2011-06-30
        • 2018-12-21
        相关资源
        最近更新 更多