我正在使用此处提供的示例:http: //blogs.msdn.com/b/toub/archive/2006/05/03/589468.aspx
连同我自己的代码来计算鼠标增量。
在任何人提到它之前,我知道 WPF 和 WF 中有直接访问 mouse.delta 属性的方法,但我需要这是一个低级别的钩子。
我对示例代码的修改如下:
private static Stopwatch CallbackTimestamp = new Stopwatch();
private static MSLLHOOKSTRUCT LastHook = new MSLLHOOKSTRUCT();
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && MouseMessages.WM_MOUSEMOVE == (MouseMessages)wParam)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
mouseExtensions.instance.InputChannels["X"].Value = hookStruct.pt.x;
mouseExtensions.instance.InputChannels["Y"].Value = hookStruct.pt.y;
int timeDif = (int)CallbackTimestamp.ElapsedTicks;
if (timeDif > 0)
{
int xDif = hookStruct.pt.x - LastHook.pt.x;
int yDif = hookStruct.pt.y - LastHook.pt.y;
double xDelta = ((double)xDif / (double)timeDif) * 10000;
mouseExtensions.instance.InputChannels["dX"].Value = (int)Math.Round(xDelta);
}
LastHook = hookStruct;
CallbackTimestamp.Restart();
}
if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
mouseExtensions.instance.InputChannels["B1"].Value = true;
if (nCode >= 0 && MouseMessages.WM_LBUTTONUP == (MouseMessages)wParam)
mouseExtensions.instance.InputChannels["B1"].Value = false;
if (nCode >= 0 && MouseMessages.WM_RBUTTONDOWN == (MouseMessages)wParam)
mouseExtensions.instance.InputChannels["B2"].Value = true;
if (nCode >= 0 && MouseMessages.WM_RBUTTONUP == (MouseMessages)wParam)
mouseExtensions.instance.InputChannels["B2"].Value = false;
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
它在大多数情况下工作得很好,但问题是我偶尔会得到不稳定的输出,例如,当将值绑定到滑块时,一致的鼠标移动将按预期移动滑块,除了突然颠簸到极端的最小值或最大值. 我认为这可能是一个除以零的问题,因为在分离过程中调用回调太快以至于时间跨度没有任何差异,但是添加逻辑来忽略 0 似乎并没有什么不同。
我可以存储一个值列表并使用平均值来帮助消除错误,但我宁愿解决问题而不是在上面贴上创可贴。