2012-11-10 206 views
1

我試圖壓制某些Windows鍵盤快捷鍵(如ALT + TAB /RWINALT + F4 ),所以我的應用程序可以處理它們elsehow(模擬外部機器上的按鍵)。禁止某些Windows鍵盤快捷鍵

根據其他SO問題和答案,這是這樣運作的:

 this.PreviewKeyDown += (s, e) => { 
      if (e.Key == Key.LWin || e.Key == Key.RWin) 
       e.Handled = true; 
     }; 

問題是,這是行不通的。每當我點擊LWIN/RWIN,開始菜單仍然彈出,我想壓制,所以我的應用程序本身可以使用它。在上面的代碼片段中,this引用了一個WPF窗口,它在測試時正在被聚焦。 (它顯然應該只在Window有焦點時纔會壓制動作。)

有什麼辦法來達到我想達到的目的?

感謝,

〜Tgys

回答

2

可以掛鉤鍵盤所有甚至鼠標事件,以檢測輸入源。換句話說,如果您使用下面鏈接中提到的Global Hook,您可以捕獲系統事件並將其作爲正常事件進行處理或將其壓制。

你應該看看這個CodeProject上文章,Processing Global Mouse and Keyboard Hooks in C#

MSDN Reference

一個全局鉤子監視在同一桌面與調用線程的所有線程的消息。 A 線程專用掛鉤僅監視單個線程的消息。全局鉤子過程可以在與調用線程相同的桌面中的任何應用程序的上下文中調用,因此過程必須位於單獨的DLL模塊中。線程特定的鉤子過程僅在關聯線程的上下文中調用。

C#代碼:

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

public partial class MainWindow : Window 
{ 
    // Structure contain information about low-level keyboard input event 
    [StructLayout(LayoutKind.Sequential)] 
    private struct KBDLLHOOKSTRUCT 
    { 
     public Keys key; 
     public int scanCode; 
     public int flags; 
     public int time; 
     public IntPtr extra; 
    } 

    //System level functions to be used for hook and unhook keyboard input 
    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId); 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern bool UnhookWindowsHookEx(IntPtr hook); 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp); 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr GetModuleHandle(string name); 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    private static extern short GetAsyncKeyState(Keys key); 

    //Declaring Global objects 
    private IntPtr ptrHook; 
    private LowLevelKeyboardProc objKeyboardProcess; 

    private IntPtr CaptureKey(int nCode, IntPtr wp, IntPtr lp) 
    { 
     if (nCode >= 0) 
     { 
      KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT)); 
      if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin) // Disabling Windows keys 
      { 
       return (IntPtr)1; 
      } 
     } 
     return CallNextHookEx(ptrHook, nCode, wp, lp); 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     //Get Current Module 
     ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule; 
     //Assign callback function each time keyboard process 
     objKeyboardProcess = new LowLevelKeyboardProc(CaptureKey); 
     //Setting Hook of Keyboard Process for current module 
     ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0); 
    } 
} 

其他好的參考資料:

  1. Low-level Windows API hooks from C# to stop unwanted keystrokes
  2. Disable Special Keys in Win App C#
+1

你提到的第一篇文章,沒有w有一個[CodePlex站點](http://globalmousekeyhook.codeplex.com/),您可以在其中下載該庫。 –

+1

感謝分享這些信息,真的很有用。 –