我有一个钩子设置,用于在我开发的插件中获取鼠标事件。我需要获取WM_LBUTTONDBLCLK
,我希望消息流为:
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK
如果在处理第一个WM_LBUTTONDOWN
时调用下一个挂钩,则流程符合预期。但是,如果我返回自己的结果,那么预期的双击将作为鼠标按下消息。知道为什么会这样吗?我需要在处理之后停止消息,而不是将其传递给下一个钩子。
答案 0 :(得分:2)
在MSDN上做了一些阅读之后,我认为这种行为的解释在于WM_LBUTTONDBLCLK
页面上的这句话:
只有拥有
CS_DBLCLKS
的窗口 风格可以收到WM_LBUTTONDBLCLK
消息,系统生成的消息 每当用户按下,释放时, 并再次按下鼠标左键 系统内的按钮 双击时间限制。
如果您的程序在处理WM_LBUTTONDOWN
或WM_LBUTTONUP
时返回非零值,则这些消息不会按预期发送到目标窗口。但是,根据上面的引用,我的推论是因为没有CS_DBLCLKS
样式的窗口因此接收消息(因为钩子阻止任何窗口接收消息),因此,系统不需要生成WM_LBUTTONDBLCLK
。
换句话说,当且仅当(a)窗口收到之前的WM_LBUTTONDBLCLK
/ WM_LBUTTONDOWN
消息时,系统才会生成WM_LBUTTONUP
(b)该窗口具有CS_DBLCLKS
样式。由于您的钩子阻止了条件(a)的满足,因此永远不会生成WM_LBUTTONDBLCLK
,因此会发送WM_LBUTTONDOWN
消息。
至于解决方法,我怀疑有一个完美的解决方案。我假设您希望收到WM_LBUTTONDBLCLK
消息的原因是您的钩子知道常规WM_LBUTTONDOWN
消息是否代表双击的第二次点击,对吧?在这种情况下,您可以做的是阅读Faisal建议的注册表中的双击时间,并让您的钩子测量WM_LBUTTONDOWN
消息之间的时间,但是很可能会得到不准确的结果(由于发送消息之间的滞后时间)。或者,如果有某种方法,您可以将WM_LBUTTONDOWN
/ WM_LBUTTONUP
消息重定向到您的挂钩拥有的隐藏窗口(具有CS_DBLCLKS
样式),系统可能最终生成WM_LBUTTONDBLCLK
消息并将其发送到您隐藏的窗口,然后您可以在该窗口中WndProc
处理(虽然我没有很多挂钩的经验所以我不知道这是否可能)。
答案 1 :(得分:0)
您在返回自己的结果之前是否正在调用CallNextHookEx() - 根据MSDN的文档MouseProc,强烈建议您调用它,因为当您返回自己的结果时,会阻止其他挂钩被调用。
您是否考虑过使用low level mouse hook?它不需要将你的DLL注入到被挂钩的进程中,我发现它是一个更加一致和强大的钩子(虽然如果没有适当编码,虽然资源更加密集) - 尤其是在某些遗留应用程序中监听点击时(有一个在古代德尔福编码的,并点击通过终端服务器(Citrix)提供的应用程序。 低级别鼠标挂钩的唯一问题是它们本身不会获得双击 - 这意味着您必须在注册表中查询“DoubleClickSpeed”,然后在触发双击之前检查该时间间隔内的两个鼠标按下事件。