Windows 获取HID设备的功能报告描述符的本机方法?

Windows 获取HID设备的功能报告描述符的本机方法?,windows,usb,hid,Windows,Usb,Hid,我们有一些HID设备(触摸数字化仪),可与内部研发工具进行通信。此工具解析来自设备的原始功能报告,以绘制触摸报告以及一些附加数据,这些数据存在于原始功能报告中,但被Windows 7的HID驱动程序过滤掉(例如,WM_touch消息中不存在压力数据) 然而,我们已经开始使用一些可能具有不同固件变体的设备,因此这些设备不共享相同的排序或字段长度,我需要修改我们的研发工具,以便它能够透明地适应所有设备 这些设备来自同一制造商(我们自己)并共享相同的设备信息,因此使用这些字段来区分不同的固件不是一个选

我们有一些HID设备(触摸数字化仪),可与内部研发工具进行通信。此工具解析来自设备的原始功能报告,以绘制触摸报告以及一些附加数据,这些数据存在于原始功能报告中,但被Windows 7的HID驱动程序过滤掉(例如,
WM_touch
消息中不存在压力数据)

然而,我们已经开始使用一些可能具有不同固件变体的设备,因此这些设备不共享相同的排序或字段长度,我需要修改我们的研发工具,以便它能够透明地适应所有设备

这些设备来自同一制造商(我们自己)并共享相同的设备信息,因此使用这些字段来区分不同的固件不是一个选项。我想做的是获取设备发送的HID功能报告描述符,并基于此信息动态更新我们的功能报告解析方法

但是,在浏览Windows API时,我没有找到正确的方法来调用以获取此描述符。到目前为止,我在MSDN上找到了,但我不确定下一步该怎么做。我能在结构中找到所需的信息吗?或者我需要调用完全不同的API吗


提前感谢您的帮助

HidP_GetPReparsedData(…)、HidP_GetValueCaps(HidP_Feature…)及其同类产品不必获取原始功能报告,就不会为您提供足够的信息吗


好的,我终于有了(几乎完全)功能性的东西。根据推断,我使用了
HidP_xxx()
函数系列,但首先需要做一点数据准备

我的解决方案就是基于这一点,以USB操纵杆为目标,并将其调整为触摸数字化仪设备。 如果其他人也对在线文档感到困惑,以下是流程中涉及的必要步骤:

  • 在启动时为原始输入设备注册应用程序。 这是通过调用函数
    registerarWinPutDevice(&Rid,1,sizeof(Rid))
    完成的,其中
    Rid
    是一个
    RAWINPUTDEVICE
    ,设置了以下属性(以便获得触摸式数字化仪):

  • 为事件
    WM_INPUT
    注册回调
    OnInput(LPARAM LPARAM)
    ,因为
    Rid
    设备将生成此类事件

  • OnInput(LPARAM LPARAM)
    方法将分两步从该事件获取数据:

    // Parse the raw input header to read its size.
    UINT bufferSize;
    GetRawInputData(HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
    
    // Allocate memory for the raw input data and retrieve it
    PRAWINPUT = (PRAWINPUT)HeapAlloc(GetProcessHeap(), 0, bufferSize);
    GetRawInputData(HRAWINPUT)lParam, RID_INPUT, rawInput /* NOT NULL */, &bufferSize, sizeof(RAWINPUTHEADER));
    
  • 然后,它调用一个解析方法,该方法创建查找函数所需的
    HIDP\u PREPARSED\u DATA
    结构:

    // Again, read the data size, allocate then retrieve
    GetRawInputDeviceInfo(rawInput->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize);
    PHIDP_PREPARSED_DATA preparsedData = (PHIDP_PREPARSED_DATA)HeapAlloc(heap, 0, bufferSize);
    GetRawInputDeviceInfo(rawInput->header.hDevice, RIDI_PREPARSEDDATA, preparsedData, &bufferSize);
    
  • 准备好的数据分为功能

        // Create a structure that will hold the values
        HidP_GetCaps(preparsedData, &caps);
        USHORT capsLength = caps.NumberInputValueCaps;
        PHIDP_VALUE_CAPS valueCaps = (PHIDP_VALUE_CAPS)HeapAlloc(heap, 0, capsLength*sizeof(HIDP_VALUE_CAPS));
        HidP_GetValueCaps(HidP_Input, valueCaps, &capsLength, preparsedData);
    
    而且,可以要求提供功能的价值:

        // Read sample value
        HidP_GetUsageValue(HidP_Input, valueCaps[i].UsagePage, 0, valueCaps[i].Range.UsageMin, &value, preparsedData, (PCHAR)rawInput->data.hid.bRawData, rawInput->data.hid.dwSizeHid);
    

    是的,那也是我的猜测。我以前找到过HidP_GetPreparsedData(),但被HidP_GetValueCaps()弄糊涂了。不过,我仍然需要找时间在示例应用程序(或我们工具的开发分支)中尝试它,以进行确认。完成后,我将更新问题。
        // Read sample value
        HidP_GetUsageValue(HidP_Input, valueCaps[i].UsagePage, 0, valueCaps[i].Range.UsageMin, &value, preparsedData, (PCHAR)rawInput->data.hid.bRawData, rawInput->data.hid.dwSizeHid);