【问题】
一个C#窗体程序,想要实现,不论程序是否获得当前焦点,都要能够捕获到全局的某个设置好的快捷键。
比如按Ctrl+Alt+Shift+M,然后程序就可以捕获到。
【解决过程】
1.从这里:c#全局热键+获取窗口句柄,得知有个RegisterHotKey的。
2.然后就找到这里:Set global hotkeys using C#,参考其代码,去添加了如下代码:
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
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
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#中如何注册/获得/捕获全局热键/快捷键