在Winform和WPF中注册全局快捷键实现思路及代码_C#教程

快捷键辅助类

复制代码 代码如下:

class HotKey
{
/// <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,
int id,
KeyModifiers fsModifiers,
int 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,
int id
);
/// <summary>
/// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
/// </summary>
/// <param name="lpString"></param>
/// <returns></returns>
[DllImport("kernel32", SetLastError = true)]
public static extern short GlobalAddAtom(string lpString);
[DllImport("kernel32", SetLastError = true)]
public static extern short GlobalDeleteAtom(short nAtom);
/// <summary>
/// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
/// </summary>
[Flags()]
public enum KeyModifiers
{
None = 0,
Alt = 1,
Ctrl = 2,
Shift = 4,
WindowsKey = 8
}
/// <summary>
/// 热键的对应的消息ID
/// </summary>
public const int WM_HOTKEY = 0x312;
}

WinForm方法
在中在onload中注册事件,然后重载WndProc,对返回的消息进行处理

复制代码 代码如下:

int alts,altd;
protected override void OnLoad(EventArgs e)
{
alts= HotKey.GlobalAddAtom("Alt-S");
altd= HotKey.GlobalAddAtom("Alt-D");
HotKey.RegisterHotKey(this.Handle, alts, HotKey.KeyModifiers.Alt, (int)Keys.S);
HotKey.RegisterHotKey(this.Handle, altd, HotKey.KeyModifiers.Alt, (int)Keys.D);
}
protected override void WndProc(ref Message m)// 监视Windows消息
{
switch (m.Msg)
{
case HotKey.WM_HOTKEY:
ProcessHotkey(m);//按下热键时调用ProcessHotkey()函数
break;
}
base.WndProc(ref m); //将系统消息传递自父类的WndProc
}
private void ProcessHotkey(Message m) //按下设定的键时调用该函数
{
IntPtr id = m.WParam;//IntPtr用于表示指针或句柄的平台特定类型
int sid=id.ToInt32();
if(sid==alts)
{
MessageBox.Show("按下Alt+S");
}
else if(sid==altd)
{
MessageBox.Show("按下Alt+D");
}
}

也可以在Application使用AddMessageFilter添加处理来代替重载WndProc,可以使form自身实现IMessageFilter接口,
注册方法

复制代码 代码如下:

[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form1();
Application.AddMessageFilter(form);
Application.Run(form);
}

实现接口

复制代码 代码如下:

bool IMessageFilter.PreFilterMessage(ref Message m)
{
const int WM_HOTKEY = 0x0312;//如果m.Msg的值为0x0312那么表示用户按下了热键
switch (m.Msg)
{
case WM_HOTKEY:
ProcessHotkey(m);//按下热键时调用ProcessHotkey()函数
break;
}
//如果筛选消息并禁止消息被调度,则为 true;如果允许消息继续到达下一个筛选器或控件,则为 false
return false ;
}

如果同时在AddMessageFilter和WndProc处理消息,顺序是先IMessageFilter,然后调用WndProc
WPF方法
WPF中的注册方法和Winform一样,只是WPF的Key枚举的值不能正确监听,要引用System.Windows.Forms.Keys或者自己定义才可以正确注册,窗口句柄也需要借助WindowInteropHelper来得到,处理函数的加入也和Winform不同,需要HwndSource来添加处理函数。
注册及处理方法

复制代码 代码如下:

int alts, altd;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
HwndSource hWndSource;
WindowInteropHelper wih = new WindowInteropHelper(this);
hWndSource = HwndSource.FromHwnd(wih.Handle);
//添加处理程序
hWndSource.AddHook(MainWindowProc);
alts = HotKey.GlobalAddAtom("Alt-S");
altd = HotKey.GlobalAddAtom("Alt-D");
HotKey.RegisterHotKey(wih.Handle, alts, HotKey.KeyModifiers.Alt, (int)System.Windows.Forms.Keys.S);
HotKey.RegisterHotKey(wih.Handle, altd, HotKey.KeyModifiers.Alt, (int)System.Windows.Forms.Keys.D);
}
private IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case HotKey.WM_HOTKEY:
{
int sid = wParam.ToInt32();
if (sid == alts)
{
MessageBox.Show("按下Alt+S");
}
else if (sid == altd)
{
MessageBox.Show("按下Alt+D");
}
handled = true;
break;
}
}
return IntPtr.Zero;
}

注意
如果注册快捷键,RegisterHotKey中的fsModifiers参数为0,即None选项,一些安全软件会警报,可能因为这样就可以全局监听键盘而造成安全问题
代码下载

时间: 2024-10-25 03:42:42

在Winform和WPF中注册全局快捷键实现思路及代码_C#教程的相关文章

WPF自动隐藏的消息框的实例代码_C#教程

(鼠标放上去将一直显示,移开动画继续),提供normal和error两种边框. 介绍:传统的确定,取消,OK,CANCAL之类的对话框太繁琐了,由于项目需要而诞生的仿手机式提示对话框.当然传统的对话框项目中也有,这里就不做介绍了. 出场和退场动画做得很简单,就用Blend随便鼓捣了一番,将就用吧. 预览效果如下: 思路其实很简单:将窗体透明化->布局和样式设计->后台传值调用. 准备工作:Microsoft.Expression.Interactions.dll和System.Windows.

C#中使用Socket获取网页源代码的代码_C#教程

WebToolkit类: 复制代码 代码如下: using System; using System.Net.Sockets; using System.Text; namespace ConsoleApplication1 { class WebToolkit { /// <summary> /// Url结构 /// </summary> struct UrlInfo { public string Host; public int Port; public string Fi

在C#代码中应用Log4Net(四)在Winform和Web中捕获全局异常

毕竟人不是神,谁写的程序都会有bug,有了bug不可怕,可怕的是出错了,你却不知道错误在哪里.所以我们需要将应用程序中抛出的所有异常都记录起来,不然出了错,找问题就能要了你的命.下面我们主要讨论的是如何捕捉全局的异常.基本上在winform或web中捕获全局异常的思路都是一样的,在全局的应用程序对象中添加异常捕获的代码,并写入日志文件中. 一.在Winform程序中捕获全局异常 在winfrom中我们需要了解Application对象中的两个事件 ①Application.ThreadExcep

GMap.Net开发之在WinForm和WPF中使用GMap.Net地图插件

GMap.NET是什么? 来看看它的官方说明:GMap.NET is great and Powerful, Free, cross platform, open source .NET control. Enable use routing, geocoding, directions and maps from Coogle, Yahoo!, Bing, OpenStreetMap, ArcGIS, Pergo, SigPac, Yendux, Mapy.cz, Maps.lt, iKart

在WinForm和WPF中使用GMap.Net地图插件简单教程_实用技巧

如何在WinForm中使用GMap.Net 项目主页:https://greatmaps.codeplex.com/ 下载GMap.Net,我下载的版本:greatmaps_81b71bf30091,编译三个核心项目: GMap.Net.Core:核心DLL GMap.Net.WindowsForms:WinForm中使用的DLL GMap.NET.WindowsPresentation:WPF中使用的DLL 在WinForm项目中使用GMap: 1.新建一个Visual C# 的Windows

C#中图片、二进制与字符串的相互转换方法_C#教程

本文实例讲述了C#中图片.二进制与字符串的相互转换方法.分享给大家供大家参考,具体如下: protected void Button1_Click(object sender, EventArgs e) { //图片转二进制 byte[] imageByte = GetPictureData(Server.MapPath("./uploadfile/111.png")); //二进制转换成字符串 string picStr = Convert.ToBase64String(imageB

C#中构造函数和析构函数用法实例详解_C#教程

本文实例讲述了C#中构造函数和析构函数用法.分享给大家供大家参考,具体如下: 构造函数与析构函数是一个类中看似较为简单的两类函数,但在实际运用过程中总会出现一些意想不到的运行错误.本文将较系统的介绍构造函数与析构函数的原理及在C#中的运用,以及在使用过程中需要注意的若干事项. 一.构造函数与析构函数的原理 作为比C更先进的语言,C#提供了更好的机制来增强程序的安全性.C#编译器具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序员的大忙.但是程序通过了编译检查并不表示错误

c#中的浮点型转整形的舍取 四舍五入和银行家舍入实现代码_C#教程

Double显示转换int 复制代码 代码如下: static void Main(string[] args) { Console.WriteLine("5.1~{0}", (int)5.1d); Console.WriteLine("5.5~{0}", (int)5.5d); Console.WriteLine("5.8~{0}", (int)5.8d); Console.WriteLine("2.1~{0}", (int

C#在winform中实现数据增删改查等功能_C#教程

winform中利用ado.net实现对单表的增删改查的详细例子,具体如下: 1.前言: 运行环境:VS2013+SQL2008+Windows10 程序界面预览: 使用的主要控件:dataGridview和menuStrip等.  2.功能具体介绍: 1.首先,我们要先实现基本的数据操作,增删改查这几个操作. (1)先定义一个数据库操作的公共类: using System; using System.Collections.Generic; using System.Linq; using S