概要
在大多数系统中,触摸屏和触控笔的使用并不常见,相关的解决方案也较少。在Windows系统中,触摸屏和触控笔通常通过USB连接,并默认映射到主屏幕。如果没有进行额外设置,以下两种场景可能导致问题:
- 主屏幕为非触控屏幕,扩展屏幕为触控屏幕,导致在扩展屏上的操作实际影响主屏幕。
- 主屏幕为触控屏幕,扩展屏幕为非触控屏幕,需要将触控和笔操作映射到扩展屏幕。
本文介绍了一种通过代码将触控/笔操作映射到扩展屏幕的方法,并确保设置实时生效,对用户透明。文末提供了源码下载链接。
分析
上述两种场景表明,需要一种方法或工具来校正触控屏的笔/消息,以对应正确的屏幕。
解决办法
1. 使用系统自带的MultiDigiMon.exe工具
- 通过“控制面板” -> “平板电脑设置”进行设置。
- 使用命令行(以管理员权限运行cmd):
C:\Windows\System32>MultiDigiMon.exe -touch C:\Windows\System32>MultiDigiMon.exe -pen
优点:直接调用系统软件设置,不要更多的代码投入
缺点:MultiDigiMon.exe需要用户手动确认,不能自动处理
2. 使用代码自动校正
感谢显示器与触摸屏的一对一绑定原理和解析的作者,通过将其思路转化为C#代码,实现了实时生效的解决方案。
2.1 找到当前触控/笔的设备路径
触控设备通过HID通信,根据usage
过滤设备:
- 触控设备:
0x04
- 笔设备:
0x02
以下是获取设备路径的C#代码示例:
/// <summary>
/// 获取触控屏设备
/// </summary>
/// <param name="isTouch">true:触控 false:笔</param>
/// <returns></returns>
public static IntPtr GetTouchDeviceHandle(bool isTouch)
{
var usage = isTouch
? Native.NativeMethods.TouchScreenUsage//0x04
: Native.NativeMethods.PenUsage;//0x02
uint count = 0;
NativeMethods.GetRawInputDeviceList(null, out count, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST)));
RAWINPUTDEVICELIST[] list = new RAWINPUTDEVICELIST[count];
if (GetRawInputDeviceList(list, out count, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST))) != 0)
{
foreach (RAWINPUTDEVICELIST device in list)
{
if (ValidateDevice(device.hDevice,usage))
{
return device