惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
T
The Exploit Database - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
T
Threatpost
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Tenable Blog
F
Full Disclosure
TaoSecurity Blog
TaoSecurity Blog
I
InfoQ
AI
AI
云风的 BLOG
云风的 BLOG
K
Kaspersky official blog
Microsoft Azure Blog
Microsoft Azure Blog
S
SegmentFault 最新的问题
Y
Y Combinator Blog
GbyAI
GbyAI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Privacy International News Feed
aimingoo的专栏
aimingoo的专栏
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
I
Intezer
L
Lohrmann on Cybersecurity
博客园_首页
量子位
Blog — PlanetScale
Blog — PlanetScale
The Last Watchdog
The Last Watchdog
Cisco Talos Blog
Cisco Talos Blog
博客园 - 叶小钗
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Help Net Security
Help Net Security
Security Archives - TechRepublic
Security Archives - TechRepublic
Apple Machine Learning Research
Apple Machine Learning Research
W
WeLiveSecurity
N
News and Events Feed by Topic
S
Schneier on Security
T
Tor Project blog
MongoDB | Blog
MongoDB | Blog
博客园 - 三生石上(FineUI控件)
V
Visual Studio Blog
T
Threat Research - Cisco Blogs
H
Help Net Security
V
V2EX
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Security @ Cisco Blogs
博客园 - Franky
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler

博客园 - 唐宋元明清2188

Electron 桌面客户端 ASAR 热更新:替换一个文件完成版本切换 .NET Win32设置只读未对齐,导致NTFS文件系统识别异常 SDD-skills执行遗漏问题 SDD基于规范编程-OpenSpec及SuperPowers .NET 磁盘BitLocker加密-技术选型 .NET Win32磁盘动态卷触发“函数不正确”问题排查 .NET SqlSugar多线程下SqlSugarClient 的线程安全陷阱 .NET 本地Db数据库-技术方案选型 .NET 磁盘Bitlocker加密-Powershell操作 .NET 磁盘管理-技术方案选型 .NET 记录Amazon上传S3异常问题 .NET 记录多框架下的Json序列化属性标记问题 .NET 阻止Windows关机以及阻止失败的一些原因 网络虚拟存储 Iscsi实现方案 Windows 网络存储ISCSI介绍 Windows 本地虚拟磁盘Vhdx .NET 数据拷贝方案选择 .NET 窗口置于最顶层 如何做好软件架构师 .NET开发一些书箱推荐 Windows应用开发-常用工具 .NET Bios相关数据读写
WPF 记录鼠标、触摸多设备混合输入场景问题
唐宋元明清2188 · 2024-12-30 · via 博客园 - 唐宋元明清2188

本文记录在WPF应用中鼠标、触摸混合输入,鼠标事件抬起时不会有MouseUp事件触发的问题。

事件输入我们都知道有3类:鼠标、触摸、触笔,鼠标是windows系统出来就有的事件,后面加了触笔、触摸。

1.鼠标输入,只会触发Mouse冒泡隧道事件;

2.触笔输入,会触发除了Stylus事件外,还会触发Mouse事件;

3.触摸输入,触发Touch事件、Stylus事件、Mouse事件。

如何区分三类事件可以参考 WPF 屏幕点击的设备类型 - 唐宋元明清2188 - 博客园,封装所有事件类型(包括Button阻止冒泡事件场景)整合成一个Device事件可以参考 WPF 设备输入事件封装 - 唐宋元明清2188 - 博客园

和小伙伴在定位PPT批注翻页问题时,发现在以WIN32跨进程设置父子窗口后再调动PPT上下翻页,批注触摸操作只会触发Mouse事件,但此Mouse事件只有Down没有Up,这类触摸只转鼠标的场景后面我单独描述下。当我尝试使用鼠标+触摸混合操作时,也能复现Mouse没有Up抬起事件。

鼠标+触摸,复现步骤:
1.鼠标按下

2.在其它位置触摸按下

3.鼠标抬起

4.触摸抬起

我们看看WPF真实反馈的事件输出,UI监听下面几个冒泡事件:

1     <Grid Background="LightGray"
2           MouseDown="UIElement_OnMouseDown" MouseUp="UIElement_OnMouseUp"
3           StylusDown="UIElement_OnStylusDown" StylusUp="UIElement_OnStylusUp"
4           TouchDown="UIElement_OnTouchDown" TouchUp="UIElement_OnTouchUp">
5     </Grid>

记录下输出事件,下面区分了鼠标、触摸、触笔:

 1     private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
 2     {
 3         if (e.StylusDevice != null) return;
 4         Debug.WriteLine("UIElement_OnMouseDown");
 5     }
 6     private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
 7     {
 8         if (e.StylusDevice != null) return;
 9         Debug.WriteLine("UIElement_OnMouseUp");
10     }
11 
12     private void UIElement_OnStylusDown(object sender, StylusDownEventArgs e)
13     {
14         if (e.StylusDevice.TabletDevice.Type != TabletDeviceType.Stylus)
15         {
16             return;
17         }
18         Debug.WriteLine("UIElement_OnStylusDown");
19     }
20     private void UIElement_OnStylusUp(object sender, StylusEventArgs e)
21     {
22         if (e.StylusDevice.TabletDevice.Type != TabletDeviceType.Stylus)
23         {
24             return;
25         }
26         Debug.WriteLine("UIElement_OnStylusUp");
27     }
28 
29     private void UIElement_OnTouchDown(object? sender, TouchEventArgs e)
30     {
31         Debug.WriteLine("UIElement_OnTouchDown");
32     }
33     private void UIElement_OnTouchUp(object? sender, TouchEventArgs e)
34     {
35         Debug.WriteLine("UIElement_OnTouchUp");
36     }

输出结果如下,鼠标+触摸混合操作时MouseUp事件被吞了

我们用Snoop抓事件列表,Grid层鼠标按下后就没有后续了:

有意思的是,鼠标重新按下抬起时,是有正常的MouseDown、MouseUp事件触发,所以只是之前那一次MouseUp未触发:

然后找了台Surface,使用鼠标+触笔按上面路径验证,也是有同样问题:

但是我发现使用触摸板+触笔,MouseUp事件正常触发了。。。 

所以这WPF框架问题,还区分鼠标、触摸板?我们看TouchPad设备的原理:标识输入设备 - Windows apps | Microsoft Learn触控板交互 - Windows apps | Microsoft Learn,触摸板可以实现鼠标+多点触摸的功能,但单指操作时并不是鼠标或者触摸,如果要区分的话就需要通过其它其它途径。比如这篇文章有说相比正常的鼠标操作,触摸板返回鼠标消息时GetMessageExtraInfo()函数返回值是0: 如何区分触摸板和鼠标设备生成的WM_MOUSE***消息?-腾讯云开发者社区-腾讯云

这个问题目前没有解决方案,上面跨进程设置父子窗口导致鼠标失效的问题,可以在触摸事件输入后判断上一次操作是否为鼠标事件,然后手动触发相应鼠标抬起事件的业务逻辑。另外同一控件多设备混合输入场景比较少见,白板、批注等应用可能使用到,也可以同样修复补偿下,或者在设备输入事件封装内处理 WPF 设备输入事件封装 - 唐宋元明清2188 - 博客园