最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】C#中如何注册/获得/捕获全局热键/快捷键

C# crifan 3776浏览 0评论

【问题】

一个C#窗体程序,想要实现,不论程序是否获得当前焦点,都要能够捕获到全局的某个设置好的快捷键。

比如按Ctrl+Alt+Shift+M,然后程序就可以捕获到。

【解决过程】

1.从这里:c#全局热键+获取窗口句柄,得知有个RegisterHotKey的。

2.然后就找到这里:Set global hotkeys using C#,参考其代码,去添加了如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace downloadSongtasteMusic
{
 
    public sealed class KeyboardHook : IDisposable
    {
        // Registers a hot key with Windows.
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
        // Unregisters the hot key with Windows.
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
 
        /// <summary>
        /// Represents the window that is used internally to get the messages.
        /// </summary>
        private class Window : NativeWindow, IDisposable
        {
            private static int WM_HOTKEY = 0x0312;
 
            public Window()
            {
                // create the handle for the window.
                this.CreateHandle(new CreateParams());
            }
 
            /// <summary>
            /// Overridden to get the notifications.
            /// </summary>
            /// <param name="m"></param>
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
 
                // check if we got a hot key pressed.
                if (m.Msg == WM_HOTKEY)
                {
                    // get the keys.
                    Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
                    ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF);
 
                    // invoke the event to notify the parent.
                    if (KeyPressed != null)
                        KeyPressed(this, new KeyPressedEventArgs(modifier, key));
                }
            }
 
            public event EventHandler<KeyPressedEventArgs> KeyPressed;
 
            #region IDisposable Members
 
            public void Dispose()
            {
                this.DestroyHandle();
            }
 
            #endregion
        }
 
        private Window _window = new Window();
        private int _currentId;
 
        public KeyboardHook()
        {
            // register the event of the inner native window.
            _window.KeyPressed += delegate(object sender, KeyPressedEventArgs args)
            {
                if (KeyPressed != null)
                    KeyPressed(this, args);
            };
        }
 
        /// <summary>
        /// Registers a hot key in the system.
        /// </summary>
        /// <param name="modifier">The modifiers that are associated with the hot key.</param>
        /// <param name="key">The key itself that is associated with the hot key.</param>
        public void RegisterHotKey(ModifierKeys modifier, Keys key)
        {
            // increment the counter.
            _currentId = _currentId + 1;
 
            // register the hot key.
            if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key))
                throw new InvalidOperationException("Couldn't register the hot key.");
        }
 
        /// <summary>
        /// A hot key has been pressed.
        /// </summary>
        public event EventHandler<KeyPressedEventArgs> KeyPressed;
 
        #region IDisposable Members
 
        public void Dispose()
        {
            // unregister all the registered hot keys.
            for (int i = _currentId; i > 0; i--)
            {
                UnregisterHotKey(_window.Handle, i);
            }
 
            // dispose the inner native window.
            _window.Dispose();
        }
 
        #endregion
    }
 
    /// <summary>
    /// Event Args for the event that is fired after the hot key has been pressed.
    /// </summary>
    public class KeyPressedEventArgs : EventArgs
    {
        private ModifierKeys _modifier;
        private Keys _key;
 
        internal KeyPressedEventArgs(ModifierKeys modifier, Keys key)
        {
            _modifier = modifier;
            _key = key;
        }
 
        public ModifierKeys Modifier
        {
            get { return _modifier; }
        }
 
        public Keys Key
        {
            get { return _key; }
        }
    }
 
    /// <summary>
    /// The enumeration of possible modifiers.
    /// </summary>
    [Flags]
    public enum ModifierKeys : uint
    {
        Alt = 1,
        Control = 2,
        Shift = 4,
        Win = 8
    }
 
    public partial class frmDownloadSonstasteMusic : Form
    {
        KeyboardHook hook = new KeyboardHook();
 
        public frmDownloadSonstasteMusic()
        {
            InitializeComponent();
 
            // register the event that is fired after the key press.
            hook.KeyPressed += new EventHandler<KeyPressedEventArgs>(hook_KeyPressed);
            // register the control + alt + F12 combination as hot key.
            hook.RegisterHotKey(ModifierKeys.Control | ModifierKeys.Alt, Keys.F12);
        }
 
        private void frmDownloadSonstasteMusic_Load(object sender, EventArgs e)
        {
 
        }
 
        private void frmDownloadSonstasteMusic_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                Hide();  // 隐藏窗体
                nfiSystem.Visible = true// 系统托盘图标可见
            }
 
        }
 
        private void nfiSystem_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.nfiSystem.Visible = false;
        }
    }
}

结果编译出错:

D:\xxx\downloadSongtasteMusic\frmDownloadSonstasteMusic.cs(15,10): error CS0246: The type or namespace name ‘DllImport’ could not be found (are you missing a using directive or an assembly reference?)

然后就先去解决DllImport的问题。

3.然后解决了上述DllImport的问题:

【已解决】error CS0246: The type or namespace name ‘DllImport’ could not be found (are you missing a using directive or an assembly reference?)

4.接着编译又出现了错误,是关于上述代码中的ModifierKeys,折腾了一下,发现好像是和系统自带的ModifierKeys有冲突,所以自己将其改为ModifierKeys_e,然后才解决问题。

其中,还由于把上面一堆代码,拷贝到当前那个窗体对应的cs文件:frmDownloadSonstasteMusic.cs中,无法工作,然后把这代码都放到另外的一个文件Program.cs,然后才可以正常使用,窗体才可以正常显示。

然后运行了一下,同时按Ctrl+Alt+F12,就可以捕获,并在texBox中显示出来了。

 

最后工作的代码是:

(1)Program.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
namespace downloadSongtasteMusic
{
 
    public sealed class KeyboardHook : IDisposable
    {
        // Registers a hot key with Windows.
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
        // Unregisters the hot key with Windows.
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
 
        /// <summary>
        /// Represents the window that is used internally to get the messages.
        /// </summary>
        private class Window : NativeWindow, IDisposable
        {
            private static int WM_HOTKEY = 0x0312;
 
            public Window()
            {
                // create the handle for the window.
                this.CreateHandle(new CreateParams());
            }
 
            /// <summary>
            /// Overridden to get the notifications.
            /// </summary>
            /// <param name="m"></param>
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
 
                // check if we got a hot key pressed.
                if (m.Msg == WM_HOTKEY)
                {
                    // get the keys.
                    Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
                    ModifierKeys_e modifier = (ModifierKeys_e)((int)m.LParam & 0xFFFF);
 
                    // invoke the event to notify the parent.
                    if (KeyPressed != null)
                        KeyPressed(this, new KeyPressedEventArgs(modifier, key));
                }
            }
 
            public event EventHandler<KeyPressedEventArgs> KeyPressed;
 
            #region IDisposable Members
 
            public void Dispose()
            {
                this.DestroyHandle();
            }
 
            #endregion
        }
 
        private Window _window = new Window();
        private int _currentId;
 
        public KeyboardHook()
        {
            // register the event of the inner native window.
            _window.KeyPressed += delegate(object sender, KeyPressedEventArgs args)
            {
                if (KeyPressed != null)
                    KeyPressed(this, args);
            };
        }
 
        /// <summary>
        /// Registers a hot key in the system.
        /// </summary>
        /// <param name="modifier">The modifiers that are associated with the hot key.</param>
        /// <param name="key">The key itself that is associated with the hot key.</param>
        public void RegisterHotKey(ModifierKeys_e modifier, Keys key)
        {
            // increment the counter.
            _currentId = _currentId + 1;
 
            // register the hot key.
            if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key))
                throw new InvalidOperationException("Couldn't register the hot key.");
        }
 
        /// <summary>
        /// A hot key has been pressed.
        /// </summary>
        public event EventHandler<KeyPressedEventArgs> KeyPressed;
 
        #region IDisposable Members
 
        public void Dispose()
        {
            // unregister all the registered hot keys.
            for (int i = _currentId; i > 0; i--)
            {
                UnregisterHotKey(_window.Handle, i);
            }
 
            // dispose the inner native window.
            _window.Dispose();
        }
 
        #endregion
    }
 
    /// <summary>
    /// Event Args for the event that is fired after the hot key has been pressed.
    /// </summary>
    public class KeyPressedEventArgs : EventArgs
    {
        private ModifierKeys_e _modifier;
        private Keys _key;
 
        internal KeyPressedEventArgs(ModifierKeys_e modifier, Keys key)
        {
            _modifier = modifier;
            _key = key;
        }
 
        public ModifierKeys_e Modifier
        {
            get { return _modifier; }
        }
 
        public Keys Key
        {
            get { return _key; }
        }
    }
 
    /// <summary>
    /// The enumeration of possible modifiers.
    /// </summary>
    [Flags]
    public enum ModifierKeys_e : uint
    {
        Alt = 1,
        Control = 2,
        Shift = 4,
        Win = 8
    }
 
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmDownloadSonstasteMusic());
        }
    }
}

(2)frmDownloadSonstasteMusic.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace downloadSongtasteMusic
{
 
 
    public partial class frmDownloadSonstasteMusic : Form
    {
        KeyboardHook hook = new KeyboardHook();
 
        public frmDownloadSonstasteMusic()
        {
            InitializeComponent();
 
            // register the event that is fired after the key press.
            hook.KeyPressed += new EventHandler<KeyPressedEventArgs>(hook_KeyPressed);
            // register the control + alt + F12 combination as hot key.
            //hook.RegisterHotKey(ModifierKeys.Control | ModifierKeys.Alt, Keys.F12);
            hook.RegisterHotKey(ModifierKeys_e.Control | ModifierKeys_e.Alt, Keys.F12);
        }
         
        void hook_KeyPressed(object sender, KeyPressedEventArgs e)
        {
            // show the keys pressed in a label.
            rtbInfo.Text = e.Modifier.ToString() + " + " + e.Key.ToString();
        }
 
        private void frmDownloadSonstasteMusic_Load(object sender, EventArgs e)
        {
 
        }
 
        private void frmDownloadSonstasteMusic_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                Hide();  // 隐藏窗体
                nfiSystem.Visible = true// 系统托盘图标可见
            }
 
        }
 
        private void nfiSystem_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.nfiSystem.Visible = false;
        }
    }
}

转载请注明:在路上 » 【已解决】C#中如何注册/获得/捕获全局热键/快捷键

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.318 seconds, using 22.13MB memory