アプリケーションのメインループの前に選択した入力を抑制できますか?
-
13-09-2019 - |
質問
Visual Studio ユーティリティ アドインの一部として サムツール, Ctrl+MouseWheel をキャッチしてアクティブ テキスト ウィンドウに pageup/pagedown コマンドを送信するマウス入力ルーチンがあります。Visual Studio 2010 では、ズームイン/ズームアウト (barf) にそのジェスチャを使用する新しい「機能」が追加されました。現在、アドインはスクロール コマンドを送信しますが、入力を取り込んでいないため、Visual Studio は依然としてフォント サイズを変更します。
への呼び出しでフックを設定しました SetWindowsHookEx
. 。これがコールバックコードです。 私の質問は次のとおりです。 これは、Visual Studio が Ctrl+マウスホイール入力をズーム コマンドとして処理しないようにする最良の方法です。 ない 電話 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.
}
}
追伸:SamTools はオープン ソース (GPL) です。リンクからダウンロードでき、ソースはインストーラー内にあります。
PSS:Ctrl+[+] および Ctrl+[-] はズームに適しています。Ctrl+マウスホイールをスクロールさせます (非常に一般的に使用されるコマンド)。
解決
によると MSDN, 、処理したマウス メッセージを破棄することが可能です。推奨事項は次のとおりです。
ncodeがゼロ未満の場合、フック手順はcallnextokexによって返された値を返す必要があります。
ncodeがゼロ以上であり、フック手順がメッセージを処理しなかった場合、callnexthookexを呼び出して返す値を返すことを強くお勧めします。それ以外の場合、wh_mouseフックをインストールした他のアプリケーションはフック通知を受け取らず、結果として誤って動作する可能性があります。フック手順がメッセージを処理した場合、システムがメッセージをターゲットウィンドウの手順に渡すことを防ぐために、ゼロ以外の値を返す場合があります。
言い換えれば、マウス コールバックがマウス メッセージを使用することになった場合、次のコールバックを呼び出す必要はありません。 CallNextHookEx
-- ゼロ以外の値を返すだけで、(少なくとも理論的には) マウスの動きが飲み込まれるはずです。ご希望どおりに動作しない場合は、コメントしていただければ繰り返し対応させていただきます。
ところで、別の可能な代替案:VS のマウス ホイールへのマッピングがツール...カスタマイズ... に表示される可能性があります。UI はキー マッピングと同じです。その場合、フック レベルで作業するのではなく、アドインのコマンドを単純に再マップすることができます。しかし、このジェスチャがハードコーディングされている可能性もあります (おそらく?)。