简体   繁体   English

禁止某些 Windows 键盘快捷键

[英]Suppress certain Windows keyboard shortcuts

I'm attempting to suppress some Windows keyboard shortcuts (eg ALT + TAB , LWIN / RWIN , ALT + F4 ) so my application can handle them elsehow (simulating keypresses on an external machine).我试图抑制一些 Windows 键盘快捷键(例如ALT + TABLWIN / RWINALT + F4 ),以便我的应用程序可以以其他方式处理它们(模拟外部机器上的按键)。

According to other SO questions and answers this is supposed to work:根据其他SO问题和答案,这应该有效:

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

Problem is, it doesn't work.问题是,它不起作用。 Whenever I hit LWIN / RWIN , the Start menu still pops up which I want to suppress so my application alone can use it.每当我点击LWIN / RWIN 时,开始菜单仍然会弹出,我想取消它,以便我的应用程序可以单独使用它。 In the above snippet, this refers to a WPF Window which was being focussed while testing this.在上面的代码片段中, this指的是在测试时正在聚焦的 WPF 窗口。 (It should obviously only suppress the action once Window has focus.) (显然,一旦 Window 获得焦点,它应该只抑制动作。)

Any way to achieve what I'd like to achieve?有什么方法可以实现我想要实现的目标吗?

Thanks,谢谢,

~Tgys ~Tgys

You can Hook all the Keyboard and even Mouse events to detect the source of input.你可以钩住所有的键盘甚至鼠标事件来检测输入源。 In other words, if you use the Global Hook as mentioned in the link below, you can capture system events and either process them like normal events or suppress them.换句话说,如果您使用下面链接中提到的全局钩子,您可以捕获系统事件并像正常事件一样处理它们或抑制它们。

You should have a look at this CodeProject article, Processing Global Mouse and Keyboard Hooks in C#您应该看看这篇CodeProject文章, 在 C# 中处理全局鼠标和键盘挂钩

MSDN Reference : MSDN参考

A global hook monitors messages for all threads in the same desktop as the calling thread.全局挂钩监视与调​​用线程位于同一桌面上的所有线程的消息。 A thread-specific hook monitors messages for only an individual thread.特定线程的挂钩仅监视单个线程的消息。 A global hook procedure can be called in the context of any application in the same desktop as the calling thread, so the procedure must be in a separate DLL module.全局挂钩过程可以在与调用线程位于同一桌面的任何应用程序的上下文中调用,因此该过程必须位于单独的 DLL 模块中。 A thread-specific hook procedure is called only in the context of the associated thread.线程特定的挂钩过程仅在关联线程的上下文中调用。

C# Code: 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); 
    }
}

Other Good References:其他好的参考资料:

  1. Low-level Windows API hooks from C# to stop unwanted keystrokes 来自 C# 的低级 Windows API 挂钩以阻止不需要的击键
  2. Disable Special Keys in Win App C# 在 Win App C# 中禁用特殊键

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM