C++ 将HID触摸设备与Pnp监视器关联

C++ 将HID触摸设备与Pnp监视器关联,c++,windows,hid,touchscreen,C++,Windows,Hid,Touchscreen,我正在开发一个工具,可以显示我们在工作中使用的系统上各种硬件组件的状态。目前,我们有16个触摸屏显示器(全部由3M公司提供)插在一个Windows 10机箱上。我需要验证任何给定的监视器是否具有windows可识别的关联触摸屏。这是为了评估系统是否存在任何硬件故障,即电缆损坏、USB端口损坏、显示器损坏等。我们看到的情况比我们想承认的要多,通常情况下,显示器工作正常,但两端的USB控制器都会断开,需要通过拔出/插回来重置 不幸的是,由于工作限制,我的代码发布将受到限制 我可以通过winapi和枚

我正在开发一个工具,可以显示我们在工作中使用的系统上各种硬件组件的状态。目前,我们有16个触摸屏显示器(全部由3M公司提供)插在一个Windows 10机箱上。我需要验证任何给定的监视器是否具有windows可识别的关联触摸屏。这是为了评估系统是否存在任何硬件故障,即电缆损坏、USB端口损坏、显示器损坏等。我们看到的情况比我们想承认的要多,通常情况下,显示器工作正常,但两端的USB控制器都会断开,需要通过拔出/插回来重置

不幸的是,由于工作限制,我的代码发布将受到限制

我可以通过winapi和枚举插入系统的所有监视器。我能够建立一个列表的所有HID触摸屏设备使用

从这里开始,如果可能的话,我没有方向去把这两件事联系起来。我的第一个想法是HID设备信息应该有某种标识符,由调用EnumDisplayDevices和EnumeratDisplayMonitors的结果共享,但我没有发现这种情况。另一种可能是将显示器的坐标/大小与其中一个触摸控制器负责的区域进行比较。同样,我也不确定这是否可行


简而言之,有没有办法通过C++将触摸设备和相应的监视器联系起来呢?

< P>在评论的建议和更深的注册表之后,我找到了一种将触摸控制器连接到监视器的方法。 使用HIDApi,您可以轮询系统并找到需要监控的所有触摸控制器的列表。我通过我们正在使用的监视器的视频进行过滤。路径的示例返回值如下所示:

“\?\hid#vid#U 0596&pid#U 0520&col02#8&33d9e616&0&0001{4d1e55b2-f16f-11cf-88cb-001111000030}”

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

“\?\HID\VID\u 0596&PID\u 0520&Col038&33d9e616&0&0002{4d1e55b2-f16f-11cf-88cb-001111000030}”\?\DISPLAYMSY1C2B7&108307f&UID524\35e6f07f-ee97-a90-a7beaf76”

第一个粗体与通过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()返回的监视器名称。

我认为您很幸运,这个驱动程序后缀与您的监视器配置匹配。在我的Windows 10多显示器设置中,如您所述,当我在驱动程序条目中使用此编号查找显示器时,显示错误

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

  • 调用
    GetRawInputDeviceList()
    获取HID设备
  • 使用
    RIDI\u DEVICEINFO
    调用
    GetRawInputDeviceInfo()
    ,以确定
    用法和
    UsagePage
  • 使用
    RIDI\u DEVICENAME
    调用
    GetRawInputDeviceInfo()
    ,以获取格式为
    \\\\?\\HID\VID\u 0EEF&PID\u 7200&Col01 6&152cc7f9&1&0000{4dee55b2-f16f-11cf-88cb-001111000030}的设备字符串
  • 在注册表中查询映射表,地址为
    HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\Wisp\Pen\Digimon
    ,并查找显示设备名称。在我的例子中,HID名称的前缀都是
    20-
    ,但剩下的部分似乎与
    GetRawInputDeviceInfo()
    查询的名称完全匹配。作为一种在没有匹配的情况下的后备方法,我还分析了Clay Brooks在回答中描述的中间部分
  • 在循环中调用
    EnumDisplayDevices()
    ,并为
    lpDevice
    使用空指针,为
    dwFlags
    使用0,直到函数返回零为止
  • 在每个循环迭代中,再次调用
    EnumDisplayDevices()
    ,当前设备为
    lpDevice
    EDD\u GET\u device\u INTERFACE\u NAME
    ,以
    dwFlags
    的形式返回
    DeviceID
    ,格式为
    \\\\\\?\\DISPLAY\35; ELO2243\5&607b301&0&UID24833\f475f-ee97-4a90-b076-33f5a7}
  • 循环直到找到HID显示匹配项,并获取“外部”EnumDisplayDevices()调用返回的
    DeviceName
    ,该调用应类似于
    \\。\DISPLAY3

  • 我不是这方面的专家,但在GitHub上查看HIDApi的源代码时,我注意到它使用SetupDienumDeviceInterface调用枚举HID设备。不能使用相同的API来检索监视器吗?使用不同的InterfaceClassGuid?我搞乱了HIDApi,能够根据您的建议@Steeve生成一个监视器列表。我通过这种方式获得了与EnumeratDisplayMonitors和EnumeratDisplayDevices相同的信息。问题仍然是如何验证给定的触摸设备是否对应于显示设备。你的头发很多毛。在设备路径、VID和PID之外,是否还有另一个我应该查找的标识符?环顾四周(例如,答案)对我来说,Windows似乎没有关联,理论上,您也可以将输入重新分配给另一个显示器。。。不管怎么说,看看答案,有一个说关联存储在注册表中的
    HKLM/Software/Microsoft/Wisp
    下。可能会有帮助。@Steeve,看起来像是w