I am trying to get the touch coordinates from precision touchpads with C++ in Win10 with the program running in background.
Rawinput can get data in background.
I can get the data with these usage id and pages from microsoft :
Member Description Page ID Mandatory/Optional
X X coordinate of contact position 0x01 0x30 Mandatory for T Optional for C
Y Y coordinate of contact position 0x01 0x31 Mandatory for T Optional for C
I can put the two of them together with HIDP_functions, from this answer .
case WM_INPUT: {
UINT dwSize;
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
LPBYTE lpb = new BYTE[dwSize];
if (lpb == NULL) {
return 0;
}
RAWINPUT* raw = (RAWINPUT*)lpb;
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_PREPARSEDDATA, NULL, &dwSize);
PHIDP_PREPARSED_DATA preparsedData = (PHIDP_PREPARSED_DATA)HeapAlloc(GetProcessHeap(), 0, dwSize);
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_PREPARSEDDATA, preparsedData, &dwSize);
HIDP_CAPS caps;
HidP_GetCaps(preparsedData, &caps);
USHORT capsLength = caps.NumberInputValueCaps;
PHIDP_VALUE_CAPS valueCaps = (PHIDP_VALUE_CAPS)HeapAlloc(GetProcessHeap(), 0, capsLength*sizeof(HIDP_VALUE_CAPS));
HidP_GetValueCaps(HidP_Input, valueCaps, &capsLength, preparsedData);
for (int i=0; i < capsLength; i++) {
CHAR value;
USHORT valuelength = valueCaps[i].BitSize * valueCaps[i].ReportCount;
HidP_GetUsageValueArray (HidP_Input, valueCaps[i].UsagePage, 0, valueCaps[i].NotRange.Usage, &value, valuelength, preparsedData, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
std::cout << valueCaps[i].UsagePage << " " << valueCaps[i].NotRange.Usage <<std::endl;
std::cout << value << std::endl;
switch(valueCaps[i].NotRange.Usage) {
case 0x30: // X-axis
std::cout << "X: " << value << std::endl;
break;
case 0x31: // Y-axis
std::cout << "y: " << value << std::endl;
break;
}
}
}
I compiled the code and touch my touchpad, but all the outputs are:
0 0
³
Have I done anything wrong? Does anyone have any idea?
A packet of minimal Contact ID, x, y, Contact, Scan may contain multiple Contact ID, x, y triplets for multiple points and then must be used valueCaps[i].LinkCollection from valueCaps[] array which increases from 1 for up to five points.
HidP_GetUsageValue
(
HidP_Input,
valueCaps[i].UsagePage,
valueCaps[i].LinkCollection, //** !!!!!
valueCaps[i].NotRange.Usage,
&value,
preparsedData,
(PCHAR)raw->data.hid.bRawData,
raw->data.hid.dwSizeHid
);
Coordinates are in array if valueCaps[i].UsagePage = 1 and valueCaps[i].NotRange.Usage = 0x30 (x), valueCaps[i].NotRange.Usage = 0x30 (y)
Very important are xLogicalMin, yLogicalMin, xLogicalMax, yLogicalMax in valueCaps[i] array
xLogicalMin = valueCaps[i].LogicalMin;
xLogicalMax = valueCaps[i].LogicalMax;
xPhysicalMin = valueCaps[i].PhysicalMin;
xPhysicalMax = valueCaps[i].PhysicalMax;
All allocated spaces must be correct released !!!!!
Pressing оп perimeter points of touchpad for initiate multiple functions, or cells of grid on touchpad as on ASUS NumberPad also with limited functions of capacitive and active pen, one finger flicks, moving along four sides of touchpad for scrolling / scale, moving cursor with one finger and click, press, press plus move, double click, click plus press second finger. Two finger operations count increased at finger space near or far possible with coordinates. With coordinates, times in "Scan" and contacts in "Contact" all possible complex gestures on touchpad are accessible.
Call of Your Program
HidP_GetUsageValueArray (HidP_Input, valueCaps[i].UsagePage, 0, valueCaps[i].NotRange.Usage, &value, valuelength, preparsedData, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
returns HIDP_STATUS_NOT_VALUE_ARRAY = 0xc011000b
In Array valueCaps[] on my notebook with PTP are valueCaps[i].UsagePage = 1 and valueCaps[i].NotRange.Usage = 0x30 / 0x31. You can use simple
HidP_GetUsageValue ( HidP_Input, valueCaps[i].UsagePage, 0, valueCaps[i].NotRange.Usage, &value, preparsedData, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid );
with 1 / 30h, 1 / 31h
corresponding to
_Must_inspect_result_ NTSTATUS __stdcall HidP_GetUsageValue( In HIDP_REPORT_TYPE ReportType, In USAGE UsagePage, _In_opt_ USHORT LinkCollection, In USAGE Usage, Out PULONG UsageValue, In PHIDP_PREPARSED_DATA PreparsedData, _In_reads_bytes_(ReportLength) PCHAR Report, In ULONG ReportLength );
and value ( UsageValue ) must be LONG !!!!!.
First value at WM_INPUT comes with UsagePage 0x0D Usage 0x51
Contact ID Uniquely identifies the contact within a given frame 0x0D 0x51 Mandatory
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.