Winform程序全局热键
Winform程序全局热键一般采用的是,调用windows api的形式,主要是通过下面的四个函数
/// <summary>
/// 如果函数执行成功,返回值不为0。
/// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error()
/// </summary>
/// <param name="hWnd">要定义热键的窗口的句柄</param>
/// <param name="id">定义热键ID(不能与其它ID重复) </param>
/// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
/// <param name="vk">定义热键的内容,WinForm中可以使用Keys枚举转换,
/// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量</param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(
IntPtr hWnd,
UInt32 id,
UInt32 fsModifiers,
UInt32 vk
);
/// <summary>
/// 取消注册热键
/// </summary>
/// <param name="hWnd">要取消热键的窗口的句柄</param>
/// <param name="id">要取消热键的ID</param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(
IntPtr hWnd,
UInt32 id
);
/// <summary>
/// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
/// </summary>
/// <param name="lpString"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true)]
public static extern UInt32 GlobalAddAtom(string lpString);
/// <summary>
/// 从全局原子表删除指定一个字符串,并返回这个字符串的唯一标识符,失败返回0
/// </summary>
/// <param name="nAtom"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true)]
public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom);
还有一个辅助类,标志用户是否注册了含有win ctrl shift等特殊键的快捷方式
/// <summary>
/// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
/// </summary>
public enum KeyFlags
{
MOD_NONE = 0x0,
MOD_ALT = 0x1,
MOD_CONTROL = 0x2,
MOD_SHIFT = 0x4,
MOD_WIN = 0x8
}
贴上全部代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections;
namespace luolunz
{
public delegate void HotkeyEventHandler(int hotKeyID);
public class HotkeyHelper : IMessageFilter
{
public event HotkeyEventHandler OnHotkey;
public enum KeyFlags
{
MOD_NONE=0x0,
MOD_ALT = 0x1,
MOD_CONTROL = 0x2,
MOD_SHIFT = 0x4,
MOD_WIN = 0x8
}
class NativeMethods
{
private NativeMethods() { }
#region WIN32 API
/// <summary>
/// 如果函数执行成功,返回值不为0。
/// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error()
/// </summary>
/// <param name="hWnd">要定义热键的窗口的句柄</param>
/// <param name="id">定义热键ID(不能与其它ID重复) </param>
/// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
/// <param name="vk">定义热键的内容,WinForm中可以使用Keys枚举转换,
/// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量</param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(
IntPtr hWnd,
UInt32 id,
UInt32 fsModifiers,
UInt32 vk
);
/// <summary>
/// 取消注册热键
/// </summary>
/// <param name="hWnd">要取消热键的窗口的句柄</param>
/// <param name="id">要取消热键的ID</param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(
IntPtr hWnd,
UInt32 id
);
/// <summary>
/// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
/// </summary>
/// <param name="lpString"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true)]
public static extern UInt32 GlobalAddAtom(string lpString);
/// <summary>
/// 从全局原子表删除指定一个字符串,并返回这个字符串的唯一标识符,失败返回0
/// </summary>
/// <param name="nAtom"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true)]
public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom);
/// <summary>
/// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
/// </summary>
public enum KeyFlags
{
MOD_NONE = 0x0,
MOD_ALT = 0x1,
MOD_CONTROL = 0x2,
MOD_SHIFT = 0x4,
MOD_WIN = 0x8
}
#endregion
}
Hashtable keyIDs = new Hashtable();
IntPtr hWnd;
public HotkeyHelper(IntPtr hWnd)
{
this.hWnd = hWnd;
Application.AddMessageFilter(this);
}
public UInt32RegisterHotkey(Keys Key, KeyFlags keyflags)
{
UInt32 hotkeyid = NativeMethods.GlobalAddAtom(System.Guid.NewGuid().ToString());
NativeMethods.RegisterHotKey((IntPtr)hWnd, hotkeyid, (UInt32)keyflags, (UInt32)Key);
keyIDs.Add(hotkeyid, hotkeyid);
return (UInt32)hotkeyid;
}
public void UnregisterHotkeys()
{
Application.RemoveMessageFilter(this);
foreach (UInt32 key in keyIDs.Values)
{
NativeMethods.UnregisterHotKey(hWnd, key);
NativeMethods.GlobalDeleteAtom(key);
}
}
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x312)
{
if (OnHotkey != null)
{
foreach (UInt32 key in keyIDs.Values)
{
if ((UInt32)m.WParam == key)
{
OnHotkey((int)m.WParam);
return true;
}
}
}
}
return false;
}
}
}
使用方式:
HotkeyHelper HotkeyHelper { set; get; }
UInt32 CONTROR_F;
UInt32 CONTROR_G;
UInt32 F10;
HotkeyHelper = new HotkeyHelper(this.Handle);
CONTROR_F = HotkeyHelper.RegisterHotkey(Keys.F, HotkeyHelper.KeyFlags.MOD_CONTROL | HotkeyHelper.KeyFlags.MOD_SHIFT);
CONTROR_G = HotkeyHelper.RegisterHotkey(Keys.G, HotkeyHelper.KeyFlags.MOD_CONTROL);
F10 = HotkeyHelper.RegisterHotkey(Keys.F10, 0);
HotkeyHelper.OnHotkey += new HotkeyEventHandler(OnHotkey);
private void OnHotkey(int hotkeyID)
{
if (hotkeyID == CONTROR_F)
{
//do something
MessageBox.Show("CONTROR_SHIT_F");
}
else if (hotkeyID == F10)
{
//do something else
MessageBox.Show("F10");
}
}
局部热键(键盘快捷键的捕获)
/// <summary>
/// 用户键盘快捷键获取与处理
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
KeyEventArgs e = new KeyEventArgs(keyData);
if (keyData == (Keys.Alt | Keys.P))
{
//do something
}
if (keyData == (Keys.Alt | Keys.C))
{
//do something
}
if (keyData == (Keys.Alt | Keys.A))
{
//do something
}
if (keyData == (Keys.Alt | Keys.Z))
{
//do something
}
if (keyData == (Keys.F1))
{
//do something
}
if (keyData == (Keys.F3))
{
//do something
}
return true;
}