【问题标题】:Associate HID Touch Device with Pnp Monitor将 HID 触控设备与 Pnp 监视器关联
【发布时间】:2017-02-13 23:04:23
【问题描述】:

我正在开发一种工具,用于显示我们在工作中使用的系统上各种硬件组件的状态。目前,我们有 16 个触摸屏显示器(全部由 3M 提供)插入 Windows 10 盒子。我需要验证任何给定的显示器是否具有被 Windows 识别的关联触摸屏。这是为了评估系统是否存在任何硬件故障,例如电缆损坏、USB 端口损坏、显示器损坏等。我们看到的比我们愿意承认的要多,通常显示器的显示器可以正常工作,但两端的 USB 控制器退出并需要通过拔出/重新插入来重置

很遗憾,由于工作限制,我的代码发布将受到限制。

我可以枚举通过winapi的EnumDisplayDevicesEnumerateDisplayMonitors插入系统的所有监视器。我可以使用HIDApi 构建所有 HID 触摸屏设备的列表。

如果可能的话,我不知道从哪里可以将这两件事联系在一起。我的第一个想法是 HID 设备信息应该具有某种由调用 EnumDisplayDevices 和 EnumerateDisplayMonitors 的结果共享的标识符,但我没有发现这种情况。另一种可能性是将监视器的坐标/大小与一个触摸控制器负责的区域进行比较。同样,不确定这是否可能。

简而言之,有没有办法通过 c++ 将 Touch 设备与其对应的监视器关联起来?

【问题讨论】:

  • 我不是这方面的专家,但在 GitHub 上查看 HIDApi 的源代码时,我注意到它使用 SetupDiEnumDeviceInterfaces 调用来枚举 HID 设备。不能使用相同的 API 来检索监视器吗?使用不同的 InterfaceClassGuid ?
  • 我搞砸了 HIDApi,并能够根据您的建议生成监视器列表@Steeve。我通过这种方式获得了与 EnumerateDisplayMonitors 和 EnumDisplayDevices 相同的信息。问题仍然是如何验证给定的 Touch 设备对应于显示设备。 Device Installation Functions 毛茸茸的。在设备路径、VID 和 PID 之外,是否还有另一个我应该寻找的标识符?
  • 环顾四周(例如this 答案)对我来说似乎是Windows 进行了关联,理论上您也可以将输入重新分配给另一个显示器...无论如何看看答案,有一个这表示关联存储在HKLM/Software/Microsoft/Wisp 下的注册表中。可能会有所帮助。
  • @Steeve,看起来这将是解决方案。谢谢!!

标签: c++ windows hid touchscreen


【解决方案1】:

我认为您很幸运,该驱动程序后缀与您的显示器配置相匹配。在我的 Windows 10 多显示器设置中,当我按照您的描述在驱动程序条目中使用此数字查找它们时,我得到了错误的显示。

将 HID 设备与显示器关联的可靠方法似乎是:

  1. 拨打GetRawInputDeviceList()获取HID设备
  2. 调用GetRawInputDeviceInfo()RIDI_DEVICEINFO 以确定UsageUsagePage
  3. 使用RIDI_DEVICENAME 调用GetRawInputDeviceInfo() 以获取\\\\?\\HID#VID_0EEF&PID_7200&Col01#6&152cc7f9&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} 形式的设备字符串
  4. 在注册表中查询HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wisp\Pen\Digimon 的映射表并查找显示设备名称。在我的情况下,HID 名称都以20- 为前缀,但其余部分似乎与GetRawInputDeviceInfo() 查询的名称完全匹配。作为万一没有匹配的后备方法,我还将中间部分解析为 Clay Brooks 在他的回答中描述的。
  5. 在循环中调用EnumDisplayDevices(),为lpDevice 使用空指针,为dwFlags 使用0,直到函数返回零。
  6. 在每次循环迭代中,再次调用EnumDisplayDevices(),当前设备为lpDeviceEDD_GET_DEVICE_INTERFACE_NAMEdwFlags,并观察到它以\\\\?\\DISPLAY#ELO2243#5&607b301&0&UID24833#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7} 的形式返回DeviceID
  7. 循环直到找到 HID 显示匹配并获取由“外部”EnumDisplayDevices() 调用返回的DeviceName,它应该类似于\\.\DISPLAY3

【讨论】:

    【解决方案2】:

    根据 cmets 中的建议并深入研究注册表,我找到了一种将 Touch 控制器链接到监视器的方法。

    使用 HIDApi,您可以轮询系统并找到您需要监控的所有触控控制器的列表。我按我们正在使用的监视器的 VID 进行过滤。路径的示例返回值如下所示:

    "\\?\hid#vid_0596&pid_0520&col02#8&33d9e616&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"

    粗体部分可用于链接到 HKLM/Software/Microsoft/Wisp/Pen/Digimon 中的条目。一个示例条目是这样的:

    "\\?\HID#VID_0596&PID_0520&Col03#8&33d9e616&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}" "\\?\DISPLAY#MSY1C2B# 7&1083071f&0&UID524#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}"

    第一个粗体匹配通过 HIDApi 找到的数据,第二组粗体(监视器名称和 UID)列在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY 中。在此处,您可以使用监视器名称和 UID 的组合来查找驱动程序条目。下面是一个示例驱动程序条目:

    {4d36e96e-e325-11ce-bfc1-08002be10318}\0010

    最后一个粗体数字可用于匹配从 EnumDisplayDevices() 返回的 DeviceID。下面是一个示例 DeviceID:

    “监视器\MSY1C2B\{4d36e96e-e325-11ce-bfc1-08002be10318}\0010”。

    然后您可以使用此粗体部分来匹配从 EnumDisplayMonitors() 返回的监视器的名称。

    【讨论】:

    • 修改注册表后,如何在不拔下 HID 平板的情况下实际应用映射?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 2019-10-25
    • 2016-06-23
    • 1970-01-01
    相关资源
    最近更新 更多