2013-03-15 88 views
4

我有一個在後臺運行的應用程序,就像我可以將我的應用程序保留在系統托盤中一樣。如果它保留在系統托盤中,我的應用程序將執行它的工作。每當用戶按下F10或F9,一些作品就會完成。我想這:在C#中使用全局熱鍵捕獲密鑰#

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 =假」這一行,如果我不設置此它的工作原理fine.For我的應用程序不work.but我必須使用此line.How我可以解決這個問題?

回答

7

您需要訂閱某些操作系統通過本機函數調用發送的消息,如RegisterHotKey()。當你調用這個函數時,通過指定窗口的Handle告訴操作系統哪個窗口發送消息,這可以被認爲是一個地址。當您設置ShowInTaskbar = false時,句柄會發生變化,因此操作系統無法知道到達哪裏。

見第一arugment:

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(); 
    } 
} 
1

據我所知,無論何時更改「ShowInTaskbar」狀態,都需要重新註冊熱鍵。

其他人也有類似的問題;請參閱this thread