1

我有一个钩子设置,用于在我开发的插件中获取鼠标事件。我需要得到WM_LBUTTONDBLCLK,并且我希望消息流是:

WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK

如果我在处理第一个时调用下一个钩子WM_LBUTTONDOWN,那么流程就像预期的那样。但是,如果我返回自己的结果,那么预期的双击会作为鼠标按下消息出现。知道为什么会这样吗?我需要在处理完消息后停止消息,而不是将其传递给下一个钩子。

4

2 回答 2

2

在 MSDN 上做了一点阅读之后,我认为对这种行为的解释在于WM_LBUTTONDBLCLK页面上的这个注释:

只有具有该CS_DBLCLKS 样式的窗口才能接收WM_LBUTTONDBLCLK 消息,只要用户在系统的双击时间限制内按下、释放和再次按下鼠标左键,系统就会生成该消息。

如果您的程序在处理WM_LBUTTONDOWN或时返回非零值WM_LBUTTONUP,则这些消息不会发送到目标窗口——正如预期的那样。但是,基于上面的引用,我的推断是,由于没有具有该CS_DBLCLKS样式的窗口因此接收消息(因为钩子阻止任何窗口接收消息),因此系统并不觉得它需要生成WM_LBUTTONDBLCLK.

换句话说,系统仅WM_LBUTTONDBLCLK 当且仅当(a)窗口接收到先前的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(尽管我没有很多挂钩经验,所以我不知道这是否可能)。

于 2009-09-22T20:46:23.243 回答
0

您是否在返回自己的结果之前调用 CallNextHookEx() - 根据 MSDN 的文档MouseProc,强烈建议您调用它,因为当您返回自己的结果时,您会阻止调用其他挂钩。

您是否考虑过使用低级鼠标挂钩?它不需要将您的 DLL 注入到被挂钩的进程中,而且我发现它是一个更加一致和强大的挂钩(尽管如果编码不当,会占用更多资源)——尤其是在某些遗留应用程序中监听点击时(有一个用古代德尔福编码的)并点击通过终端服务器(citrix)提供的应用程序。低级鼠标挂钩的唯一问题是它们本身不接收双击 - 这意味着您必须在注册表中查询“DoubleClickSpeed”,然后在触发双击之前检查该间隔内的两个鼠标按下事件。

于 2009-09-22T04:25:15.723 回答