2012-11-10 161 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

感谢分享这些信息,真的很有用。 –