1

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

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

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

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

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

谢谢,

~Tgys

4

1 回答 1

2

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

您应该看看这篇CodeProject文章,在 C# 中处理全局鼠标和键盘挂钩

MSDN 参考

全局挂钩监视与调用线程相同的桌面中的所有线程的消息。特定于线程的挂钩仅监视单个线程的消息。全局挂钩过程可以在与调用线程相同的桌面中的任何应用程序的上下文中调用,因此该过程必须位于单独的 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. 来自 C# 的低级 Windows API 挂钩以阻止不需要的击键
  2. 在 Win App C# 中禁用特殊键
于 2012-11-10T17:33:48.620 回答