检测 WM_MOUSEMOVE 是不是由触摸/笔引起

Posted

技术标签:

【中文标题】检测 WM_MOUSEMOVE 是不是由触摸/笔引起【英文标题】:Detect if WM_MOUSEMOVE is caused by touch/pen检测 WM_MOUSEMOVE 是否由触摸/笔引起 【发布时间】:2015-04-24 21:13:21 【问题描述】:

我正在试验 WM_TOUCH 并想检测鼠标事件是从触摸/笔事件合成还是由于实际鼠标事件。

根据MSDN的官方解决方案是检查GetMessageExtraInfo()的结果是否将高24位设置为0xFF515700

这行得通。 大部分时间。如果我使用一根手指,一切都很好,但如果我使用多个手指,松开最后一根手指会导致鼠标移动GetMessageExtraInfo() == 0。此外,当窗口通过触摸失去焦点时,最多会生成 3 条带有GetMessageExtraInfo() == 0 的鼠标移动消息。

是否有一种可靠的方法来消除鼠标、触摸和笔输入之间的歧义?

【问题讨论】:

对于投反对票的人,请说明您对该问题的不满意之处。 【参考方案1】:

您发布的链接确实显示了区分物理鼠标生成的鼠标消息和响应触摸和笔输入而合成的鼠标消息的唯一可靠方法。

为了完整起见,这里是完整的工作代码。该代码依赖于仅在处理鼠标消息时有效的状态。在任何其他时间调用它都有未定义的行为:

bool IsTouchEvent() 
    const LONG_PTR c_SIGNATURE_MASK = 0xFFFFFF00;
    const LONG_PTR c_MOUSEEVENTF_FROMTOUCH = 0xFF515700;

    LONG_PTR extraInfo = GetMessageExtraInfo();
    return ( ( extraInfo & c_SIGNATURE_MASK ) == c_MOUSEEVENTF_FROMTOUCH );

您正在观察的附加 WM_MOUSEMOVE 消息是系统如何实现其内部簿记的工件。例如,如果一个窗口被显示或隐藏,鼠标光标现在可能在另一个窗口上,需要重新计算。为此,系统会合成一条人工的WM_MOUSEMOVE 消息。

Raymond Chen 的博客中解释了这种效果:Why do I get spurious WM_MOUSEMOVE messages?。

【讨论】:

我怀疑发生了类似的事情,但是当将焦点从窗口移开时,存储鼠标位置并忽略重复的消息会起作用,但反之则不行。 @Joe:那些WM_MOUSEMOVE 消息与触摸输入无关。它们将在不存在触摸输入设备的系统上生成。如果您需要找到过滤掉这些消息的方法,您可能需要提出一个新问题。 如果事件对应于实际的上一个鼠标移动(不是触摸),我不在乎,因为这些值对应于上一个/下一个鼠标移动。但是它们是由触摸事件引起的(到不同的窗口)。 在过滤来自 WM_MOUSEMOVE 的触摸输入时,您会发现触摸指针释放时的最终移动表明它来自鼠标设备。所有以前的都来自 Touch 通过额外的信息。如果您尝试在应用程序中编写不同的触摸和鼠标行为,这会很麻烦。大多数来自触摸的 WM_MOUSEMOVES 都是善意的谎言,但最后一个是令人讨厌的! @Greg:我相信最后的WM_MOUSEMOVE 根本与触摸输入无关。它是让我们通过发送假鼠标移动来结束消息,它也在非触摸系统上生成。当然,它在解释触摸输入时会妨碍您,但在使用鼠标将另一个窗口置于前台时,您会收到相同的消息。

以上是关于检测 WM_MOUSEMOVE 是不是由触摸/笔引起的主要内容,如果未能解决你的问题,请参考以下文章

检测节点是不是被任何手指触摸

检测用户是不是在 iOS 上触摸过屏幕

检测设备是不是有键盘,或者是触摸设备

如何检测 iOS UIViewController 是不是被交互或触摸

在 Xcode 中检测任何触摸(不是 TapGesture)

触摸屏物体识别到底是怎么实现的