Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用C语言编程取消键盘命令#_C#_Excel_Winapi_Vsto_Keyboard Shortcuts - Fatal编程技术网

C# 用C语言编程取消键盘命令#

C# 用C语言编程取消键盘命令#,c#,excel,winapi,vsto,keyboard-shortcuts,C#,Excel,Winapi,Vsto,Keyboard Shortcuts,我正在尝试使用VSTO将一个钩子写入MS Excel,我非常接近我所需要的,但我有一个小问题 我使用了低级WINAPI调用来获取键盘事件并检查按键笔划(效果很好) 一切都连接好了,工作正常(使用SetWindowsHookEx),我的代码通过KeyDown调用,没有任何问题。唯一的问题是我试图覆盖Excel中的默认命令,即Ctrl+Shift+1。这将导致出现默认功能 在我的代码中,result返回是否应该覆盖行为(即使用我的新行为,而不是默认行为)。也许我曾希望返回IntPtr.Zero会断开

我正在尝试使用VSTO将一个钩子写入MS Excel,我非常接近我所需要的,但我有一个小问题

我使用了低级WINAPI调用来获取键盘事件并检查按键笔划(效果很好)

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

在我的代码中,result返回是否应该覆盖行为(即使用我的新行为,而不是默认行为)。也许我曾希望返回IntPtr.Zero会断开并从泵中取出钥匙,但这似乎没有任何作用


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

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

    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 int CallNextHookEx(IntPtr hhk, 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 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);
    }

我记不清到底该返回什么,但当你想自己吃按键的时候,你不应该调用
CallNextHookEx
。我刚刚想好了。哦。必须在WINAPI调用中将IntPtr(在示例源代码中)转换为int,然后在返回时将IntPtr.Zero更改为1。将发布一个示例。您可以将返回类型保留为
IntPtr
本身,并返回
(IntPtr)1
新的IntPtr(1)
。还有+1用于发布您的作品。您是否意识到
IntPtr
是正确的而
int
不是?如果您想正确地执行此操作,您需要理解
IntPtr
。您有任何文档吗?我想是的,但是有一些MSDN(来自MVPs)根据其他引用将其引用为int,而不是IntPtr。您有确认此更改的链接吗?