2

現在、マウスカーソルが画面の隅に到達した場合にアプリを表示するために、グローバルマウスフックを使用しています。Raw Input の存在について読んだところですが、私が理解していることから、フックの速度低下がシステム全体に影響を与えないため、これはより堅牢な方法です。

問題は、WPF で Raw Input を使用する例がどこにも見つからないことです。

私が得た最も近いものは、次のコードを持つSlimDXでした:

  Device.RegisterDevice(UsagePage.Generic, UsageId.Mouse, 
                        DeviceFlags.None);

  Device.MouseInput += new EventHandler<MouseInputEventArgs>(mouse_MouseInput);

しかし、それはWPFでは機能しないようで、winformsのみです。

4

1 に答える 1

0

これらは、バックグラウンドで入力をキャプチャするDeviceFlags.None必要があります。InputSinkSharpDX フラグには、実際にはRAWINPUTDEVICEFLAGS ( InputSink = 0x00000100) のラッパーがあります。

WPF では、1) オーバーライドOnSourceInitializedし、2) そこにフックWndProcします。ウィンドウ ポインターが使用可能である間に、監視する RAWINPUTDEVICE の flag を定義する必要がありますInputSink

それは次のようになります

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
    source.AddHook(WndProc);

    var win = source.Handle;

    RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[2];

    rid[0].UsagePage = (HIDUsagePage)0x01;
    rid[0].Usage = (HIDUsage)0x05;                 // adds game pad
    rid[0].Flags = RawInputDeviceFlags.InputSink;  // accept input in background
    rid[0].WindowHandle = win;

    rid[1].UsagePage = (HIDUsagePage)0x01;
    rid[1].Usage = (HIDUsage)0x04;                 // adds joystick
    rid[1].Flags = RawInputDeviceFlags.InputSink;  // accept input in background
    rid[1].WindowHandle = win;

    if (RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0])) == false)
    {
        var err = Marshal.GetLastWin32Error();
        if (err > 0)
        {
            throw new Win32Exception($"GetLastWin32Error: {err}");
        }
        else
        {
            throw new Win32Exception("RegisterRawInputDevices failed with error code 0. Parameter count mis-match?");
        }
    }
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case WM_INPUT:
            {
                System.Diagnostics.Debug.WriteLine("Received WndProc.WM_INPUT");
                DoTheThing(lParam);
            }
            break;
    }
    return hwnd;
}
于 2019-12-22T14:12:11.807 に答える