[編集]これまでにマウス入力の処理について収集した内容は次のとおりです。私はこれをさまざまなソースと実験を通じて学んだので、これを福音と見なさないでください:1)マウスイベントはマウスの動きで発生します2)SetWindowsHookEx(WH_MOUSE_LL)ハンドラーLowLevelMouseProcは最初にイベントを確認します3)OS / appフレームワークはマウスイベントを高レベルで処理します(マウスカーソルの移動)4)WM_INPUTイベントはアプリイベントキューによって取得され、WndProcによって処理されます(ただし、この時点で処理しても、ステップ3でマウスカーソルの移動が停止することはありません)。5)メッセージはComponentDispatcherを介してディスパッチされます。6)PreviewMouseMoveおよびMouseMoveイベントがトリガーされ、アプリによって処理される場合があります。
これに基づいて、マウスカーソルが動かないようにする唯一の方法は、WH_MOUSE_LLを介してフィルタリングすることだと思います。もちろん、この投稿で前述したように、この時点では、このマウスイベントがどのデバイスから発生しているかを知るための十分な情報がないため、フィルタリングがすべてまたはまったく行われず、私の要件を満たしていません。
[編集]WH_MOUSE_LLをフックし、ハンドラーから0より大きい値を返すことで、イベントをドロップできることを確認しました。ここで、WH_MOUSE_LLレベルで生成されたマウスイベントをデバイスからのイベントと一致させる方法を理解する必要があります...
WndProcから0より大きい値を返してみました。イベントはまだ私のアプリによって処理されていました。
機械式USBマウスのY軸をベースにした回転入力デバイスを統合しようとしています。このデバイスを生の入力デバイスとしてのみ動作させ、デバイスによって生成された通常のマウス移動イベント(少なくとも私のアプリケーションのコンテキストでは)をドロップしたいと思います。
これまでのところ、WindowIteropHandlerとAddHookを使用して、WndProcをWPFアプリケーションのMainWindowにフックすることができました。WM_INPUTイベントを受信し、特定のUSB VID / PIDデバイスからマウスイベント用にそれらをフィルタリングすることができます(私のニーズには十分です)。
メッセージを処理済みとしてマークして0を返すと、メッセージがWPFウィンドウの残りの部分に伝達されないことが予想されますが、そうではありません...デバイスを移動してもMouseMoveイベントが発生します。これが私のコードです(WM_INPUTメッセージの処理を削除するために簡略化されていますが、それでも同じ問題が発生します):
public partial class MainWindow : Window
{
private const int WM_INPUT = 0x00FF;
public MainWindow()
{
InitializeComponent();
}
public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_INPUT)
{
// TODO - figure out why this doesn't halt further processing of this handled event
handled = true;
}
return IntPtr.Zero;
}
[StructLayout(LayoutKind.Sequential)]
internal struct RAWINPUTDEVICE
{
[MarshalAs(UnmanagedType.U2)]
public ushort usUsagePage;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsage;
[MarshalAs(UnmanagedType.U4)]
public int dwFlags;
public IntPtr hwndTarget;
}
private const int RIDEV_INPUTSINK = 0x00000100;
[DllImport("User32.dll")]
extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);
private void Window_SourceInitialized(object sender, EventArgs e)
{
WindowInteropHelper helper = new WindowInteropHelper(this);
HwndSource source = HwndSource.FromHwnd(helper.Handle);
RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];
rid[0].usUsagePage = 0x01;
rid[0].usUsage = 0x02;
rid[0].dwFlags = RIDEV_INPUTSINK;
rid[0].hwndTarget = source.Handle;
RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0]));
source.AddHook(WndProc);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
e.Handled = true;
}
}
WndProcで処理したマウスイベントがMainWindowに伝播されるのをデキューまたはブロックする方法を知っている人はいますか?
TIA!
-マット