zoukankan      html  css  js  c++  java
  • C# 注册 Windows 热键

    闲扯:

      前几日,一个朋友问我如何实现按 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 的效果了。

  • 相关阅读:
    UVa 12174 (滑动窗口) Shuffle
    UVa 1607 (二分) Gates
    CodeForces ZeptoLab Code Rush 2015
    HDU 1525 (博弈) Euclid's Game
    HDU 2147 (博弈) kiki's game
    UVa 11093 Just Finish it up
    UVa 10954 (Huffman 优先队列) Add All
    CodeForces Round #298 Div.2
    UVa 12627 (递归 计数 找规律) Erratic Expansion
    UVa 714 (二分) Copying Books
  • 原文地址:https://www.cnblogs.com/zhhh/p/4464551.html
Copyright © 2011-2022 走看看