基本上,首先,我想重现 WizMouse 的功能或 KatMouse .一个相关的 super 用户问题是 here .
我需要哪些 Windows API?
此外,作为第二步,我想到了实现 MacOSX 滚动加速和像素精确滚动等功能。 (基本上,你总是逐个像素地滚动,但是当你快速移动滚轮时,它会比线性加速,例如二次方,加速到滚轮速度。这样,你可以滚动更多更快地滚动到结束一个很长的页面,同时,您可以滚动得更少但更精确。)
有没有办法让一些元素只滚动一个像素? (我可以自己实现所有剩余的逻辑。)
这个问题是用 C++ 和 Winapi 标记的,但如果使用其他 Windows-API 和其他语言更容易,我也愿意接受。
最佳答案
GetCursorPos
会让你得到鼠标指针的坐标。在那之后,WindowFromPoint
会让你弄清楚那个点是哪个窗口。显然是 figuring out which window is at a given point is complicated, though ,因此您需要对不同的 ...FromPoint...
API 进行一些试验(从 Old New Thing 博客文章来看,WindowFromPoint
应该为您的目的工作得很好)。
要捕获鼠标滚动消息,您需要将 SetWindowsHookEx
与 WH_MOUSE_LL
结合使用。这将向您发送所有鼠标消息。确保为 WM_MOUSEWHEEL
或 WM_HMOUSEWHEEL
以外的任何消息调用 CallNextHookEx
;你不想吃掉所有的信息!不过,您确实想要使用 WM_MOUSEWHEEL
和 WM_HMOUSEWHEEL
事件,因为您是手动将它们发送到另一个窗口。
我对下一部分不太确定。我想你会想将 WM_MOUSEWHEEL
直接传递给光标下的窗口,但你需要确保你的钩子(Hook)不会吃掉它。 (完成此操作的最佳方法可能是让 Hook 过程确定 WM_MOUSEWHEEL
消息是否已传递到光标下的窗口,如果没有,则只处理/吃掉它。)你可以还可以利用消息的 wParam
来设置滚动的速度。我不相信您能够逐个像素地滚动,但您最初可以使用最小滚动距离 (WHEEL_DELTA * 1
),并随着滚动速度的加快和快点。冲洗并重复 WM_HMOUSEWHEEL
。
您需要非常小心的一件事是超时。来自 WH_MOUSE_LL
钩子(Hook)的文档:
The hook procedure should process a message in less time than the data entry specified in the LowLevelHooksTimeout value in the following registry key: HKEY_CURRENT_USER\Control Panel\Desktop
The value is in milliseconds. If the hook procedure times out, the system passes the message to the next hook. However, on Windows 7 and later, the hook is silently removed without being called. There is no way for the application to know whether the hook is removed.
The FAQ for X-Button Mouse Control 是一款与您正在寻找的功能类似的应用程序,它说(强调我的):
When using on Windows 7, XMBC can stop responding to mouse click seemingly randomly. This is not strictly a bug in XMBC but a change in the behaviour of Windows. Windows 7 introduced the concept of a timeout for system hooks (the method XMBC uses to monitor the mouse). If the CPU is busy (eg. playing HD movies) XMBC may not be scheduled (by windows) in time to respond to the hook before this timeout occurs. When this happens, the hook is removed without notification (thanks Microsoft!) and XMBC appears to have stopped working. Restarting it or pressing Apply in the settings screen fixes the problem until it happens again.
The only solution to this is to increase the LowLevelHookTimeout value (in the registry for now).
您的软件很可能会面临同样的问题。您需要确保对其进行记录和/或自行调整该注册表项以提供更高的超时值。
关于c++ - 捕获全局鼠标滚动,并将自定义鼠标滚动事件发送到应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22476260/