在MFC中,双击鼠标单击事件会触发以下消息序列
因此,响应 WM_LBUTTONDBCLK 消息可以检测到双击。但如果我只是想检测一次单击如何区分它?
但仅仅查看 WM_LBUTTONUP 消息是不够的,因为它可能是单击,也可能是双击的第一次点击。
如何才能成功识别单击?
答案 0 :(得分:10)
(请允许我将这些事件称为Mouse Up和Mouse Down。我的MFC有点生疏。而且有一些名为.NET的东西最近弄乱了我的术语; - )
短篇小说:您不只是想了解鼠标点击。你需要更多。
长篇故事:
虽然这是违反直觉的,但似乎只是想要鼠标点击是相当罕见的。大多数情况下,您需要在Mouse Down上执行一些处理,并在Mouse Up上进行一些进一步处理。诀窍是仅仅跟踪Mouse Up消息是不够的:在窗口中可能没有发生鼠标停用。你认为这是一个有效的点击吗?特别是考虑到鼠标按下处理(例如选择项目)没有发生。
进一步推理,你不应该依赖于在处理鼠标后接收鼠标:用户可能已经移动了鼠标并在其他地方释放了按钮(想想拖拉),在这种情况下,你不接收MouseUp事件...除非您在MouseDown上捕获鼠标以确保鼠标事件达到Mouse Up,即使鼠标离开窗口也是如此。
总而言之,您最终会跟踪Mouse Down,捕获鼠标,当您收到Mouse Up时,只需检查您是否拥有捕获。如果没有,鼠标要么双击(没有第二个鼠标按下),要么鼠标在其他地方发生,因此你很可能不关心这个鼠标。
总结:没有MouseClick消息只是因为你不会走得太远:你需要处理更多的消息并实现更多的机制。
哦!如果您处理已经处理了所有这些项目和选择内容的现有控件(例如列表视图),则可能会提供类似的自定义通知,例如项目激活或项目选择已更改。
答案 1 :(得分:1)
我刚刚在Delphi中尝试过这种方法,行为是一样的:即使发生双击,也会在两个中的第一个之后发出单击事件。
我使用计时器解决了它,它的工作原理如下:
bDbl
设置为true
)bDbl==false
bDbl==true
(并重置bDbl
),则我将计时器的间隔设置为GetDoubleClickTime
返回的时间。
MSDN说:
GetDoubleClickTime函数 检索当前的双击 鼠标的时间。双击即可 两次点击鼠标 按钮,第二个发生在一个 第一个之后的指定时间。该 双击时间是最大值 可能发生的毫秒数 在第一次和第二次点击之间 双击。
如果计时器恰好点火,那么你就是真正的点击。在我的情况下,双击间隔是500毫秒,所以任何“真正的点击”将延迟这么久。
答案 2 :(得分:0)
你可以检查在WM_LBUTTONUP之前没有多次调用WM_LBUTTONDOWN。在实践中,Windows会为您执行此操作,因为如果您获得WM_LBUTTONDBCLK,则往往不会获得WM_LBUTTONUP。
答案 3 :(得分:0)
您可以使用PreTranslateMessage()来计算出现的消息。如果您只收到与单击相对应的鼠标消息,并且系统配置的双击时间已过期,您可以放心地假设只需单击一次。
据我所知,没有办法知道这种情况正在发生,这是有道理的 - 直到时间到期,没有办法知道第二次点击是否来临
答案 4 :(得分:0)
我会检测到WM_LBUTTONDOWN& WM_LBUTTONUP组合,将该事件存储在某处并设置超时一秒左右。如果在超时期间没有WM_LBUTTONDBCLK,则只需单击一下即可。
这可能意味着你需要运行另一个线程,但我认为你可以用一个线程完成它。
答案 5 :(得分:0)
我认为解决方案是在第一次点击后启动计时器。然后检查下次立即点击后经过的时间,这将告诉您是单击还是双击。
答案 6 :(得分:-2)
您通常会查看@MLButtonUp,并且您不会在同一个鼠标按钮上单击和双击行为。