• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
flashpast
博客园    首页    新随笔    联系   管理    订阅  订阅

热键注册

要做热键首先,要做的就是定义一些枚举来表示一些常量。
Code
 1    [Flags]
 2    public enum KeyModifiers
 3    {
 4        None = 0,
 5        Alt,
 6        Ctrl,
 7        Shift,
 8        Windows
 9    }

10
11    public enum WindowsMessage
12    {
13        WM_CREATE = 0X1,
14        WM_DESTROY = 0X2,
15        WM_HOTKEY = 0X312,
16    }

然后,要做的就是建立一个HotKey类,这个用来保存热键的键值,热键被激活是所触发的事件,并负责注册热键,撤销热键的操作。
Code
  1    public interface IHotKey
  2    {
  3        bool AltHotKey(KeyModifiers keyModifiers, System.Windows.Forms.Keys vk);
  4        IntPtr HWnd { get; }
  5        uint ID { get; }
  6        bool IsRegistered { get; }
  7        bool IsSuccess { get; }
  8        KeyModifiers KeyModifiers { get; }
  9        void OnHotKeyEvent();
 10        event EventHandler RegisterFailedEvent;
 11        event EventHandler HotKeyEvent;
 12        bool RegisterHotKey();
 13        void UnregisterHotKey();
 14        System.Windows.Forms.Keys Vk { get; }
 15    }

 16    public class HotKey : IHotKey
 17    {
 18        public HotKey(IntPtr hWnd, KeyModifiers keyModifiers, Keys vk)
 19        {
 20            m_hWnd = hWnd;
 21            m_keyModifiers = keyModifiers;
 22            m_vk = vk;
 23        }

 24
 25        [DllImport("user32.dll")]
 26        public static extern bool RegisterHotKey(IntPtr hWnd, UInt32 id, KeyModifiers keyModifiers, Keys vk);
 27
 28        [DllImport("user32.dll")]
 29        public static extern UInt32 UnregisterHotKey(IntPtr hWnd, UInt32 id);
 30
 31        [DllImport("kernel32.dll")]
 32        public static extern UInt32 GlobalAddAtom(String lpString);
 33
 34        [DllImport("kernel32.dll")]
 35        public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom);
 36
 37        IHotKey 成员#region IHotKey 成员
 38
 39        public bool AltHotKey(KeyModifiers keyModifiers, Keys vk)
 40        {
 41            UnregisterHotKey();
 42            m_keyModifiers = keyModifiers;
 43            m_vk = vk;
 44            return RegisterHotKey();
 45        }

 46
 47        private IntPtr m_hWnd;
 48
 49        public IntPtr HWnd
 50        {
 51            get { return m_hWnd; }
 52        }

 53        private UInt32 m_id;
 54
 55        public UInt32 ID
 56        {
 57            get { return m_id; }
 58        }

 59
 60        private KeyModifiers m_keyModifiers;
 61
 62        public KeyModifiers KeyModifiers
 63        {
 64            get { return m_keyModifiers; }
 65        }

 66        private Keys m_vk;
 67
 68        public Keys Vk
 69        {
 70            get { return m_vk; }
 71        }

 72
 73        private bool m_isRegistered;
 74
 75        public bool IsRegistered
 76        {
 77            get { return m_isRegistered; }
 78        }

 79
 80        private bool m_isSuccess;
 81
 82        public bool IsSuccess
 83        {
 84            get { return m_isSuccess; }
 85        }

 86
 87        public bool RegisterHotKey()
 88        {
 89            m_isRegistered = true;
 90            m_id = HotKey.GlobalAddAtom(Guid.NewGuid().ToString());
 91            if (!(m_isSuccess = HotKey.RegisterHotKey(m_hWnd, m_id, m_keyModifiers, m_vk)))
 92            {
 93                OnRegisterFailedEvent();
 94            }

 95            return m_isSuccess;
 96        }

 97
 98        public event EventHandler RegisterFailedEvent;
 99
100        private void OnRegisterFailedEvent()
101        {
102            if (RegisterFailedEvent != null)
103            {
104                RegisterFailedEvent(this, EventArgs.Empty);
105            }

106        }

107
108        public void UnregisterHotKey()
109        {
110            HotKey.UnregisterHotKey(m_hWnd, m_id);
111            HotKey.GlobalDeleteAtom(m_id);
112        }

113        public event EventHandler HotKeyEvent;
114
115        public void OnHotKeyEvent()
116        {
117            if (HotKeyEvent != null)
118            {
119                HotKeyEvent(this, EventArgs.Empty);
120            }

121        }

122
123        #endregion

124    }

热键我们往往并不是注册一个这时我们就需要个集合来保存这些热键。
Code
 1    public class HotKeyList : List<IHotKey>
 2    {
 3        public new void Add(IHotKey item)
 4        {
 5            if (!this.Contains(item))
 6            {
 7                base.Add(item);
 8            }

 9        }

10
11        public new bool Remove(IHotKey item)
12        {
13            item.UnregisterHotKey();
14            return base.Remove(item);
15        }

16
17        public void RegisterAllHotKey()
18        {
19
20            foreach (IHotKey item in this)
21            {
22                if (!item.IsRegistered || (item.IsRegistered && !item.IsSuccess))
23                {
24                    item.RegisterHotKey();
25                }

26            }

27        }

28
29        public void OnHotKeyEvent(int hotKeyID)
30        {
31            foreach (IHotKey item in this)
32            {
33                if (item.ID == hotKeyID)
34                {
35                    item.OnHotKeyEvent();
36                }

37            }

38        }

39
40        public void UnregisterAllHotKey()
41        {
42            foreach (IHotKey item in this)
43            {
44                if (item.IsRegistered && item.IsSuccess)
45                {
46                    item.UnregisterHotKey();
47                }

48            }

49        }

50    }

最后,热键虽然注册了,但我们没有捕获这些热键被激发的消息,这时有两种选择,一种是使用消息筛选器,这种会降低winform的处理消息的效率;另一种是重写我winform的WndProc方法。
第一种方式:
Code
 1    public class HotKeyMessageFilter : IMessageFilter
 2    {
 3        private HotKeyMessageFilter()
 4        {
 5            m_hotKeyList = new HotKeyList();
 6        }

 7
 8        private readonly static HotKeyMessageFilter m_hotKeyMessageFilter = new HotKeyMessageFilter();
 9
10        public static HotKeyMessageFilter GetInstance()
11        {
12            return m_hotKeyMessageFilter;
13        }

14
15        private HotKeyList m_hotKeyList;
16
17        public HotKeyList HotKeyList
18        {
19            get { return m_hotKeyList; }
20        }

21
22        public void Add(IHotKey item)
23        {
24            m_hotKeyList.Add(item);
25        }

26
27        public void AddRange(IEnumerable<IHotKey> collection)
28        {
29            m_hotKeyList.AddRange(collection);
30        }

31
32        public void Remove(IHotKey item)
33        {
34            m_hotKeyList.Remove(item);
35        }

36
37        public void RegisterHotKeyMessageFilter()
38        {
39            Application.AddMessageFilter(this);
40        }

41
42        public void UnregisterHotKeyMessageFilter()
43        {
44            Application.RemoveMessageFilter(this);
45        }

46
47        public void RegisterAllHotKey()
48        {
49            m_hotKeyList.RegisterAllHotKey();
50        }

51
52        public void UnregisterHotKey()
53        {
54            m_hotKeyList.UnregisterAllHotKey();
55        }

56
57        IMessageFilter 成员#region IMessageFilter 成员
58
59        public bool PreFilterMessage(ref Message m)
60        {
61            switch ((WindowsMessage)m.Msg)
62            {
63                case WindowsMessage.WM_DESTROY:
64                    m_hotKeyList.UnregisterAllHotKey();
65                    UnregisterHotKeyMessageFilter();
66                    break;
67                case WindowsMessage.WM_HOTKEY:
68                    m_hotKeyList.OnHotKeyEvent(m.WParam.ToInt32());
69                    break;
70                default:
71                    break;
72            }

73            return false;
74        }

75
76        #endregion

77    }

下面就是使用方法:
Code
 1        private HotKey m_hotKey;
 2
 3        private void RegisterHotKey()
 4        {
 5            m_hotKey = new HotKey(this.Handle, KeyModifiers.Ctrl, Keys.K);
 6            m_hotKey.RegisterFailedEvent += new EventHandler(m_hotKey_RegisterFailedEvent);
 7            m_hotKey.HotKeyEvent += new HotKeyEventHandler(m_hotKey_HotKeyEvent);
 8            HotKeyMessageFilter hotKeyMessageFilter = HotKeyMessageFilter.GetInstance();
 9            hotKeyMessageFilter.RegisterHotKeyMessageFilter();
10            hotKeyMessageFilter.Add(m_hotKey);
11            hotKeyMessageFilter.RegisterAllHotKey();
12        }

13
14        private void m_hotKey_HotKeyEvent()
15        {
16            //操作
17        }

18
19        private void m_hotKey_RegisterFailedEvent(object sender, EventArgs e)
20        {
21            MessageBox.Show("热键注册失败");
22        }

第二种方法:
Code
 1        private HotKeyList m_hotKeyList = new HotKeyList();
 2        private HotKey m_hotKey;
 3
 4        private void RegisterHotKey()
 5        {
 6            m_hotKey = new HotKey(this.Handle, KeyModifiers.Ctrl, Keys.K);
 7            m_hotKey.RegisterFailedEvent += new EventHandler(m_hotKey_RegisterFailedEvent);
 8            m_hotKey.HotKeyEvent += new HotKeyEventHandler(m_hotKey_HotKeyEvent);
 9            m_hotKeyList.Add(m_hotKey);
10            m_hotKeyList.RegisterAllHotKey();
11        }

12
13
14        private void m_hotKey_HotKeyEvent()
15        {
16            //操作
17        }

18
19        private void m_hotKey_RegisterFailedEvent(object sender, EventArgs e)
20        {
21            MessageBox.Show("热键注册失败");
22        }

23
24        protected override void WndProc(ref Message m)
25        {
26            switch ((WindowsMessage)m.Msg)
27            {
28                case WindowsMessage.WM_DESTROY:
29                    m_hotKeyList.UnregisterAllHotKey();
30                    break;
31                case WindowsMessage.WM_HOTKEY:
32                    m_hotKeyList.OnHotKeyEvent(m.WParam.ToInt32());
33                    break;
34                case WindowsMessage.WM_CREATE:
35                    RegisterHotKey();
36                    break;
37                default:
38                    break;
39            }

40            base.WndProc(ref m);
41        }

源代码下载:http://www.rayfile.com/zh-cn/files/327886c0-9b56-11de-a89d-0014221b798a/27b1b83e/
网易博客:http://blog.163.com/haibo__song/
posted @ 2009-09-06 22:29  flashpast  阅读(633)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3