捕捉全局鼠标滚动,并向应用程序发送自定义鼠标滚动事件

catch global mouse scroll, and send custom mouse scroll events to apps

本文关键字:滚动 鼠标 事件 应用程序 自定义 全局      更新时间:2023-10-16

首先,我想重现WizMouse或KatMouse的功能。一个相关的超级用户问题在这里。

我需要哪些Windows api ?

另外,作为第二步,我想实现MacOSX滚动加速和像素精确滚动。(基本上,你总是逐像素滚动,但当你快速移动滚轮时,它加速超过线性,例如二次,滚轮速度。这样,你就可以更快地滚动到一个长页面的末尾,同时,你也可以滚动得更少更精确。

是否有一种方法来滚动一些元素只有一个像素?(我可以自己实现所有剩余的逻辑)

这个问题被标记为c++和Winapi,但如果使用其他windows api和其他语言更容易,我也愿意。

GetCursorPos将让您获得鼠标指针的坐标。之后,WindowFromPoint会让你算出那个点的窗口。显然,找出哪个窗口是在一个给定的点是复杂的,虽然,所以你会想做一些实验不同的...FromPoint... api(从看旧的新事物的博客文章,WindowFromPoint应该工作得很好,为您的目的)。

要捕获鼠标滚动消息,您将需要使用SetWindowsHookExWH_MOUSE_LL。这将向您发送任何和所有鼠标消息。对于WM_MOUSEWHEELWM_HMOUSEWHEEL以外的任何消息,请确保调用CallNextHookEx;你不会想吃掉所有的信息吧!您确实想要吃掉WM_MOUSEWHEELWM_HMOUSEWHEEL事件,但是,因为您手动将它们发送到另一个窗口。

我对下一部分不太确定。我认为你会想要将WM_MOUSEWHEEL直接传递给光标下的窗口,但你需要确保你的钩子不会吃掉它。(实现这一点的最佳方法可能是让钩子子程确定WM_MOUSEWHEEL消息是否已经传递给了光标下的窗口,如果没有,则只处理/吃掉它。)您还可以利用消息的wParam来设置滚动的速度。我不相信您能够逐像素滚动,但您可以最初使用最小滚动距离(WHEEL_DELTA * 1),并随着滚动速度越来越快而扩大乘数。冲洗并重复WM_HMOUSEWHEEL

您需要非常小心的一件事是超时。来自WH_MOUSE_LL钩子的文档:

钩子子程处理消息的时间应该少于以下注册表项中的LowLevelHooksTimeout值所指定的数据条目的时间:桌面HKEY_CURRENT_USER 控制面板

单位为毫秒。如果钩子子程超时,系统将消息传递给下一个钩子。然而,在Windows 7及更高版本上,钩子在不被调用的情况下被静默删除。应用程序无法知道钩子是否被删除。

x键鼠标控制的常见问题解答,一个类似于你正在寻找的应用程序,说(强调我的):

在Windows 7上使用时,XMBC可以停止响应鼠标点击看似随机。严格来说,这不是XMBC中的错误,而是Windows行为的变化。Windows 7引入了系统钩子超时的概念(XMBC用来监视鼠标的方法)。如果CPU繁忙(例如;(播放高清电影)XMBC可能无法在此超时发生之前及时调度(由窗口)以响应钩子。当发生这种情况时,钩子将在没有通知的情况下被删除(感谢Microsoft!), XMBC似乎已经停止工作。重新启动它或在设置界面中按"应用"可以修复问题,直到再次发生。

唯一的解决方案是增加LowLevelHookTimeout值(目前在注册表中)

你的软件很可能会面临同样的问题。您需要确保您记录了它并/或自己调整注册表项以提供更高的超时值。