取消某些Windows键盘快捷键

时间:2012-11-10 17:01:44

标签: c# wpf keyboard

我试图压制一些Windows键盘快捷键(例如 ALT + TAB LWIN / RWIN ALT + F4 )所以我的应用程序可以处理它们的其他方式(模拟外部机器上的按键)。

根据其他SO问题和答案,这应该有效:

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

问题是,它不起作用。每当我点击 LWIN / RWIN 时,仍会弹出“开始”菜单,我想要禁止它,这样我的应用程序就可以单独使用它。在上面的代码片段中,this指的是WPF窗口,该窗口在测试时被关注。 (一旦Window有焦点,它显然只能抑制动作。)

有什么方法可以实现我想要实现的目标?

谢谢,

〜Tgys

1 个答案:

答案 0 :(得分:2)

您可以挂钩所有键盘甚至鼠标事件来检测输入源。换句话说,如果您使用下面链接中提到的 Global Hook ,您可以捕获系统事件并像正常事件一样处理它们或抑制它们。

您应该查看此 CodeProject 文章,Processing Global Mouse and Keyboard Hooks in C#

MSDN Reference

  

全局挂钩监视与调用线程在同一桌面中的所有线程的消息。 特定于线程的挂钩仅监视单个线程的消息。可以在与调用线程相同的桌面中的任何应用程序的上下文中调用全局钩子过程,因此该过程必须位于单独的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#