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