Native way to get the feature report descriptor of HID device?

老子叫甜甜 提交于 2019-12-06 06:14:11
sansuiso

Ok, finally I've got something (almost completely) functional. As inferred by mcoill, I used the HidP_xxx() family of functions, but it needs a little bit of data preparation first.

I based my solution on this example code that targets USB joysticks and adapted it to touch digitizer devices. If someone else also gets confused by the online doc, here are the required steps involved in the process:

  1. registering the application for a Raw Input device at launch. This is done by calling the function RegisterRawInputDevice(&Rid, 1, sizeof(Rid)), where Rid is a RAWINPUTDEVICE with the following properties set (in order to get a touch digitizer) :

    Rid.usUsage = 0x04;
    Rid.usUsagePage = 0x0d;
    Rid.dwFlags = RIDEV_INPUT_SINK;
    
  2. registering a callback OnInput(LPARAM lParam) for the events WM_INPUT since the Rid device will generate this type of events;

  3. the OnInput(LPARAM lParam) method will get the data from this event in two steps:

    // 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));
    
  4. it then calls a parsing method that creates the HIDP_PREPARSED_DATA structure required by the lookup functions:

    // 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);
    

The preparsed data is split into capabilities:

    // 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);

And capabilities can be asked for their value:

    // 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);

Wouldn't HidP_GetPReparsedData(...), HidP_GetValueCaps(HidP_Feature, ...) and their ilk give you enough information without having to get the raw feature report?

HIDClass Support Routines on MSDN

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!