如果鼠标光标到达屏幕的一角,我正在使用全局鼠标钩子来显示应用程序。我刚刚读到了Raw Input的存在,据我所知,这是一种更健壮的方法,因为我的钩子减速不会影响整个系统。
问题是我在WPF中使用Raw Input无法找到任何示例。
我得到的最近的是SlimDX,代码如下:
Device.RegisterDevice(UsagePage.Generic, UsageId.Mouse,
DeviceFlags.None);
Device.MouseInput += new EventHandler<MouseInputEventArgs>(mouse_MouseInput);
但这似乎不适用于WPF,只有winforms。
答案 0 :(得分:0)
这些DeviceFlags.None
必须是InputSink
才能在后台捕获输入。 SharpDX标志实际上是RAWINPUTDEVICEFLAGS(InputSink = 0x00000100
)的包装。
在WPF中,您想要1)覆盖OnSourceInitialized
和2)钩住WndProc
。当窗口指针可用时,您需要定义要观看的RAWINPUTDEVICE,标记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;
}