c++ - 捕获全局鼠标滚动,并将自定义鼠标滚动事件发送到应用程序

标签 c++ windows winapi scroll mouseevent

基本上,首先,我想重现 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 应该为您的目的工作得很好)。

要捕获鼠标滚动消息,您需要将 SetWindowsHookExWH_MOUSE_LL 结合使用。这将向您发送所有鼠标消息。确保为 WM_MOUSEWHEELWM_HMOUSEWHEEL 以外的任何消息调用 CallNextHookEx;你不想吃掉所有的信息!不过,您确实想要使用 WM_MOUSEWHEELWM_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/

相关文章:

c++ - 服务器和客户端之间如何异步通信

c++ - 使用 C++11 的 boost::date_time 编译失败

java - 带有cygwin noclassdefinition的Windows中的hadoop发现错误

windows - 获取设备名称

c++ - 如何在 Windows Mobile 中动态更改所有者绘制的列表框的高度?

c++ - exe的基地址?

c++ - std::对象的 move 和构造/销毁

c++ - 从 dll 中导出专门的模板函数

javascript - IE10 JavaScript 无法在计算机锁定时重新绘制窗口?

尽管 Eclipse 和 SDK 管理器在 Vista 上以管理员身份运行,但 Android-SDK 包安装错误