我可以在应用程序的主循环之前抑制选定的输入吗?

时间:2009-08-12 04:32:43

标签: visual-studio-2010 visual-studio-addins mousewheel mouse-hook

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

我通过调用SetWindowsHookEx来设置我的钩子。这是回调代码。 我的问题是:是阻止Visual Studio将Ctrl + MouseWheel输入作为缩放命令处理的最佳方法,当我得到一个时,调用CallNextHookEx按住Ctrl键的鼠标滚轮事件?

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

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滚动(更常用的命令)。

1 个答案:

答案 0 :(得分:1)

根据MSDN,可以抛出您处理的鼠标消息。以下是建议:

  

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

     

如果nCode大于或等于   零,钩子程序没有   处理消息,它是高度的   建议你打电话   CallNextHookEx并返回它的值   回报;否则,其他应用程序   已经安装了WH_MOUSE钩子   不会收到挂钩通知   并且可能表现不正常   结果。如果挂钩程序   处理完邮件后,可能会返回一个   非零值以防止系统   从将消息传递给目标   窗口程序。

换句话说,如果使用鼠标消息结束鼠标回调,则不必调用下一个CallNextHookEx - 只返回非零值并且(理论上至少)鼠标移动应该被吞下去。如果这不符合您的要求,请发表评论并重复。

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