如何在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函数, 以便可以在按下热键时捕获。
【如何在Winforms中为单个键注册单个或多个全局热键】在此示例中, 当用户在窗体外按F9时, 我们将附加一个MessageBox:
using System.Windows.Forms; using System; using System.Diagnostics; using System.Threading; using System.Drawing.Printing; // 1. Import the InteropServices typeusing 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 somethingint 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).aspxint HotKeyCode = (int)Keys.F9; // Register the "F9" hotkeyBoolean F9Registered = RegisterHotKey(this.Handle, UniqueHotkeyId, 0x0000, HotKeyCode); // 4. Verify if the hotkey was succesfully registered, if not, show message in the consoleif (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 typeusing 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 somethingint 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).aspxint FirstHotKeyKey = (int)Keys.F9; // Register the "F9" hotkeyBoolean F9Registered = RegisterHotKey(this.Handle, FirstHotkeyId, 0x0000, FirstHotKeyKey); // Repeat the same process but with F10int 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 consoleif (!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 pressedswitch (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 typeusing 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" hotkeyint 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 HotKeyBoolean 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); }}}

编码愉快!

    推荐阅读