获取游戏手柄的按键输入

类别:VC语言 点击:0 评论:0 推荐:

//可以查看按游戏手柄按钮时的情况.

//USB接口的游戏手柄

//编译环境:Windows 2000 server+VC++ 6.0+Win2K DDK

#include <stdio.h>
#include <windows.h>
#include <setupapi.h>
#include <tchar.h>
extern "C"
{
#include <hidsdi.h>
}

void main()
{
 GUID HidGuid;

 // 查找本系统中HID类的GUID标识
 HidD_GetHidGuid(&HidGuid);
 _tprintf("系统中HID类的GUID标识为:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
   HidGuid.Data1,HidGuid.Data2 ,HidGuid.Data3 ,
   HidGuid.Data4[0],HidGuid.Data4[1],HidGuid.Data4[2],
   HidGuid.Data4[3],HidGuid.Data4[4],HidGuid.Data4[5],
   HidGuid.Data4[6],HidGuid.Data4[7]);
 
 // 准备查找符合HID规范的USB设备
 HDEVINFO hDevInfo = SetupDiGetClassDevs(&HidGuid,
           NULL,
           NULL,
           DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
 if (hDevInfo == INVALID_HANDLE_VALUE)
 {
  _tprintf("符合HID规范的USB设备发生错误\n");
  return;
 }

 _tprintf("正在查找可用的USB设备...\n");

 DWORD MemberIndex = 0;
 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
 BOOL bSuccess = FALSE;

 DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
 do
 {
  bSuccess = SetupDiEnumDeviceInterfaces(hDevInfo,
             NULL,
             &HidGuid,
             MemberIndex,
             &DeviceInterfaceData);
  if ((!bSuccess) && (GetLastError() == ERROR_NO_MORE_ITEMS))
  {
   if(MemberIndex == 0)
    _tprintf("抱歉,未找到可用的USB设备!\n");
   else
    _tprintf("没有更多的可用的USB设备!\n");

   SetupDiDestroyDeviceInfoList(hDevInfo);
   return;
  }
  _tprintf("找到了一个USB设备:\n");
  //若找到了一个USB设备,则获取该设备的细节信息
  PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData;
  DWORD Length = 0;
  
  SetupDiGetDeviceInterfaceDetail(hDevInfo,
          &DeviceInterfaceData,
          NULL,
          0,
          &Length,
          NULL);
  pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
  pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);  //MUST BE!!!

  if (!SetupDiGetDeviceInterfaceDetail(hDevInfo,
          &DeviceInterfaceData,
          pDeviceInterfaceDetailData,
          Length,
          NULL,
          NULL))
   _tprintf("查找路径设备时出错!\n");
  else
   _tprintf("设备路径:%s\n",pDeviceInterfaceDetailData->DevicePath );
  
  //打开设备句柄
  HANDLE hDeviceHandle = CreateFile(pDeviceInterfaceDetailData->DevicePath ,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            0,
            NULL);
  if (hDeviceHandle == INVALID_HANDLE_VALUE)
   _tprintf("打开设备路径出错!\n");
  else
  {
   HIDD_ATTRIBUTES Attributes;
   HidD_GetAttributes(hDeviceHandle,&Attributes);
   //将有关该设备的标识显示出来
   _tprintf("供应商ID\t:0X%04X\n",Attributes.VendorID);
   _tprintf("产品ID\t:0X%04X\n",Attributes.ProductID);
   _tprintf("产品版本号:0X%04X\n",Attributes.VersionNumber);
   
   WCHAR mString[256];
   TCHAR Buffer[256];

   HidD_GetManufacturerString(hDeviceHandle,mString,sizeof(mString));
   if (wcstombs(Buffer,mString,256) == -1)  // fail
    Buffer[0] = NULL;
   _tprintf("生产商:\t%s\n",Buffer);
   
   HidD_GetProductString(hDeviceHandle,mString,sizeof(mString));
   if (wcstombs(Buffer,mString,256) == -1)
    Buffer[0] = NULL;
   _tprintf("产品名称:\t%s\n",Buffer);

   // 通信:
   PHIDP_PREPARSED_DATA pHidpPreparsedData;
   HIDP_CAPS    hidPCaps;
   if (!HidD_GetPreparsedData(hDeviceHandle,&pHidpPreparsedData))
   {
    _tprintf("获取 HID PREPARED DATA 失败!\n");
    return;
   }
   NTSTATUS status = HidP_GetCaps(pHidpPreparsedData,&hidPCaps);
   if (status == HIDP_STATUS_SUCCESS)
   {
    _tprintf("CAP信息如下:\n");
    _tprintf("     InputReportByteLength %d\n", hidPCaps.InputReportByteLength);
    _tprintf("     OutputReportByteLength %d\n", hidPCaps.OutputReportByteLength);
   }
   DWORD nReadBytes = 0;
   BYTE *pInputReport = new BYTE[hidPCaps.InputReportByteLength];
   memset(pInputReport,0,hidPCaps.InputReportByteLength);
   
   do
   {
    ReadFile(hDeviceHandle,pInputReport,hidPCaps.InputReportByteLength,&nReadBytes,NULL);
    if (hidPCaps.InputReportByteLength == nReadBytes)
    {
     for(unsigned int i=0; i<(nReadBytes-1);i++)
      _tprintf("%02x-",pInputReport[i]);
     _tprintf("%02x\r",pInputReport[nReadBytes-1]);
    }
    if (pInputReport[nReadBytes-2] == 0x20)  //break the loop when pressing a specific key
    {
     _tprintf("\n");
     break;
    }
    Sleep(10);
   }while(hidPCaps.InputReportByteLength == nReadBytes);

   //释放句柄资源
   CloseHandle(hDeviceHandle);
  }
    
  MemberIndex++;
 }while(bSuccess);

 SetupDiDestroyDeviceInfoList(hDevInfo);
}

本文地址:http://com.8s8s.com/it/it1189.htm