来自GetRawInputDeviceList()的原始输入设备太多

时间:2011-07-30 04:38:05

标签: c winapi

之后

UINT lSize; 
GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, NULL, &lSize);
RID_DEVICE_INFO* lInfo = (RID_DEVICE_INFO*) malloc(lSize); 
GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, lInfo, &lSize);

我有9个设备:3个鼠标,3个键盘,3个隐藏设备。 我有一个鼠标,一个触摸板,两个键盘和一个操纵杆。

什么是剩菜?

另一件事,我不确定给定的信息是否正确:

//keyboard #1
cbSize = 32
dwType = 1
keyboard.dwType = 81
keyboard.dwSubType = 0
keyboard.dwKeyboardMode = 1
keyboard.dwNumberOfFunctionKeys = 12
keyboard.dwNumberOfIndicators = 3
keyboard.dwNumberOfKeysTotal = 101

//keyboard #2 //keyboard 2
cbSize = 32
dwType = 1
keyboard.dwType = 81
keyboard.dwSubType = 0
keyboard.dwKeyboardMode = 1
keyboard.dwNumberOfFunctionKeys = 12 //~15
keyboard.dwNumberOfIndicators = 3
keyboard.dwNumberOfKeysTotal = 265 //~110

//keyboard #3 //keyboard 1
cbSize = 32
dwType = 7
keyboard.dwType = 81
keyboard.dwSubType = 0
keyboard.dwKeyboardMode = 1
keyboard.dwNumberOfFunctionKeys = 12
keyboard.dwNumberOfIndicators = 3
keyboard.dwNumberOfKeysTotal = 101 //~110


//mouse #1 //the touchpad
cbSize = 32
dwType = 0
mouse.dwId = 2
mouse.dwNumberOfButtons = 2
mouse.dwSampleRate = 60
mouse.fHasHorizontalWheel = 0 //1

//mouse #2 //the mouse
cbSize = 32
dwType = 0
mouse.dwId = 256
mouse.dwNumberOfButtons = 9 //5 buttons
mouse.dwSampleRate = 0 // the range is [-170,+170]
mouse.fHasHorizontalWheel = 0 //1

//mouse #3
cbSize = 32
dwType = 0
mouse.dwId = 32
mouse.dwNumberOfButtons = 3
mouse.dwSampleRate = 100
mouse.fHasHorizontalWheel = 0

//hid device #1 //the joystick
cbSize = 32 
dwType = 2
hid.dwVendorId = 1699 
hid.dwProductId = 1124
hid.dwVersionNumber = 275
hid.usUsagePage = 1
hid.usUsage = 4

//hid device #2
cbSize = 32
dwType = 2
hid.dwVendorId = 1452
hid.dwProductId = 545
hid.dwVersionNumber = 113
hid.usUsagePage = 12
hid.usUsage = 1

//hid device #3
cbSize = 32
dwType = 2
hid.dwVendorId = 1276
hid.dwProductId = 2049
hid.dwVersionNumber = 5649
hid.usUsagePage = 12
hid.usUsage = 1

所以我错了? 如果这些信息是正确的,那么它们的含义是什么? 谢谢你!

2 个答案:

答案 0 :(得分:6)

这是因为Windows创建的设备可以捕获多个设备(这是默认设备)通常是GetRawInputDeviceList(.........)

中的第一个设备

示例:

kb0 = real keyboard 1 & real keyboard 2
kb1 = real keyboard 1
kb2 = real keyboard 2

mouse0 = touchpad+mouse
mouse1 = touchpad
mouse2 = mouse

答案 1 :(得分:1)

我在示例应用程序中有以下从此问题派生的源代码段,因为我了解了HID USB设备和原始输入。我做了一个实验,我在Dell Latitude笔记本电脑上运行这个应用程序,它有一个键盘和两个鼠标输入设备,一个带两个按钮的触摸板和一个带两个按钮的操纵杆。

源代码段如下所示。此代码将HID设备列表提供到Visual Studio的“输出”窗格中,因为我在调试器中运行此示例,以便我可以检查各种数据字段。

我遇到的一个问题是,在调用函数GetRawInputDeviceInfo()时,使用RIDI_DEVICEINFO参数来检索RID_DEVICE_INFO结构的数据,我不得不初始化具有结构或函数大小的cbSize成员不会将设备信息填充到结构中。

HRESULT  hResult;
TCHAR    szTempOutput[256];

PRAWINPUTDEVICELIST pRawInputDeviceList;
UINT  uiNumDevices;
UINT  cbSize = sizeof(RAWINPUTDEVICELIST);

GetRawInputDeviceList(NULL, &uiNumDevices, cbSize);    
pRawInputDeviceList = (PRAWINPUTDEVICELIST)malloc(cbSize * uiNumDevices);   
GetRawInputDeviceList(pRawInputDeviceList, &uiNumDevices, cbSize);

hResult = StringCchPrintf(szTempOutput, STRSAFE_MAX_CCH, TEXT(" DeviceList Num Devices %d \n"), uiNumDevices);
if (SUCCEEDED(hResult))
{
    OutputDebugString(szTempOutput);
} else {
    // TODO: write error handler
}
TCHAR *psDwType [] = {
    TEXT("RIM_TYPEMOUSE"),
    TEXT("RIM_TYPEKEYBOARD"),
    TEXT("RIM_TYPEHID")
};

for (int i = 0; i < uiNumDevices; i++) {
    UINT             cbDataSize = 1000;
    TCHAR            *pType = TEXT("Unknown");
    RID_DEVICE_INFO  DevInfo = {0};
    char             pData[1000] = {0};

    // For each device get the device name and then the device information
    cbDataSize = sizeof(pData);
    GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, pData, &cbDataSize);
    DevInfo.cbSize = cbDataSize = sizeof(DevInfo);  // specify the buffer size
    GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &DevInfo, &cbDataSize);

    if (pRawInputDeviceList[i].dwType <= sizeof(psDwType)/sizeof(psDwType[0]))
        pType = psDwType[pRawInputDeviceList[i].dwType];

    hResult = StringCchPrintf(szTempOutput, STRSAFE_MAX_CCH, TEXT(" DeviceList %d  dwType = %d, %d (%s) name = %s\n"),
        i, pRawInputDeviceList[i].dwType, DevInfo.dwType, pType, pData);
    if (SUCCEEDED(hResult))
    {
        OutputDebugString(szTempOutput);
    } else {
        // TODO: write error handler
    }
    switch (DevInfo.dwType) {
        case RIM_TYPEHID:
            hResult = StringCchPrintf(szTempOutput, STRSAFE_MAX_CCH, TEXT("   HID  dwVendorId = 0x%x dwProductId = 0x%x dwVersionNumber = 0x%x\n"),
                DevInfo.hid.dwVendorId, DevInfo.hid.dwProductId, DevInfo.hid.dwVersionNumber);
            if (SUCCEEDED(hResult))
            {
                OutputDebugString(szTempOutput);
            } else {
                // TODO: write error handler
            }
            break;
        case RIM_TYPEMOUSE:
            hResult = StringCchPrintf(szTempOutput, STRSAFE_MAX_CCH, TEXT("   Mouse  dwId = 0x%x dwNumButtons = %d \n"),
                DevInfo.mouse.dwId, DevInfo.mouse.dwNumberOfButtons);
            if (SUCCEEDED(hResult))
            {
                OutputDebugString(szTempOutput);
            } else {
                // TODO: write error handler
            }
            break;
        case RIM_TYPEKEYBOARD:
            hResult = StringCchPrintf(szTempOutput, STRSAFE_MAX_CCH, TEXT("   Keyboard  dwType = 0x%x dwSubType = 0x%x dwKeyboardMode = 0x%x\n"),
                DevInfo.keyboard.dwType, DevInfo.keyboard.dwSubType, DevInfo.keyboard.dwKeyboardMode);
            if (SUCCEEDED(hResult))
            {
                OutputDebugString(szTempOutput);
            } else {
                // TODO: write error handler
            }
            break;
    }
}
free (pRawInputDeviceList);

我跑了两次这个来源。第一次运行是笔记本电脑的原样。第二次运行是在将Logitech双按钮滚轮(作为第三或中心按钮操作)激光鼠标插入USB端口之后。设备信息似乎将Logitech视为三键鼠标,另外两个鼠标为双键鼠标。似乎两个不同的鼠标输入设备被视为单个设备,内置键盘和内置鼠标在设备列表中有两个不同的条目,其中Logitech鼠标物理插入USB端口仅添加单个条目列表。

 DeviceList Num Devices 4 
 DeviceList 0  dwType = 1, 1 (RIM_TYPEKEYBOARD)
   name = \??\Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
   Keyboard  dwType = 0x51 dwSubType = 0x0 dwKeyboardMode = 0x1
 DeviceList 1  dwType = 1, 1 (RIM_TYPEKEYBOARD)
   name = \??\ACPI#PNP0303#4&2f94427b&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
   Keyboard  dwType = 0x4 dwSubType = 0x0 dwKeyboardMode = 0x1
 DeviceList 2  dwType = 0, 0 (RIM_TYPEMOUSE)
   name = \??\Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
   Mouse  dwId = 0x2 dwNumButtons = 2 
 DeviceList 3  dwType = 0, 0 (RIM_TYPEMOUSE)
   name = \??\ACPI#PNP0F13#4&2f94427b&0#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
   Mouse  dwId = 0x2 dwNumButtons = 2 



 DeviceList Num Devices 5 
 DeviceList 0  dwType = 0, 0 (RIM_TYPEMOUSE)
   name = \??\HID#Vid_046d&Pid_c00e#6&37d208f8&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
   Mouse  dwId = 0x100 dwNumButtons = 3 
 DeviceList 1  dwType = 1, 1 (RIM_TYPEKEYBOARD)
   name = \??\Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
   Keyboard  dwType = 0x51 dwSubType = 0x0 dwKeyboardMode = 0x1
 DeviceList 2  dwType = 1, 1 (RIM_TYPEKEYBOARD)
   name = \??\ACPI#PNP0303#4&2f94427b&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
   Keyboard  dwType = 0x4 dwSubType = 0x0 dwKeyboardMode = 0x1
 DeviceList 3  dwType = 0, 0 (RIM_TYPEMOUSE)
   name = \??\Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
   Mouse  dwId = 0x2 dwNumButtons = 2 
 DeviceList 4  dwType = 0, 0 (RIM_TYPEMOUSE)
   name = \??\ACPI#PNP0F13#4&2f94427b&0#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
   Mouse  dwId = 0x2 dwNumButtons = 2 

查看&#34;鼠标和其他指针设备下的设备管理器实用程序&#34;我看到两个设备,&#34;罗技USB滚轮鼠标&#34;和一个&#34; PS / 2兼容鼠标&#34;。 Logitech鼠标显示设备实例ID为HID\VID_046D&PID_C00E\6&37D208F8&0&0000,PS / 2鼠标显示设备实例ID为ACPI\PNP0F13\4&2F94427B&0

Logitech鼠标也显示在&#34;人机接口设备&#34;设备ID为USB\VID_046D&PID_C00E\5&38366AA3&0&1的列表。

有一个&#34;标准101/102键&#34;键盘中的键盘&#34;键盘&#34;设备ID为ACPI\PNP0303\4&2F94427B&0

的列表

当我从USB端口拔下Logitech鼠标时,当我再次运行应用程序时,第五个设备从列表中消失,我回到了四个设备的原始列表。

最后,我在SAM4S制造的Titan-150销售点终端上运行了该实用程序。终端配有触摸屏和磁条读取器(MSR)。此外,我将一个Logitech键盘插入其中一个USB端口。

 DeviceList Num Devices 6

 Dev No.: 0  dwType = 2, 2 (RIM_TYPEHID)
   name = \\?\HID#DCO9000&Col02#6&178d2043&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}
   HID  dwVendorId = 0x14e1 dwProductId = 0x9000 dwVersionNumber = 0x0

 Dev No.: 1  dwType = 1, 1 (RIM_TYPEKEYBOARD)
   name = \\?\Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
   Keyboard  dwType = 0x51 dwSubType = 0x0 dwKeyboardMode = 0x1

 Dev No.: 2  dwType = 1, 1 (RIM_TYPEKEYBOARD)
   name = \\?\HID#VID_1C8A&PID_0203#7&1af96a6b&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
   Keyboard  dwType = 0x51 dwSubType = 0x0 dwKeyboardMode = 0x1

 Dev No.: 3  dwType = 1, 1 (RIM_TYPEKEYBOARD)
   name = \\?\HID#VID_046D&PID_C312#7&32af08f0&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
   Keyboard  dwType = 0x51 dwSubType = 0x0 dwKeyboardMode = 0x1

 Dev No.: 4  dwType = 0, 0 (RIM_TYPEMOUSE)
   name = \\?\Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
   Mouse  dwId = 0x2 dwNumButtons = 2

 Dev No.: 5  dwType = 0, 0 (RIM_TYPEMOUSE)
   name = \\?\HID#DCO9000&Col01#6&178d2043&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}
   Mouse  dwId = 0x80 dwNumButtons = 3

查看list of USB vendor ids available from linux-usb.org我可以看到Logitech键盘,设备#3,供应商ID为046d,PenMount 5000 Touch Controller,设备#0,供应商ID为14e1。看起来触摸控制器使用另外两个USB设备,设备#4和设备#5,它们分别作为双键鼠标和三键鼠标呈现给Windows应用程序。这两个USB鼠标设备(虚拟设备)提供了一种方法,通过鼠标消息为应用程序提供触摸屏表面的触摸,从而允许在终端上使用标准Windows应用程序。

然而,还有另一个设备#2,供应商ID为1c8a,其供应商ID不在linus-usb.org列表中。该设备似乎是MSR设备,其被配置为充当楔形键盘设备,将卡刷卡数据作为一系列键盘消息推送到应用程序。 MSR确实充当了楔形键盘设备。使用带有记事本应用程序且带焦点的磁条卡尝试时,持卡人帐户数据将显示在记事本窗口中。