VC学习:获取游戏手柄的按键输入

2016-02-19 14:28 259 1 收藏

图老师设计创意栏目是一个分享最好最实用的教程的社区,我们拥有最用心的各种教程,今天就给大家分享VC学习:获取游戏手柄的按键输入的教程,热爱PS的朋友们快点看过来吧!

【 tulaoshi.com - 编程语言 】

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

  //USB接口的游戏手柄

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

  #include
  #include
  #include
  #include
  extern "C"
  {
  #include
  }

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  void main()
  {
  GUID HidGuid;

  // 查找本系统中HID类的GUID标识
  HidD_GetHidGuid(&HidGuid);
  _tprintf("系统中HID类的GUID标识为:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  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设备发生错误");

  return;
  }

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

  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设备!");
  else
  _tprintf("没有更多的可用的USB设备!");

  SetupDiDestroyDeviceInfoList(hDevInfo);
  return;
  }

  _tprintf("找到了一个USB设备:");
  //若找到了一个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("查找路径设备时出错!");
  else
  _tprintf("设备路径:%s",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("打开设备路径出错!");
  else

  {
  HIDD_ATTRIBUTES Attributes;
  HidD_GetAttributes(hDeviceHandle,&Attributes);
  //将有关该设备的标识显示出来
  _tprintf("供应商ID:0X%04X",Attributes.VendorID);
  _tprintf("产品ID:0X%04X",Attributes.ProductID);
  _tprintf("产品版本号:0X%04X",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("生产商:%s",Buffer);

  HidD_GetProductString(hDeviceHandle,mString,sizeof(mString));
  if (wcstombs(Buffer,mString,256) == -1)
  Buffer[0] = NULL;
  _tprintf("产品名称:%s",Buffer);

  // 通信:
  PHIDP_PREPARSED_DATA pHidpPreparsedData;
  HIDP_CAPS hidPCaps;
  if (!HidD_GetPreparsedData(hDeviceHandle,&pHidpPreparsedData))
  {
  _tprintf("获取 HID PREPARED DATA 失败!");
  return;
}
  NTSTATUS status = HidP_GetCaps(pHidpPreparsedData,&hidPCaps);
  if (status == HIDP_STATUS_SUCCESS)
  {
  _tprintf("CAP信息如下:");
  _tprintf(" InputReportByteLength %d", hidPCaps.InputReportByteLength);
  _tprintf(" OutputReportByteLength %d", 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",pInputReport[nReadBytes-1]);
  }
  if (pInputReport[nReadBytes-2] == 0x20) //break the loop when pressing a specific key
  {
  _tprintf("");
  break;
  }
  Sleep(10);
  }while(hidPCaps.InputReportByteLength == nReadBytes);

  //释放句柄资源
  CloseHandle(hDeviceHandle);
  }

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  MemberIndex++;
  }while(bSuccess);

  SetupDiDestroyDeviceInfoList(hDevInfo);
  }

来源:https://www.tulaoshi.com/n/20160219/1607030.html

延伸阅读
标签: 游戏动漫
《细胞分裂6 黑名单》手柄按键操作指南 全新潜入类游戏《细胞分裂6:黑名单》即将上市,对于手柄的具体按键操作方法是怎样的呢,下面就为玩家带来手柄按键操作指南,各按键功能介绍。 L2 使用道具 L1 瞄准 R2 标记/取消标记 R1 开火 上下左右 切换武器/装备 左摇杆 移动(按住为下蹲) 右摇杆 视角(按住为上弹夹) △ 处决 □ 绞杀(按...
  近日写程序,让全局共享变量给害苦了,现将结果公布出来,不希望有人步我后尘。   先总结经验:全局共享变量一定要在定义时初始化,否则无效。   下面写两行代码进行验证(Visual Studio .NET 2003 + Windows Servers 2003):   ////////////////////////////   //main.c   #include   #include "r...
标签: 时光之刃
《时光之刃》游戏控制按键 翻译 主要按键分为4大类 一般模式 W :前 A  :后 S  :左 D :右 空格 :跳跃 连续按键2次可使用二级跳 ALT:奔跑/行走切换 SHIFT:冲刺 E:使用 TAB:时光倒流 右键:俯冲攻击(这个需要配合浮空攻击的使用) 左键:普通用剑攻击 右键:右键连击浮空攻击 最后一击可使出俯冲攻击 中键:锁定目标 ...
《暗黑血统》按键与游戏技巧 召唤watcher给予游戏提示(有时屏幕右方会出现watcher头像,这说明他有提示) C 召唤天狗 V 变身(这个游戏的主角的变身很强大,攻击力超高,而且基本无敌) R 拖动物品 F1 地图、游戏统计 ESC 物品栏,游戏选项 鼠标中键 投掷捡起的物品(汽车,箱子),手中无物品的时候是使用右上角左栏的物品。 1,2,3 切...
搜狗输入法如何取消按键震动   1)安装搜狗输入法,打开系统设置依次点击   2)点击→选择弱,即可以消除振动提示。           注 :更多精彩教程请关注图老师手机教程栏目,图老师手机数码群:296605639欢迎你的加入

经验教程

87

收藏

25
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部