精密触摸板的X和Y坐标与原始输入

时间:2017-10-29 21:51:58

标签: c++ windows hid raw-input touchpad

背景

我试图在Win10中使用C ++从精密触摸板获取触摸坐标,程序在后台运行。

研究

Rawinput可以在后台获取数据。

我可以使用microsoft中的这些使用ID和页面获取数据:

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

我可以将其中两个与HIDP_functions放在一起,来自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;
        }
    }

}

问题

我编译了代码并触摸了我的触摸板,但所有输出都是:

0  0
³

我做错了什么吗?有没有人有任何想法?

2 个答案:

答案 0 :(得分:0)

最小联系人ID,x,y,Contact,Scan的数据包可能包含多个联系人ID,x,y三元组(用于多个点),因此必须使用 valueCaps []数组中的valueCaps [i] .LinkCollection,该值从1开始增加多达五个点。

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

如果valueCaps [i] .UsagePage = 1且坐标为数组 valueCaps [i] .NotRange.Usage = 0x30(x),valueCaps [i] .NotRange.Usage = 0x30(y)

valueCaps [i]数组中的xLogicalMin,yLogicalMin,xLogicalMax,yLogicalMax非常重要

    xLogicalMin = valueCaps[i].LogicalMin;
    xLogicalMax = valueCaps[i].LogicalMax;
    xPhysicalMin = valueCaps[i].PhysicalMin;
    xPhysicalMax = valueCaps[i].PhysicalMax;

所有分配的空间必须正确释放!!!!!

按下触摸板的外围点以启动多种功能,或者像华硕NumberPad一样在触摸板上的网格单元也具有有限的电容和有源笔功能,一根手指轻拂,沿着触摸板的四个侧面移动以滚动/缩放,移动用一根手指光标单击,然后按,再按加号移动, 双击,单击加号并按第二根手指。在有坐标的情况下,在手指空间接近或远离时,两个手指的操作计数增加。通过坐标,可以访问“扫描”中的时间以及“联系人”中的联系人,从而可以访问触摸板上的所有可能的复杂手势。

答案 1 :(得分:-1)

程序调用

HidP_GetUsageValueArray(HidP_Input,valueCaps [i] .UsagePage,0,valueCaps [i] .NotRange。用法,&value,valuelength,preparsedData,(PCHAR)raw-> data.hid.bRawData,raw-> data.hid。 dwSizeHid);

返回HIDP_STATUS_NOT_VALUE_ARRAY = 0xc011000b

在我带有PTP的笔记本上,数组valueCaps []中有valueCaps [i] .UsagePage = 1和valueCaps [i] .NotRange.Usage = 0x30 / 0x31。您可以使用简单的

HidP_GetUsageValue (     HidP_Input,     valueCaps [i] .UsagePage,     0,     valueCaps [i] .NotRange。用法,     &值,     preparsedData,     (PCHAR)原始-> data.hid.bRawData,     raw-> data.hid.dwSizeHid );

有1 / 30h,1 / 31h

对应

_Must_inspect_result_ NTSTATUS __stdcall HidP_GetUsageValue(     中HIDP_REPORT_TYPE报告类型,     使用情况用法页面中,     _In_opt_ USHORT LinkCollection,     用法中,      Out PULONG UsageValue,      PHIDP_PREPARSED_DATA PreparsedData中,     _In_reads_bytes_(ReportLength)PCHAR报告,      In ULONG ReportLength     );

和值(UsageValue)必须是长!!!!!。

WM_INPUT的第一个值是UsagePage 0x0D用法0x51

联系人ID唯一标识给定框架内的联系人0x0D 0x51必填