读 WPF 源代码笔记 从 WM_POINTER 消息到 Touch 事件
内容提要
本文介绍了在WPF底层如何从Win32的消息循环中获取WM_POINTER消息,并将其转换为触摸事件的参数。文章分为两个部分,第一部分介绍了如何从Win32消息循环中获取WM_POINTER消息并转换为输入坐标点,第二部分介绍了WPF框架如何安排这些处理逻辑并与WPF框架进行对接。在WPF中,触摸初始化是在PointerTabletDeviceCollection.cs中开始的,通过调用GetPointerDevices方法进行初始化获取设备数量,然后调用GetPointerDeviceProperties方法获取设备属性信息。在HwndSource.cs中,根据配置参数决定是否使用Pointer消息处理的HwndPointerInputProvider类型。在HwndPointerInputProvider的FilterMessage方法中,根据消息类型进行处理,调用GetRawPointerDeviceData方法获取原始触摸信息,并进行解析处理。最后,通过关联设备和生成原始触摸数据,将触摸消息转换为WPF的输入数据。
关键要点
-
本文介绍了如何从Win32消息循环中获取WM_POINTER消息并转换为WPF触摸事件参数。
-
文章分为两个部分:第一部分讨论Win32程序如何处理WM_POINTER消息,第二部分讨论WPF框架如何处理这些逻辑。
-
在Win32应用程序中,有三种方式处理Pointer消息,分别为获取ptPixelLocationRaw、ptHimetricLocationRaw和原始触摸信息。
-
方式1通过ptPixelLocationRaw获取屏幕坐标,但精度较低,适合简单应用。
-
方式2使用ptHimetricLocationRaw获取更高精度的触摸点,但需要额外的坐标转换。
-
方式3获取原始触摸信息,适合需要高控制的应用,但处理复杂。
-
WPF框架通过PointerTabletDeviceCollection.cs初始化触摸设备,调用GetPointerDevices和GetPointerDeviceProperties获取设备信息。
-
WPF使用HwndPointerInputProvider处理WM_POINTER消息,FilterMessage方法根据消息类型进行处理。
-
在处理WM_POINTER消息时,WPF通过GetRawPointerDeviceData获取原始触摸信息并进行解析。
-
WPF通过PointerData类聚合指针数据,并根据pointerId获取触摸或笔的信息。
-
WPF将获取到的原始触摸数据转换为窗口坐标系,并兼容WISP获取的数据格式。
-
最终,WPF将生成的原始指针信息传递给输入管理器以启动事件链。
延伸问答
WPF如何处理WM_POINTER消息?
WPF通过HwndPointerInputProvider类处理WM_POINTER消息,使用FilterMessage方法过滤并处理输入数据。
WM_POINTER消息的处理方式有哪些?
WM_POINTER消息的处理方式有三种:获取ptPixelLocationRaw、ptHimetricLocationRaw和原始触摸信息,分别适用于不同精度需求的应用。
WPF如何初始化触摸设备?
WPF通过PointerTabletDeviceCollection类调用GetPointerDevices和GetPointerDeviceProperties方法来初始化触摸设备。
如何从WM_POINTER消息获取触摸事件参数?
通过调用GetRawPointerDeviceData方法获取原始触摸信息,并解析这些信息以生成WPF的输入数据。
WPF中如何处理触摸设备的属性信息?
WPF通过GetPointerDeviceProperties方法获取触摸设备的属性信息,并将其映射到WPF的定义属性。
WM_POINTER消息的设计有什么优势?
WM_POINTER消息设计为只发送PointerId,具体数据通过GetPointerInfo获取,这样可以减少消息堆积,提高系统性能。