Winform注册和注销全局快捷键

本文转载:http://www.cnblogs.com/scottckt/archive/2007/12/03/981105.html

1.首先引入System.Runtime.InteropServices

using System.Runtime.InteropServices;

2.在类内部声明两个API函数,它们的位置和类的成员变量等同.

[System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函数 
public static extern bool RegisterHotKey(
            IntPtr hWnd, // handle to window 
            int id, // hot key identifier 
            uint fsModifiers, // key-modifier options 
            Keys vk // virtual-key code 
            ); 

            [System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函数 
public static extern bool UnregisterHotKey(
            IntPtr hWnd, // handle to window 
            int id // hot key identifier 
            );

3.定义一个KeyModifiers的枚举,以便出现组合键

public enum KeyModifiers
            {
            None = 0,
            Alt = 1,
            Control = 2,
            Shift = 4,
            Windows = 8
            }

4.在类的构造函数出注册系统热键 示例,下例注册了四个热键:

public MainForm()
            {
            InitializeComponent(); 

            RegisterHotKey(Handle, 100, 2, Keys.Left); // 热键一:Control +光标左箭头
RegisterHotKey(Handle, 200, 2, Keys.Right); / /热键一:Control +光标右箭头
RegisterHotKey(Handle, 300, 2, Keys.Up); // 热键一:Control +光标上箭头
RegisterHotKey(Handle, 400, 2, Keys.Down); // 热键一:Control +光标下箭头

....; 
            }

5.重写WndProc()方法,通过监视系统消息,来调用过程 示例:

protected override void WndProc(ref Message m)//监视Windows消息 
{ 
const int WM_HOTKEY = 0x0312; //如果m.Msg的值为0x0312那么表示用户按下了热键 
switch (m.Msg) 
            { 
            case WM_HOTKEY: 
            ProcessHotkey(m); //按下热键时调用ProcessHotkey()函数
break; 
            } 
            base.WndProc(ref m); //将系统消息传递自父类的WndProc 
            }

5.不用说,我们接下来需要实现ProcessHotkey函数:

//按下设定的键时调用该函数 

private void ProcessHotkey(Message m) 
            {
            IntPtr id = m.WParam; //IntPtr用于表示指针或句柄的平台特定类型 
//MessageBox.Show(id.ToString()); 
            string sid = id.ToString(); 
            switch (sid)
            {
            case "100": DecreseVolumnb(); break; // 按下Control +光标左箭头,调用函数DecreseVolumnb(); 
            case "200": AddVolumnb(); break; // 按下Control +光标右箭头,调用函数AddVolumnb()
            case "300":// 按下Control +光标上箭头,显示窗体
this.Visible = true; 
            break; 
            case "400":// 按下Control +光标下箭头,隐藏窗体
this.Visible = false; 
            break; 
            } 
            }

很明显接下来分别实现函数DecreseVolumnb(); 和AddVolumnb(); 即可. 6.最后别忘了在程序退出时取消热键的注册

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
            {
            UnregisterHotKey(Handle, 100); //卸载第1个快捷键 
UnregisterHotKey(Handle, 200); //缷载第2个快捷键
UnregisterHotKey(Handle, 300); //卸载第3个快捷键 
UnregisterHotKey(Handle, 400); //缷载第4个快捷键
}

以上就是在C#程序中使用系统热键的整个过程。


闲扯:
  前几日,一个朋友问我如何实现按 F1 键实现粘贴(Ctrl+V)功能,百度了一个方法,发给他,他看不懂(已经是 Boss 的曾经的码农),我就做了个Demo给他参考。今日得空,将 Demo 整理一下,做为收集,也给大家一个参考。

Begin:

  注册系统热键,.net 类库好像没有提供现成的方法,需要使用系统提供的 DLL。

  微软将许多常用的系统函数都封装在 user32.dll 中,注册系统热键使用到的 RegisterHotKey 函数和 UnregisterHotKey 函数也在该 DLL 文件中,所以我们需要将这两个方法映射到 C# 类中。下面代码封装了这两个方法,并做一些简单的封装,如下:

复制代码
 1 using System;
 2 using System.Text;
 3 using System.Runtime.InteropServices;
 4 using System.Windows.Forms;
 5 
 6 public class SystemHotKey
 7 {
 8     /// <summary>
 9     /// 如果函数执行成功,返回值不为0。
10     /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。
11     /// </summary>
12     /// <param name="hWnd">要定义热键的窗口的句柄</param>
13     /// <param name="id">定义热键ID(不能与其它ID重复)</param>
14     /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
15     /// <param name="vk">定义热键的内容</param>
16     /// <returns></returns>
17     [DllImport("user32.dll", SetLastError = true)]
18     public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);
19 
20     /// <summary>
21     /// 注销热键
22     /// </summary>
23     /// <param name="hWnd">要取消热键的窗口的句柄</param>
24     /// <param name="id">要取消热键的ID</param>
25     /// <returns></returns>
26     [DllImport("user32.dll", SetLastError = true)]
27     public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
28 
29     /// <summary>
30     /// 辅助键名称。
31     /// Alt, Ctrl, Shift, WindowsKey
32     /// </summary>
33     [Flags()]
34     public enum KeyModifiers { None = 0, Alt = 1, Ctrl = 2, Shift = 4, WindowsKey = 8 }
35 
36     /// <summary>
37     /// 注册热键
38     /// </summary>
39     /// <param name="hwnd">窗口句柄</param>
40     /// <param name="hotKey_id">热键ID</param>
41     /// <param name="keyModifiers">组合键</param>
42     /// <param name="key">热键</param>
43     public static void RegHotKey(IntPtr hwnd, int hotKeyId, KeyModifiers keyModifiers, Keys key)
44     {
45         if (!RegisterHotKey(hwnd, hotKeyId, keyModifiers, key))
46         {
47             int errorCode = Marshal.GetLastWin32Error();
48             if (errorCode == 1409)
49             {
50                 MessageBox.Show("热键被占用 !");
51             }
52             else
53             {
54                 MessageBox.Show("注册热键失败!错误代码:" + errorCode);
55             }
56         }
57     }
58 
59     /// <summary>
60     /// 注销热键
61     /// </summary>
62     /// <param name="hwnd">窗口句柄</param>
63     /// <param name="hotKey_id">热键ID</param>
64     public static void UnRegHotKey(IntPtr hwnd, int hotKeyId)
65     {
66         //注销指定的热键
67         UnregisterHotKey(hwnd, hotKeyId);
68     }
69 
70 }
复制代码
  (这个类是网上搜到的,这里借用一下。。。在此对原作者表示感谢!)

  上面这个类中,只需要使用两个静态方法 RegHotKey 和 UnRegHotKey 来注册和注销热键即可。

  这里有一点需要注意一下:这两个方法需要一个窗口的句柄来绑定系统热键消息,也就是说,当用户按下注册过的热键以后,系统会将按键消息发送给指定窗口。

  RegHotKey 方法有四个参数,第一个是窗口句柄,第二个是自定义的热键ID,第三个是组合键,比如Ctrl、Alt、Shift等,如果没有,就是None,第四个就是指定的热键了。

  UnRegHotKey 方法只需要窗口句柄和热键ID,就可以将该热键注销。

 

  然后,创建一个窗体,在代码视图中添加如下代码:

复制代码
        private const int WM_HOTKEY = 0x312; //窗口消息:热键
        private const int WM_CREATE = 0x1; //窗口消息:创建
        private const int WM_DESTROY = 0x2; //窗口消息:销毁

        private const int HotKeyID = 1; //热键ID(自定义)

        protected override void WndProc(ref Message msg)
        {
            base.WndProc(ref msg);
            switch (msg.Msg)
            {
                case WM_HOTKEY: //窗口消息:热键
                    int tmpWParam = msg.WParam.ToInt32();
                    if (tmpWParam == HotKeyID)
                    {
                        System.Windows.Forms.SendKeys.Send("^v");
                    }
                    break;
                case WM_CREATE: //窗口消息:创建
                    SystemHotKey.RegHotKey(this.Handle, HotKeyID, SystemHotKey.KeyModifiers.None, Keys.F1);
                    break;
                case WM_DESTROY: //窗口消息:销毁
                    SystemHotKey.UnRegHotKey(this.Handle, HotKeyID); //销毁热键
                    break;
                default:
                    break;
            }
        }
复制代码
  在上面代码中,WM_HOTKEY、WM_CREATE、WM_DESTROY 三个常量的值是系统定义,不用关心。HotKeyID 是自定义的一个数值,用于在注册了多个热键的时候使用该数值来区分不同热键处理逻辑,系统会在用户触发热键时将该值做为参数传递给处理程序。

  另外,上面代码中重写了一个系统方法 WndProc,这个方法叫“窗口过程”(参考百度百科),用于接收处理注册到该窗体上的所有事件,包括窗体创建、窗体销毁、系统热键等等。该方法有一个 Message 结构体参数,该参数封装了 Windows 消息的一些基本属性,比如消息ID、参数等等。

  上面代码在该方法接收到窗口创建消息的时候注册热键 F1,并且在接收到窗口销毁消息的时候注销该热键,并且在接收到系统热键消息的时候,根据消息参数(热键ID)来确认触发我们想要的动作,比如这里的模拟用户按下 Ctrl+V 键。

 

  最后,运行该程序,就可以在任意应用程序里使用 F1 键完成 Ctrl+V 的效果了。

参考:http://www.5i881.com/?winform/thread-26-1-1

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Quartz.NET 3.0 正式发布

2198
来自专栏葡萄城控件技术团队

Asp.Net MVC4入门指南(9):查询详细信息和删除记录

在本教程中,您将查看自动生成的Details和Delete方法。 查询详细信息和删除记录 打开Movie控制器并查看Details方法。 public Acti...

2368
来自专栏从零开始学自动化测试

python接口自动化3-自动发帖(session)

前言 上一篇模拟登录博客园,但这只是第一步,一般登录后,还会有其它的操作,如发帖,评论等,这时候如何保持会话呢? 一、session简介 1.查看帮助文档...

3943
来自专栏ASP.NETCore

如何在多个项目中分离Asp.Net Core Mvc的Controller和Areas

软件系统中总是希望做到松耦合,项目的组织形式也是一样,本篇文章将介绍在ASP.NET CORE MVC中怎么样将Controller与主网站项目进行分离,并且对...

2463
来自专栏圣杰的专栏

事件总线知多少(2)

源码路径:Github-EventBus 事件总线知多少(1) 事件总线知多少(2) 1.引言 之前的一篇文章事件总线知多少(1),介绍了什么是事件总线...

2367
来自专栏张善友的专栏

Quartz.NET 3.0 正式发布

Quartz.NET是一个强大、开源、轻量的作业调度框架,你能够用它来为执行一个作业而创建简单的或复杂的作业调度。它有很多特征,如:数据库支持,集群,插件,支持...

24510
来自专栏数值分析与有限元编程

CodeBlocks 安装及配置

CodeBlocks 是最适合gfortran的IDE,可以说是量身打造,配置也不复杂。而且体量很小,跟vs动不动就几个G甚至十几个G相比,那是小巫见大巫了。C...

2583
来自专栏noteless

批处理启动vm虚拟机服务 vm12启动无界面启动vm虚拟机系统 windows上如何操作服务 sc net启动关闭服务

"D:\ApplicationFiles\System\VMware Workstation\vmrun.exe" start "F:\virtualMachi...

4623
来自专栏博客园

深入浅出话资源

我们把有用的东西称为资源。“兵马未动,粮草先行”-----程序中的各种数据就是算法的原料和粮草。程序中可以存放数据的地方有很多,可以放在数据库里、可以存储在变量...

1062
来自专栏iOS技术杂谈

iOS多线程——你要知道的NSThread都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里

你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里 转载请注明出处 https://cloud.tencent.co...

3769

扫码关注云+社区

领取腾讯云代金券