English 中文(简体)
在MFC中检测单击鼠标
原标题:
  • 时间:2009-02-03 16:18:50
  •  标签:

在MFC中,双击鼠标事件会触发以下消息序列

  • WM_LBUTTONDOWN
  • WM_LBUTTONUP
  • WM_LBUTTONDBCLK
  • WM_LBUTTONUP

所以,回应 WM_LBUTTONDBCLK 消息允许你检测双击。但是,如果我只想检测单击,我该如何区分它呢?

但仅仅查看WM_LBUTTONUP消息是不够的,因为它可能是单击,也可能是双击的第一次点击。

我该如何成功识别只有单击?

最佳回答

请允许我称这些事件为“鼠标弹起”和“鼠标按下”。我的MFC有点生疏。最近有个叫.NET的东西最近一直搞乱我的术语 ;)

短篇小说:你不只是想了解鼠标点击。你需要更多。

长故事

尽管这听起来有些违反直觉,但似乎仅仅想要一个鼠标点击是相当罕见的。通常情况下,您会想在鼠标按下时执行一些处理,并在鼠标松开时进行进一步处理。诀窍在于,仅仅跟踪鼠标松开消息是不够的:鼠标按下可能没有发生在您的窗口中。那么您认为这是有效的点击吗?特别是考虑到鼠标按下处理(例如选择某个项目)没有发生。

进一步推理,你不应该依赖于在处理鼠标下降后接收鼠标抬起:用户可能已经移动了鼠标并在其他地方释放了按钮(考虑拖放),在这种情况下,你本来不会收到鼠标抬起的事件...除非在MouseDown时捕获鼠标,以确保你获取了鼠标事件,直到鼠标抬起,即使鼠标离开你的窗口。

总的来说,你要跟踪鼠标按下,捕获鼠标,当你收到鼠标抬起时,只需检查是否拥有捕获。如果没有,鼠标可能是双击(没有第二次鼠标按下)或鼠标按下发生在其他地方,因此你可能不关心此鼠标抬起。

总之: 没有鼠标单击消息是因为您不能很远地使用它:您需要处理更多的消息并实现更多的机制。

哦!如果您正在处理一个已经处理所有这些项目和选择的控件,例如列表视图,那么它很有可能会提供类似的自定义通知,如项目激活或项目选择已更改。

问题回答

我刚刚在Delphi中尝试了这个,行为是一样的:即使发生了双击,两次单击事件中的第一次后面仍然会发出一个单击事件。

我使用定时器解决它,它的工作原理是:

  • deactivate timer on WM_LBUTTONDBLCLK (and set bDbl to true)
  • activate timer on WM_LBUTTONUP if bDbl==false
  • deactivate on WM_LBUTTONUP if bDbl==true (and reset bDbl)

我将定时器的间隔设置为 GetDoubleClickTime 返回的时间。

MSDN说:

The GetDoubleClickTime function retrieves the current double-click time for the mouse. A double-click is a series of two clicks of the mouse button, the second occurring within a specified time after the first. The double-click time is the maximum number of milliseconds that may occur between the first and second click of a double-click.

如果定时器恰好触发,则会发出真正的点击声。在我的情况下,双击间隔为500毫秒,因此任何“真正的点击”都会延迟这么长时间。

在 WM_LBUTTONUP 之前,您可以检查 WM_LBUTTONDOWN 是否被调用超过一次。在实践中,Windows 会为您执行此操作,即如果您收到 WM_LBUTTONDBCLK,则很容易不会收到 WM_LBUTTONUP。

您可以使用PreTranslateMessage()函数来计算消息的数量,当它们出现时。如果您只收到与单击相对应的鼠标消息,并且已经超过了系统配置的双击时间,您可以安全地假设这是一个单击。

据我所知,目前没有办法在发生时知道情况,这很有道理——在时间到期之前,无法知道是否会发生第二次点击。

那有点棘手。

我将检测 WM_LBUTTONDOWN 和 WM_LBUTTONUP 组合,将该事件存储在某个地方并设置一个大约一秒钟的超时。如果在超时期间没有 WM_LBUTTONDBCLK,则表示您进行了单击。

这可能意味着您需要运行另一个线程,但我认为您可以通过一个线程完成它。

我认为解决方法是在第一次点击后启动定时器,然后在下一次即时点击后检查经过的时间,这将告诉你它是单击还是双击。

你通常会查看 @MLButtonUp,并且同一个鼠标按钮上不会同时拥有单击和双击行为。





相关问题
热门标签