编程取消c#中的键盘命令

本文关键字:键盘 命令 取消 编程 | 更新日期: 2023-09-27 18:14:33

我正试图用VSTO写一个钩子到MS Excel,我真的很接近我需要的,但我有一个小问题。

我使用了低级的WINAPI调用来获取键盘事件并检查击键(这工作得很好)。

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook, KeyCaptureDelegate lpfn, IntPtr hMod, uint dwThreadId);
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
    private static IntPtr KeyCaptureCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0)
        {
            int pointerCode = Marshal.ReadInt32(lParam);
            bool result = false;
            if (wParam == (IntPtr)WM_KEYDOWN)
            {
                if (KeyDown != null)
                {
                    result = KeyDown(pointerCode);
                }
            }
            //if (result)
                //return IntPtr.Zero;
        }
        return CallNextHookEx(_keyCaptureHook, nCode, wParam, lParam);
    }

一切都是连接和工作良好(使用SetWindowsHookEx),我的代码通过KeyDown调用没有任何问题。唯一的问题是,我试图覆盖Excel中的默认命令,即Ctrl+Shift+1。这会导致默认功能发生。

在我的代码中,result返回是否应该重写行为(即使用我的新行为,而不是默认行为)。我曾希望,也许,返回ptr。Zero会把钥匙从泵上拆下来,但这似乎没有任何作用。

是否有办法阻止其他(默认)行为?我想通过取消/处理事件(就像我们在WinForms/WPF中所做的那样),应该有一些方法可以防止击键进一步迁移到Excel中。任何想法吗?

编程取消c#中的键盘命令

所以,我需要做一些小的改变:

    private delegate IntPtr KeyCaptureDelegate(int nCode, IntPtr wParam, IntPtr lParam);

变成:

    private delegate int KeyCaptureDelegate(int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

变成:

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

允许我将其重写为:

    private static int KeyCaptureCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0)
        {
            int pointerCode = Marshal.ReadInt32(lParam);
            bool result = false;
            if (wParam == (IntPtr)WM_KEYDOWN)
            {
                if (KeyDown != null)
                {
                    result = KeyDown(pointerCode);
                }
            }
            if (result)
            {
                return 1;
            }
        }
        return CallNextHookEx(_keyCaptureHook, nCode, wParam, lParam);
    }