热键注册
要做热键首先,要做的就是定义一些枚举来表示一些常量。

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/
1
[Flags]2
public enum KeyModifiers3

{4
None = 0,5
Alt,6
Ctrl,7
Shift,8
Windows9
}10

11
public enum WindowsMessage12

{13
WM_CREATE = 0X1,14
WM_DESTROY = 0X2,15
WM_HOTKEY = 0X312,16
}然后,要做的就是建立一个HotKey类,这个用来保存热键的键值,热键被激活是所触发的事件,并负责注册热键,撤销热键的操作。
1
public interface IHotKey2

{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 : IHotKey17

{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 HWnd50

{51

get
{ return m_hWnd; }52
}53
private UInt32 m_id;54

55
public UInt32 ID56

{57

get
{ return m_id; }58
}59

60
private KeyModifiers m_keyModifiers;61

62
public KeyModifiers KeyModifiers63

{64

get
{ return m_keyModifiers; }65
}66
private Keys m_vk;67

68
public Keys Vk69

{70

get
{ return m_vk; }71
}72

73
private bool m_isRegistered;74

75
public bool IsRegistered76

{77

get
{ return m_isRegistered; }78
}79

80
private bool m_isSuccess;81

82
public bool IsSuccess83

{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
#endregion124
}热键我们往往并不是注册一个这时我们就需要个集合来保存这些热键。
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方法。
第一种方式:
1
public class HotKeyMessageFilter : IMessageFilter2

{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 HotKeyList18

{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
#endregion77
}下面就是使用方法:
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
}第二种方法:
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/
浙公网安备 33010602011771号