个性化阅读
专注于IT技术分析

如何在Winforms中为单个键注册单个或多个全局热键

本文概述

有多种方法可以在WinForms应用程序中添加NHotkey库之类的热键, 但是许多方法都需要添加特定的KeyStroke(例如Alt + Ctrl + F8)才能执行, 并且仅在Form处于焦点状态时才起作用。使用全局热键的正确方法。作为计算机爱好者, 当所有内容都易于使用时, 我会喜欢它, 并使用许多应用程序来录制像camtasia这样的屏幕, 它使用了有用的HotKey功能, 可让你通过按F9或F10来启动或暂停当前的录制过程。对这种功能感兴趣的是, 我开始研究, 直到找到一个很好的解决方案来将此类HotKeys附加到WinForms应用程序中, 并且今天我想与你共享此解决方案。

添加单个热键

要继续为单个键附加单个HotKey, 你需要首先在类顶部导入InteropServices模块。这将允许你导入Windows的user32.dll的RegisterHotKey方法。该方法是你用来全局注册你的热键的一种方法, 根据所按的方法, 执行一些操作。作为第一个参数, 该方法期望控件绑定到的窗口句柄, 即Form.Handle, 然后作为第二个参数, 一个唯一ID标识你自己的应用程序中的HotKey。该ID可以是你想要的ID, 只要是整数即可。作为第三个参数, 请提供0x0000以指示null作为修饰符, 最后是将在按下时触发此HotKey的Key的KeyCode。该参数应为整数, 因此你可以在MSDN官方网站上检查键码列表, 或仅强制转换Windows Forms的键枚举, 使之对开发人员更友好, 如纯代码。作为最后一步, 你需要在代码中覆盖user32.dll的WndProc函数, 以便可以在按下热键时捕获。

在此示例中, 当用户在窗体外按F9时, 我们将附加一个MessageBox:

using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing.Printing;

// 1. Import the InteropServices type
using System.Runtime.InteropServices;

namespace Sandbox
{
    public partial class Form1 : Form
    {
        // 2. Import the RegisterHotKey Method
        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

        public Form1()
        {
            InitializeComponent();

            // 3. Register HotKey

            // Set an unique id to your Hotkey, it will be used to
            // identify which hotkey was pressed in your code to execute something
            int UniqueHotkeyId = 1;
            // Set the Hotkey triggerer the F9 key 
            // Expected an integer value for F9: 0x78, but you can convert the Keys.KEY to its int value
            // See: https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
            int HotKeyCode = (int)Keys.F9;
            // Register the "F9" hotkey
            Boolean F9Registered = RegisterHotKey(
                this.Handle, UniqueHotkeyId, 0x0000, HotKeyCode
            );

            // 4. Verify if the hotkey was succesfully registered, if not, show message in the console
            if (F9Registered)
            {
                Console.WriteLine("Global Hotkey F9 was succesfully registered");
            }
            else
            {
                Console.WriteLine("Global Hotkey F9 couldn't be registered !");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        protected override void WndProc(ref Message m)
        {
            // 5. Catch when a HotKey is pressed !
            if (m.Msg == 0x0312)
            {
                int id = m.WParam.ToInt32();
                // MessageBox.Show(string.Format("Hotkey #{0} pressed", id));

                if (id == 1)
                {
                    MessageBox.Show("F9 Was pressed !");
                }
            }

            base.WndProc(ref m);
        }
    }
}

添加多个热键

在某些情况下, 你的应用程序还需要多个热键来触发多个操作。你只需增加每个附加的热键的热键ID, 就可以轻松实现此行为。如前所述, RegisterHotKey方法需要一个唯一的标识符作为你需要手动提供的第二个参数。在下面的示例中, 我们将分别为每个键1和2添加2个全局热键, 即F9和F10作为ID(如果附加了更多的热键, 则增加为3、4、5等)。当按下这些键时, 将显示一个简单的消息框, 警告你已按下热键:

using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing.Printing;

// 1. Import the InteropServices type
using System.Runtime.InteropServices;

namespace Sandbox
{
    public partial class Form1 : Form
    {
        // 2. Import the RegisterHotKey Method
        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

        public Form1()
        {
            InitializeComponent();

            // 3. Register HotKeys
            
            // Set an unique id to your Hotkey, it will be used to
            // identify which hotkey was pressed in your code to execute something
            int FirstHotkeyId = 1;
            // Set the Hotkey triggerer the F9 key 
            // Expected an integer value for F9: 0x78, but you can convert the Keys.KEY to its int value
            // See: https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
            int FirstHotKeyKey = (int)Keys.F9;
            // Register the "F9" hotkey
            Boolean F9Registered = RegisterHotKey(
                this.Handle, FirstHotkeyId, 0x0000, FirstHotKeyKey
            );

            // Repeat the same process but with F10
            int SecondHotkeyId = 2;
            int SecondHotKeyKey = (int)Keys.F10;
            Boolean F10Registered = RegisterHotKey(
                this.Handle, SecondHotkeyId, 0x0000, SecondHotKeyKey
            );

            // 4. Verify if both hotkeys were succesfully registered, if not, show message in the console
            if (!F9Registered)
            {
                Console.WriteLine("Global Hotkey F9 couldn't be registered !");
            }

            if (!F10Registered)
            {
                Console.WriteLine("Global Hotkey F10 couldn't be registered !");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        protected override void WndProc(ref Message m)
        {
            // 5. Catch when a HotKey is pressed !
            if (m.Msg == 0x0312)
            {
                int id = m.WParam.ToInt32();
                // MessageBox.Show(string.Format("Hotkey #{0} pressed", id));

                // 6. Handle what will happen once a respective hotkey is pressed
                switch (id)
                {
                    case 1:
                        MessageBox.Show("F9 Key Pressed ! Do something here ... ");
                    break;
                    case 2:
                        MessageBox.Show("F10 Key Pressed ! Do something here ... ");
                    break;
                }
            }

            base.WndProc(ref m);
        }
    }
}

取消注册热键

你的热键可能在应用程序的某个阶段可以工作, 这意味着如果用户改变了视图或应用程序中发生了某些特殊情况, 则该热键将不再可用。你只需在相同的上下文中运行UnregisterHotKey方法并将第二个已注册的HotKey的ID设置为第二个参数, 即可注销ID:

注意

有时最好具有一个布尔标志, 该标志允许根据应用程序的状态执行某些代码或不执行某些代码, 而不是注销热键。但是, 很高兴知道如何注销它们。

using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing.Printing;

// 1. Import the InteropServices type
using System.Runtime.InteropServices;

namespace Sandbox
{
    public partial class Form1 : Form
    {
        // 2. Import the RegisterHotKey Method
        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

        // 3. Import the UnregisterHotKey Method
        [DllImport("user32.dll")]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        public Form1()
        {
            InitializeComponent();

            // 4. Register the "F9" hotkey
            int UniqueHotkeyId = 1;
            int HotKeyCode = (int)Keys.F9;
            Boolean F9Registered = RegisterHotKey(
                this.Handle, UniqueHotkeyId, 0x0000, HotKeyCode
            );

            if (F9Registered)
            {
                Console.WriteLine("Global Hotkey F9 was succesfully registered");
            }
            else
            {
                Console.WriteLine("Global Hotkey F9 couldn't be registered !");
            }

            // 5. Unregister F9 HotKey
            Boolean F9UnRegistered = UnregisterHotKey(this.Handle, UniqueHotkeyId);

            if (F9UnRegistered)
            {
                Console.WriteLine("Global Hotkey F9 was succesfully UNregistered");
            }
            else
            {
                Console.WriteLine("Global Hotkey F9 couldn't be UNregistered !");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0312)
            {
                int id = m.WParam.ToInt32();
                // MessageBox.Show(string.Format("Hotkey #{0} pressed", id));

                if (id == 1)
                {
                    // This will never happen because we have registered the hotkey !
                    MessageBox.Show("F9 Was pressed !");
                }
            }

            base.WndProc(ref m);
        }
    }
}

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何在Winforms中为单个键注册单个或多个全局热键

评论 抢沙发

评论前必须登录!