1

作为我的 Visual Studio 实用程序插件SamTools的一部分,我有一个鼠标输入例程,它可以捕获 Ctrl+MouseWheel 并将 pageup/pagedown 命令发送到活动文本窗口。Visual Studio 2010 添加了一个新的“功能”,使用该手势进行放大/缩小(barf)。目前,我的加载项确实发送了滚动命令,但 Visual Studio 仍然会更改字体大小,因为我没有吃掉输入。

我打电话给SetWindowsHookEx. 这是回调代码。我的问题是:当我按下 Ctrl 键获得鼠标滚轮事件时,防止 Visual Studio 将 Ctrl+MouseWheel 输入作为缩放命令处理的最佳方法是根本调用吗?CallNextHookEx

(请记住,这是我的一些代码。):)

private IntPtr MouseCallback(int code, UIntPtr wParam, ref MOUSEHOOKSTRUCTEX lParam)
{
    try
    {
        // the callback runs twice for each action - this is the latch
        if (enterHook)
        {
            enterHook = false;
            if (code >= 0)
            {
                int x = lParam.mstruct.pt.X;
                int y = lParam.mstruct.pt.Y;

                uint action = wParam.ToUInt32();
                switch (action)
                {
                case WM_MOUSEWHEEL:
                    OnMouseWheel(new MouseEventArgs(MouseButtons.None, 0, x, y, ((short)HIWORD(lParam.mouseData)) / (int)WHEEL_DELTA));
                    break;

                default:
                    // don't do anything special
                    break;
                }
            }
        }
        else
        {
            enterHook = true;
        }
    }
    catch
    {
        // can't let an exception get through or VS will crash
    }

    return CallNextHookEx(mouseHandle, code, wParam, ref lParam);
}

这是响应MouseWheel事件执行的代码:

void mouse_enhancer_MouseWheel( object sender, System.Windows.Forms.MouseEventArgs e )
{
    try
    {
        if ( Keyboard.GetKeyState( System.Windows.Forms.Keys.ControlKey ).IsDown && Connect.ApplicationObject.ActiveWindow.Type == vsWindowType.vsWindowTypeDocument )
        {
            int clicks = e.Delta;
            if (e.Delta < 0)
            {
                Connect.ApplicationObject.ExecuteCommand( "Edit.ScrollPageDown", "" );
            }
            else
            {
                Connect.ApplicationObject.ExecuteCommand( "Edit.ScrollPageUp", "" );
            }
        }
    }
    catch ( System.Runtime.InteropServices.COMException )
    {
        // this occurs if ctrl+wheel is activated on a drop-down list. just ignore it.
    }
}

PS:SamTools 是开源的 (GPL) - 您可以从链接下载它,源代码在安装程序中。

PSS:Ctrl+[+] 和 Ctrl+[-] 更适合缩放。让 Ctrl+MouseWheel 滚动(更常用的命令)。

4

1 回答 1

1

根据MSDN,可以扔掉您处理的鼠标消息。这是建议:

如果 nCode 小于零,则挂钩过程必须返回 CallNextHookEx 返回的值。

如果nCode大于等于0,并且hook过程没有处理该消息,强烈建议调用CallNextHookEx并返回它返回的值;否则,其他安装了 WH_MOUSE 钩子的应用程序将不会收到钩子通知,因此可能会出现错误行为。如果钩子过程处理了消息,它可能会返回一个非零值,以防止系统将消息传递给目标窗口过程。

换句话说,如果您的鼠标回调最终使用鼠标消息,您不必调用下一个CallNextHookEx- 只需返回一个非零值,并且(至少在理论上)鼠标移动应该被吞没。如果这不能按您想要的方式工作,请发表评论,我们可以进行迭代。

顺便说一句,另一种可能的选择:VS 到鼠标滚轮的映射可能会显示在工具...自定义... UI 中,就像键映射一样。在这种情况下,您可以简单地重新映射加载项的命令,而不是在挂钩级别工作。但也有可能(可能?)这个手势是硬编码的。

于 2009-10-29T23:19:46.707 回答