2010-08-25 29 views
5

如何创建使用键盘快捷键执行操作的应用程序(应用程序必须是不可见的)。例如,当用户按Ctrl + Alt + W时显示MessageBox。如何在我的应用程序中调用函数的窗口中创建键盘快捷键?

+0

您需要包含更多关于您正在尝试完成的信息。技术(winforms,wpf等)。另外你的问题似乎暗示它应该是试图挂钩键盘的后台任务,但它不明确。 – 2010-08-25 17:50:33

+1

是的,我想让它在背景上工作。和Winforms – 2010-08-25 18:02:27

回答

9

一个解决办法是使用互操作和使用Win32 API RegisterHotKey。这是一个快速而肮脏的例子,我只是把它放在一起,所以它没有得到很好的测试,我不确定没有未被发现的副作用,但它应该起作用。

首先这里是一个简单HotKeyManager这需要照顾的基本互操作的,提供了一个隐藏的窗口来处理本地的Windows消息(WM_HOTKEY),它被翻译成.NET事件HotKeyPressed

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

    public class HotKeyManager 
    { 
    public static event EventHandler<HotKeyEventArgs> HotKeyPressed; 

    public static int RegisterHotKey(Keys key, KeyModifiers modifiers) 
    { 
     int id = System.Threading.Interlocked.Increment(ref _id); 
     RegisterHotKey(_wnd.Handle, id, (uint)modifiers, (uint)key); 
     return id; 
    } 

    public static bool UnregisterHotKey(int id) 
    { 
     return UnregisterHotKey(_wnd.Handle, id); 
    } 

    protected static void OnHotKeyPressed(HotKeyEventArgs e) 
    { 
     if (HotKeyManager.HotKeyPressed != null) 
     { 
     HotKeyManager.HotKeyPressed(null, e); 
     } 
    } 

    private static MessageWindow _wnd = new MessageWindow(); 

    private class MessageWindow : Form 
    { 
     protected override void WndProc(ref Message m) 
     { 
     if (m.Msg == WM_HOTKEY) 
     { 
      HotKeyEventArgs e = new HotKeyEventArgs(m.LParam); 
      HotKeyManager.OnHotKeyPressed(e); 
     } 

     base.WndProc(ref m); 
     } 

     private const int WM_HOTKEY = 0x312; 
    } 

    [DllImport("user32")] 
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); 

    [DllImport("user32")] 
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id); 

    private static int _id = 0; 
    } 


    public class HotKeyEventArgs : EventArgs 
    { 
    public readonly Keys Key; 
    public readonly KeyModifiers Modifiers; 

    public HotKeyEventArgs(Keys key, KeyModifiers modifiers) 
    { 
     this.Key = key; 
     this.Modifiers = modifiers; 
    } 

    public HotKeyEventArgs(IntPtr hotKeyParam) 
    { 
     uint param = (uint)hotKeyParam.ToInt64(); 
     Key = (Keys)((param & 0xffff0000) >> 16); 
     Modifiers = (KeyModifiers)(param & 0x0000ffff); 
    } 
    } 

    [Flags] 
    public enum KeyModifiers 
    { 
    Alt = 1, 
    Control = 2, 
    Shift = 4, 
    Windows = 8, 
    NoRepeat = 0x4000 
    } 

下面显示一个简单的Windows窗体应用程序,它将隐藏主窗体并响应热键事件。我没有处理关闭应用程序和取消注册热键,您可以处理该问题。

using System; 
using System.Windows.Forms; 

namespace HotKeyManager 
{ 
    public partial class Form1 : Form 
    { 
    public Form1() 
    { 
     InitializeComponent(); 
     HotKeyManager.RegisterHotKey(Keys.A, KeyModifiers.Alt); 
     HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(HotKeyManager_HotKeyPressed);  
    } 

    void HotKeyManager_HotKeyPressed(object sender, HotKeyEventArgs e) 
    { 
     MessageBox.Show("Hello"); 
    } 

    protected override void SetVisibleCore(bool value) 
    {  
     // Quick and dirty to keep the main window invisible  
     base.SetVisibleCore(false); 
    } 
    } 
} 
-4

添加到您的窗体的KeyPress事件:

if(e.KeyCode == (char)Keys.W && e.Modifiers == Keys.Control && e.Modifiers = Keys.Alt) 
{ 
    MessageBox.Show("I think this is a homework and that you should study instead of asking for an already cooked up answer on programming websites","Cheater"); 
} 
+0

这是错误的答案。你做了功课吗? – 2010-08-25 18:37:22

+0

看起来我错过了“应用程序必须是隐形的”部分。 – Wildhorn 2010-08-25 18:38:12

相关问题