开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1036|回复: 2
收起左侧

[精币悬赏] 我这有个C的 硬件 谁能帮忙写到易语言里

[复制链接]
结帖率:47% (17/36)
发表于 2019-10-16 17:23:57 | 显示全部楼层 |阅读模式   上海市上海市
5精币
本帖最后由 大司命 于 2019-10-16 17:35 编辑


我附加下源码


#include "stdafx.h"
#include <hidusage.h>
#include <shidfact.h>
#include <hidpi.h>
#include <SetupAPI.h>
#include <hidsdi.h>
#include "HIDControl.h"
#pragma comment(lib,"hid.lib")
#pragma comment(lib,"setupapi.lib")
int CHIDControl::FindHIDDevice()
{
//定义一个GUID的结构体HidGuid来保存HID设备的接口类GUID。
GUID HidGuid;
//定义一个DEVINFO的句柄hDevInfoSet来保存获取到的设备信息集合句柄。
HDEVINFO hDevInfoSet;
//定义MemberIndex,表示当前搜索到第几个设备,0表示第一个设备。
DWORD MemberIndex;
//DevInterfaceData,用来保存设备的驱动接口信息
SP_DEVICE_INTERFACE_DATA DevInterfaceData;
//定义一个BOOL变量,保存函数调用是否返回成功
BOOL Result;
//定义一个RequiredSize的变量,用来接收需要保存详细信息的缓冲长度。
DWORD RequiredSize;
//定义一个指向设备详细信息的结构体指针。
PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetailData;
//定义一个用来保存打开设备的句柄。
HANDLE hDevHandle;
//定义一个HIDD_ATTRIBUTES的结构体变量,保存设备的属性。
HIDD_ATTRIBUTES DevAttributes;
//初始化设备未找到
MyDevFound = FALSE;
//获取在文本框中设置的VID、PID、PVN。
//GetMyIDs();
MyVid = 0x0965;
MyPid = 0x6915;
MyPvn = 0;
//初始化读、写句柄为无效句柄。
hReadHandle = INVALID_HANDLE_VALUE;
hWriteHandle = INVALID_HANDLE_VALUE;
//对DevInterfaceData结构体的cbSize初始化为结构体大小
DevInterfaceData.cbSize = sizeof(DevInterfaceData);
//对DevAttributes结构体的Size初始化为结构体大小
DevAttributes.Size = sizeof(DevAttributes);
//调用HidD_GetHidGuid函数获取HID设备的GUID,并保存在HidGuid中。
HidD_GetHidGuid(&HidGuid);
//根据HidGuid来获取设备信息集合。其中Flags参数设置为
//DIG*FDEVICEINTERFACE|DIG*FPRESENT,前者表示使用的GUID为
//接口类GUID,后者表示只列举正在使用的设备,因为我们这里只
//查找已经连接上的设备。返回的句柄保存在hDevinfo中。注意设备
//信息集合在使用完毕后,要使用函数SetupDiDestroyDeviceInfoList
//销毁,不然会造成内存泄漏。
hDevInfoSet = SetupDiGetClassDevs(&HidGuid,
  NULL,
  NULL,
  DIG*FDEVICEINTERFACE | DIG*FPRESENT);
//然后对设备集合中每个设备进行列举,检查是否是我们要找的设备
//当找到我们指定的设备,或者设备已经查找完毕时,就退出查找。
//首先指向第一个设备,即将MemberIndex置为0。
MemberIndex = 0;
while (1)
{
  //调用SetupDiEnumDeviceInterfaces在设备信息集合中获取编号为
  //MemberIndex的设备信息。
  Result = SetupDiEnumDeviceInterfaces(hDevInfoSet,
   NULL,
   &HidGuid,
   MemberIndex,
   &DevInterfaceData);
  //如果获取信息失败,则说明设备已经查找完毕,退出循环。
  if (Result == FALSE) break;
  //将MemberIndex指向下一个设备
  MemberIndex++;
  //如果获取信息成功,则继续获取该设备的详细信息。在获取设备
  //详细信息时,需要先知道保存详细信息需要多大的缓冲区,这通过
  //第一次调用函数SetupDiGetDeviceInterfaceDetail来获取。这时
  //提供缓冲区和长度都为NULL的参数,并提供一个用来保存需要多大
  //缓冲区的变量RequiredSize。
  Result = SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
   &DevInterfaceData,
   NULL,
   NULL,
   &RequiredSize,
   NULL);
  //然后,分配一个大小为RequiredSize缓冲区,用来保存设备详细信息。
  pDevDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);
  if (pDevDetailData == NULL) //如果内存不足,则直接返回。
  {
   SetupDiDestroyDeviceInfoList(hDevInfoSet);
   return -1;
  }
  //并设置pDevDetailData的cbSize为结构体的大小(注意只是结构体大小,
  //不包括后面缓冲区)。
  pDevDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  //然后再次调用SetupDiGetDeviceInterfaceDetail函数来获取设备的
  //详细信息。这次调用设置使用的缓冲区以及缓冲区大小。
  Result = SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
   &DevInterfaceData,
   pDevDetailData,
   RequiredSize,
   NULL,
   NULL);
  //将设备路径复制出来,然后销毁刚刚申请的内存。
  MyDevPathName = pDevDetailData->DevicePath;
  free(pDevDetailData);
  //如果调用失败,则查找下一个设备。
  if (Result == FALSE) continue;
  //如果调用成功,则使用不带读写访问的CreateFile函数
  //来获取设备的属性,包括VID、PID、版本号等。
  //对于一些独占设备(例如USB键盘),使用读访问方式是无法打开的,
  //而使用不带读写访问的格式才可以打开这些设备,从而获取设备的属性。
  hDevHandle = CreateFile(MyDevPathName.c_str(),
   NULL,
   FILE_SHARE_READ | FILE_SHARE_WRITE,
   NULL,
   OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL,
   NULL);
  //如果打开成功,则获取设备属性。
  if (hDevHandle != INVALID_HANDLE_VALUE)
  {
   //获取设备的属性并保存在DevAttributes结构体中
   Result = HidD_GetAttributes(hDevHandle,
    &DevAttributes);
   //关闭刚刚打开的设备
   CloseHandle(hDevHandle);
   //获取失败,查找下一个
   if (Result == FALSE) continue;
   //如果获取成功,则将属性中的VID、PID以及设备版本号与我们需要的
   //进行比较,如果都一致的话,则说明它就是我们要找的设备。
   if (DevAttributes.VendorID == MyVid) //如果VID相等
   {
    if (DevAttributes.ProductID == MyPid) //并且PID相等
    {
     //if (DevAttributes.VersionNumber == MyPvn) //并且设备版本号相等
     //{
     MyDevFound = TRUE; //设置设备已经找到
     //那么就是我们要找的设备,分别使用读写方式打开之,并保存其句柄
     //并且选择为异步访问方式。
     //读方式打开设备
     hReadHandle = CreateFile(MyDevPathName.c_str(),
      GENERIC_READ,
      FILE_SHARE_READ | FILE_SHARE_WRITE,
      NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
      NULL);
     if (hReadHandle != INVALID_HANDLE_VALUE);//cout << "读访问打开设备成功" << endl;
     else return -2;// cout << "读访问打开设备失败" << endl;
     //写方式打开设备
     hWriteHandle = CreateFile(MyDevPathName.c_str(),
      GENERIC_WRITE,
      FILE_SHARE_READ | FILE_SHARE_WRITE,
      NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
      NULL);
     if (hWriteHandle != INVALID_HANDLE_VALUE);//cout << "写访问打开设备成功" << endl;
     else return -3;//cout << "写访问打开设备失败" << endl;
     DataInSending = FALSE; //可以发送数据
     //手动触发事件,让读报告线程恢复运行。因为在这之前并没有调用
     //读数据的函数,也就不会引起事件的产生,所以需要先手动触发一
     //次事件,让读报告线程恢复运行。
     SetEvent(ReadOverlapped.hEvent);
     //显示设备的状态。
     //SetDlgItemText(IDC_DS, "设备已打开");
     //找到设备,退出循环。本程序只检测一个目标设备,查找到后就退出
     //查找了。如果你需要将所有的目标设备都列出来的话,可以设置一个
     //数组,找到后就保存在数组中,直到所有设备都查找完毕才退出查找
     break;
    }
   }
  }
  //如果打开失败,则查找下一个设备
  else continue;
}
//调用SetupDiDestroyDeviceInfoList函数销毁设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfoSet);
return 1;
}

结帖率:99% (71/72)
发表于 2019-10-16 17:36:24 | 显示全部楼层   广东省深圳市
定制区,大神多,这个难度不小。
回复

使用道具 举报

结帖率:47% (17/36)
 楼主| 发表于 2019-10-16 17:39:45 | 显示全部楼层   上海市上海市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表