WPF 注册全局快捷键

 

 

 

.NET技术交流群 199281001 .欢迎加入。

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Windows;
  6 using System.Windows.Forms;
  7 using System.Windows.Interop;
  8 using System.Collections;
  9 
 10 
 11 /// <summary>
 12 /// 直接构造类实例即可注册
 13 /// 自动完成注销
 14 /// 注意注册时会抛出异常
 15 /// </summary>
 16 public class HotKey
 17 //注册系统热键类
 18 //热键会随着程序结束自动解除,不会写入注册表
 19 {
 20     #region Member
 21 
 22     int KeyId;         //热键编号
 23     IntPtr Handle;     //窗体句柄
 24     Window window;     //热键所在窗体
 25     uint Controlkey;   //热键控制键
 26     uint Key;          //热键主键
 27 
 28     public delegate void OnHotkeyEventHandeler();     //热键事件委托
 29     public event OnHotkeyEventHandeler OnHotKey = null;   //热键事件    
 30 
 31     static Hashtable KeyPair = new Hashtable();         //热键哈希表
 32 
 33     private const int WM_HOTKEY = 0x0312;       // 热键消息编号
 34 
 35     public enum KeyFlags    //控制键编码
 36     {
 37         MOD_ALT = 0x1,
 38         MOD_CONTROL = 0x2,
 39         MOD_SHIFT = 0x4,
 40         MOD_WIN = 0x8,
 41         MOD_CONTROLALT = 0x2 + 0x1
 42     }
 43 
 44     #endregion
 45 
 46     /// <summary>
 47     /// 构造函数
 48     /// </summary>
 49     /// <param name="win">注册窗体</param>
 50     /// <param name="control">控制键</param>
 51     /// <param name="key">主键</param>
 52     public HotKey(Window win, HotKey.KeyFlags control, Keys key)
 53     //构造函数,注册热键
 54     {
 55 
 56         Handle = new WindowInteropHelper(win).Handle;
 57         window = win;
 58         Controlkey = (uint)control;
 59         Key = (uint)key;
 60         KeyId = (int)Controlkey + (int)Key * 10;
 61         if (HotKey.KeyPair.ContainsKey(KeyId))
 62         {
 63             throw new Exception("热键已经被注册!");
 64         }
 65 
 66         //注册热键
 67         if (false == HotKey.RegisterHotKey(Handle, KeyId, Controlkey, Key))
 68         {
 69             throw new Exception("热键注册失败!");
 70         }
 71         if (HotKey.KeyPair.Count == 0)
 72         {
 73             //消息挂钩只能连接一次!!
 74             if (false == InstallHotKeyHook(this))
 75             {
 76                 throw new Exception("消息挂钩连接失败!");
 77             }
 78         }
 79 
 80         //添加这个热键索引
 81         HotKey.KeyPair.Add(KeyId, this);
 82 
 83     }
 84 
 85     #region core
 86 
 87     [System.Runtime.InteropServices.DllImport("user32")]
 88     private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint controlKey, uint virtualKey);
 89 
 90     [System.Runtime.InteropServices.DllImport("user32")]
 91     private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
 92 
 93     static private bool InstallHotKeyHook(HotKey hk)
 94     //安装热键处理挂钩
 95     {
 96         if (hk.window == null || hk.Handle == IntPtr.Zero)
 97             return false;
 98 
 99         //获得消息源
100         System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd(hk.Handle);
101         if (source == null) return false;
102 
103         //挂接事件
104         source.AddHook(HotKey.HotKeyHook);
105         return true;
106     }
107 
108     static private IntPtr HotKeyHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
109     //热键处理过程
110     {
111         if (msg == WM_HOTKEY)
112         {
113             HotKey hk = (HotKey)HotKey.KeyPair[(int)wParam];
114             if (hk.OnHotKey != null) hk.OnHotKey();
115         }
116         return IntPtr.Zero;
117     }
118 
119     ~HotKey()
120     //析构函数,解除热键
121     {
122         HotKey.UnregisterHotKey(Handle, KeyId);
123     }
124 
125     #endregion
126 }
注册和卸载钩子

 

调用:

 1     private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
 2         {
 3            HotKey hot = new HotKey(this,HotKey.KeyFlags.MOD_CONTROLALT,Keys.M);
 4            hot.OnHotKey += hot_OnHotKey;
 5         }
 6 
 7         void hot_OnHotKey()
 8         {
 9             MessageBox.Show("我是按ctrl+alt+m 进来的!");
10         }
posted @ 2014-07-03 10:52  b̶i̶n̶g̶.̶  阅读(1092)  评论(1编辑  收藏  举报