【问题】
一个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的问题:
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#中如何注册/获得/捕获全局热键/快捷键