在使用一些诡异的系统以及诡异的触摸框的时候,也许会出现 WPF 程序触摸失效,失效的本质原因是 Win32 层应用触摸失效。也许出现的问题是某个窗口设置 TopMost 然后插拔一些触摸设备等,这些行为,如果触摸设备太过诡异,也许就会让 Win32 窗口触摸失效。刚好 WPF 也是一个 Win32 窗口,此时的 WPF 也会触摸失效
这个方法因为过于强,我建议只有你在尝试过其他方法无法修复之后才能使用。本文的方法修复触摸是根据没有什么是重启解决不了的方法修复的,本文的方法将会使用反射调用 WPF 的代码,我仅仅有测试 .NET Framework 4.8 的框架里面的逻辑,这就意味着需要你在运行的设备上安装有 .NET Framework 4.8 框架,但是对于运行的 WPF 没有任何限制,可以使用 .NET Framework 4.5 甚至是 .NET Framework 4.0 的版本。当然,本文方法对于 .NET Core 3.1 和 .NET 5 同样生效
本文的核心逻辑就是调用 WispLogic 的 RegisterHwndForInput 和 UnRegisterHwndForInput 来实现重启触摸,但是没有真的结束触摸线程,因此不够彻底。而我自己基于开源的 WPF 框架也定制了可以从触摸线程都重启的强力版本,当然了,这个版本非开源的版本
在使用本文的方法之前,请确定你对触摸有足够的了解
如果你对触摸的了解很少,那么我推荐你先看以下博客
对于 Win32 应用来说,如果应用的触摸失效了,可以的解决方法是重新注册一次触摸,或者重启应用。而在 WPF 中,没有公开的方法可以让咱重启注册触摸,但是使用非公开的方法可以调用到。关于在 WPF 中的触摸调用细节请看 WPF 触摸到事件 和 WPF 通过 InputManager 模拟调度触摸事件
重启注册触摸的步骤就是先反注册,然后再次注册。分别调用的是 WispLogic 的 UnRegisterHwndForInput 和 RegisterHwndForInput 方法,以下是步骤
在 WPF 中,可以使用下面代码获取 StylusLogic 对象
在没有开启 Pointer 的情况下,这里的 StylusLogic 就是 WispLogic 对象,因为 WispLogic 的定义如下
在 Win10 中,大多数的触摸失效问题,都可以通过开启 Pointer 消息解决。而在 .NET 5 中,修复了 WPF 使用 WM_Pointer 消息在高 DPI 下的兼容触摸。如何开启 Pointer 消息请看 WPF dotnet core 如何开启 Pointer 消息的支持
在获取到 WispLogic 就可以通过反射调用 RegisterHwndForInput 和 UnRegisterHwndForInput 方法来重启触摸
通过开源的 WPF 代码可以看到两个方法的定义如下
这里的 InputManager 可以使用 InputManager.Current 获取,而 PresentationSource 可以使用 PresentationSource.FromVisual(this)
获取,上面的 this
需要一个在界面显示的元素
而 HwndSource 可以使用下面代码获取
先调用 UnRegisterHwndForInput 禁用触摸,然后调用 RegisterHwndForInput 打开触摸
更新版本的使用 WPF 最简逻辑实现多指顺滑的笔迹书写 的代码放在 github 和 gitee 欢迎小伙伴访问
本文的方法不能解决内部逻辑调用问题的触摸失效问题,也不能解决太过诡异的系统的触摸失效问题。本文的重启触摸的方法的执行速度是很慢的
以上方法也是有缺点的,使用了上面方法之后,就不能使用 高性能 DynamicRenderer 书写 的方式。解决 DynamicRenderer 丢失的方法就是重新注册一次 StylusPlugIn 元素
更多触摸请看 WPF 触摸相关 更多笔迹相关请看
- WPF 渲染原理
- 高性能笔迹原理
- WPF 高性能笔
- WPF 高速书写 StylusPlugIn 原理
- WPF 最小的代码使用 DynamicRenderer 书写
- WPF 使用 Composition API 做高性能渲染
- WPF 使用 Win2d 渲染
- win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl
- WPF 最简逻辑实现多指顺滑的笔迹书写
- WPF 笔迹触摸点收集工具
- WPF 实现自定义的笔迹橡皮擦
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。 欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。