我使用的是此处提供的示例: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的逻辑似乎并没有产生影响。
我可以存储一个值列表并使用平均值来帮助消除错误,但是我宁愿解决问题而不是使用创可贴。