1

私の Visual Studio ユーティリティ アドインSamToolsの一部として、 Ctrl+MouseWheel をキャッチし、ページアップ/ページダウン コマンドをアクティブなテキスト ウィンドウに送信するマウス入力ルーチンがあります。Visual Studio 2010 では、ズームイン/ズームアウト (バーフ) にそのジェスチャを使用する新しい "機能" が追加されました。現在、アドインはスクロール コマンドを送信しますが、入力を食べていないため、Visual Studio は依然としてフォント サイズを変更します。

への呼び出しでフックを設定しましたSetWindowsHookEx。コールバック コードは次のとおりです。私の質問は、Visual Studio が Ctrl+MouseWheel 入力をズーム コマンドとして処理して、Ctrl キーを押した状態でマウス ホイール イベントを取得したときに単に呼び出さないようにする最善の方法ですか?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 が 0 未満の場合、フック プロシージャは CallNextHookEx によって返された値を返す必要があります。

nCode が 0 以上で、フック プロシージャがメッセージを処理しなかった場合は、CallNextHookEx を呼び出して、返された値を返すことを強くお勧めします。そうしないと、WH_MOUSE フックをインストールした他のアプリケーションがフック通知を受信せず、結果として正しく動作しない可能性があります。フック プロシージャがメッセージを処理した場合、システムがメッセージをターゲット ウィンドウ プロシージャに渡さないようにするために、0 以外の値が返される場合があります。

つまり、マウス コールバックがマウス メッセージを使用することになった場合、次のコールバックを呼び出す必要はありませんCallNextHookEx。0 以外の値を返すだけで、(少なくとも理論上は) マウスの動きが飲み込まれるはずです。それが思い通りにいかない場合は、コメントしてください。繰り返します。

ところで、別の可能な代替手段: キー マッピングと同じように、VS のマウス ホイールへのマッピングが Tools...Customize... UI に表示される可能性があります。その場合、フック レベルで作業する代わりに、アドインのコマンドを単純に再マップすることができます。しかし、このジェスチャがハードコーディングされている可能性もあります (おそらく?)。

于 2009-10-29T23:19:46.707 に答える