本文概述
有多种方法可以在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);
}
}
}
编码愉快!
评论前必须登录!
注册