代码之家  ›  专栏  ›  技术社区  ›  Sam Harwell

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

  •  1
  • Sam Harwell  · 技术社区  · 15 年前

    作为我的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 回复  |  直到 15 年前
        1
  •  1
  •   Justin Grant    15 年前

    根据 MSDN ,可以丢弃您处理的鼠标消息。建议如下:

    如果ncode小于零,则钩子 过程必须返回值 由callenxthookex返回。

    如果ncode大于或等于 零,钩子程序没有 处理消息,它是高度 建议您拨打 callNexthookex并返回它的值 返回;否则,其他应用程序 安装了鼠标挂钩的 将不接收挂钩通知 可能表现得不正确 结果。如果钩子程序 已处理消息,它可能会返回 非零值以防止系统 将消息传递给目标 窗口程序。

    换句话说,如果鼠标回调最后使用鼠标消息,则不必调用下一个 CallNextHookEx --只需返回一个非零值(至少理论上是这样),鼠标的移动就会被吞没。如果这不符合你想要的方式,请评论,我们可以迭代。

    顺便说一句,另一种可能的选择是:vs的鼠标轮映射可能出现在工具中…自定义…用户界面,就像键映射一样。在这种情况下,您可以简单地重新映射外接程序的命令,而不是在钩子级别工作。但这也是可能的。这个手势是硬编码的。