C#中使用全局热键进行密钥捕获

我有一个在后台运行的应用程序,就像我可以将我的应用程序保存在系统托盘中。如果它仍然在系统托盘上,我的应用程序将完成它的工作。 每当用户按F10或F9时,将完成一些工作。 我试过这个:

public partial class Form1 : Form { public int a = 1; [DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc); [DllImport("user32.dll")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); [DllImport("User32.dll")] private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey); [DllImport("User32.dll")] private static extern short GetAsyncKeyState(System.Int32 vKey); const int MYACTION_HOTKEY_ID = 1; public Form1() { InitializeComponent(); RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9); RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int)Keys.F10); this.ShowInTaskbar = false; } protected override void WndProc(ref Message m) { if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F9) == -32767)) { if ((a % 2) != 0) { a++; MessageBox.Show(a.ToString()+"not equal F9"); label1.Text = "not equal F9"; } if ((a % 2) == 0) { a++; MessageBox.Show(a.ToString()+"equal F9"); label1.Text = " equal F9"; } } else if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F10) == -32767)) { if ((a % 2) != 0) { a++; MessageBox.Show(a.ToString() + "not equal F10"); label1.Text = "not equal F10"; } if ((a % 2) == 0) { a++; MessageBox.Show(a.ToString() + "equal F10"); label1.Text = " equal F10"; } } base.WndProc(ref m); } } 

因为我使用设置“this.ShowInTaskbar = false”这一行它不起作用。但如果我没有设置它它工作正常。对于我的应用程序我必须使用这一行。我怎么能解决这个????

您需要通过RegisterHotKey()类的本机函数调用来订阅操作系统发送的某些消息。 当你调用这个函数你通过指定窗口的Handle告诉操作系统发送消息的窗口,这可以被认为是一个地址。 当您设置ShowInTaskbar = false ,句柄会更改,因此操作系统将不知道从何处与您联系。

看到第一个问题:

 RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9); 

要解决您的问题,您可以创建一个派生自NativeWindow的类,“ 提供窗口句柄和窗口过程的低级封装。 ”并从该类中(或至少根据您的实现使用该类的句柄),使用永不改变的句柄注册热键。

 public sealed class HotkeyManager : NativeWindow, IDisposable { public HotkeyManager() { CreateHandle(new CreateParams()); } protected override void WndProc(ref Message m) { if (m.Msg == Constants.WM_HOTKEY) { //handle hotkey message } base.WndProc(ref m); } public void Dispose() { DestroyHandle(); } } 

据我所知,只要更改“ShowInTaskbar”状态,就需要重新注册热键。

其他人有类似的问题; 看到这个post 。