【问题标题】:Detecting a single mouse click in MFC在 MFC 中检测单击鼠标
【发布时间】:2010-10-05 04:49:58
【问题描述】:

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

  • WM_LBUTTONDOWN
  • WM_LBUTTONUP
  • WM_LBUTTONDBCLK
  • WM_LBUTTONUP

因此响应 WM_LBUTTONDBCLK 消息可以让您检测到双击。但是如果我只是想检测单击如何区分呢?

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

我如何才能成功识别单击?

【问题讨论】:

    标签: user-interface winapi visual-c++ mfc


    【解决方案1】:

    我认为解决方案是在第一次单击后启动计时器,然后在下一次立即单击后检查经过的时间,这将告诉您是单击还是双击。

    【讨论】:

      【解决方案2】:

      (请允许我将这些事件称为 Mouse Up 和 Mouse Down。我的 MFC 有点生锈了。还有一个叫做 .NET 的东西最近弄乱了我的术语;-)

      小故事:您不只是想了解鼠标点击。你需要更多。

      长篇大论

      虽然这是违反直觉的,但似乎只是想要单击鼠标是相当少见的。大多数情况下,您需要在 Mouse Down 上执行一些处理并在 Mouse Up 上进行一些进一步的处理。诀窍是仅仅跟踪 Mouse Up 消息是不够的:Mouse Down 可能没有在您的窗口中发生。你认为这是一次有效的点击吗?特别是考虑到没有发生 Mouse Down 处理(例如选择一个项目)。

      进一步推理,在处理鼠标按下后,您不应该依赖接收鼠标按下:用户可能已经移动了鼠标并在其他地方释放了按钮(想想拖放),在这种情况下,您不接收 MouseUp 事件...除非您在 MouseDown 上捕获鼠标以确保即使鼠标离开您的窗口也能将鼠标事件提升到 Mouse Up。

      总而言之,您最终会跟踪 Mouse Down,捕获鼠标,当您收到 Mouse Up 时,只需检查您是否拥有捕获的所有权。如果没有,鼠标要么被双击(没有第二次按下鼠标),要么鼠标按下发生在其他地方,因此你很可能不关心这个鼠标按下。

      结论:没有 MouseClick 消息只是因为您不会走得太远:您需要处理更多消息并实现更多机制。

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

      【讨论】:

        【解决方案3】:

        我刚刚在 Delphi 中尝试过,行为是相同的:即使发生双击,单击事件也会在两者中的第一个之后立即发出。

        我使用计时器解决了这个问题,它的工作原理如下:

        • 停用 WM_LBUTTONDBLCLK 上的计时器(并将 bDbl 设置为 true
        • 如果bDbl==false,则在 WM_LBUTTONUP 上激活计时器
        • 如果 bDbl==true 则在 WM_LBUTTONUP 上停用(并重置 bDbl

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

        MSDN 说:

        GetDoubleClickTime 函数 检索当前的双击 鼠标的时间。双击是 一系列的两次点击鼠标 按钮,第二个发生在 第一次之后的指定时间。这 双击时间最长 可能发生的毫秒数 在第一次和第二次点击之间 双击。

        如果计时器碰巧触发,那么您就有了真正的点击。在我的情况下,双击间隔是 500 毫秒,所以任何“真正的点击”都会延迟这么长时间。

        【讨论】:

          【解决方案4】:

          这有点棘手。

          我会检测 WM_LBUTTONDOWN 和 WM_LBUTTONUP 组合,将该事件存储在某处并设置一秒钟左右的超时。如果在该超时期间没有 WM_LBUTTONDBCLK,那么您只需单击一下。

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

          【讨论】:

            【解决方案5】:

            您可以使用 PreTranslateMessage() 对出现的消息进行计数。如果您只收到与单击对应的鼠标消息,并且系统配置的双击时间已过期,您可以放心地认为它是单击。

            据我所知,没有办法知道正在发生这种情况,这是有道理的 - 直到时间到期,没有办法知道第二次点击是否到来.

            【讨论】:

              【解决方案6】:

              您可以检查 WM_LBUTTONDOWN 在 WM_LBUTTONUP 之前是否被多次调用。实际上,Windows 会为您执行此操作,因为如果您获得 WM_LBUTTONDBCLK,您往往不会获得 WM_LBUTTONUP。

              【讨论】:

                【解决方案7】:

                您通常会查看@MLButtonUp,并且不会在同一个鼠标按钮上进行单击和双击行为。

                【讨论】:

                  猜你喜欢
                  • 2013-12-08
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-04-18
                  • 2016-04-22
                  • 1970-01-01
                  相关资源
                  最近更新 更多