QT MFC 通用 相同UVC设备绑定对应COM口

主要描述:UVC设备相同的情况下搜索到的信息相同,这种情况下很难区分UVC设备对应的COM口。

下面是通过用windosAPI搜索设备管理器获取COM口以及USB设备对应属性对比进行UVC设备与COM口绑定。

主要包含的头文件

#include <QMainWindow>
#include <Windows.h>
#include <vector>
#include <string>
#include <stdint.h>
#include <stdio.h>
#include <devguid.h>

#include <map>
#include <dshow.h>
#include <atlcomcli.h>
#include <SetupAPI.h>
#include <string>
#pragma comment(lib, "Setupapi.lib")
#pragma comment(lib, "Strmiids.lib")
#include <comutil.h>
#include  <string>
#pragma comment(lib, "comsuppw.lib")

using namespace std;

用到的结构体容器

//存储USB设备信息
typedef struct _USB_DEV
{
    string strUsbName;
    string strUsbProperty;
} USB_DEV;
vector<USB_DEV> g_usbDevices;
//存储COM口信息
typedef struct _COM_DEV
{
    string strComName;
    string strComProperty;
} _COM_DEV;
vector<_COM_DEV> g_comDevices;
//存储USB设备与COM口对应信息
typedef struct DEVICES
{
    int DevicesNum;
    string strName;
    string strCom;
} DEVICES;
vector<DEVICES> g_Devices;

搜索USB设备信息

void GetUsbProperty()
{

    HRESULT hr;
    VARIANT name;

    LONGLONG start = 0, stop = MAXLONGLONG;

    ICreateDevEnum*		dev_enum;
    IEnumMoniker*		enum_moniker;
    IMoniker*			moniker;
    IPropertyBag*		pbag;

    //create an enumerator for video input devices
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&dev_enum);
    if (hr < 0) throw hr;

    hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enum_moniker, NULL);
    if (hr < 0) throw hr;
    if (hr == S_FALSE) return; //no devices found
    while (enum_moniker->Next(1, &moniker, 0) == S_OK)
    {
        //get properties
        hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pbag);
        if (hr >= 0)
        {
            VariantInit(&name);

            //get the description
            hr = pbag->Read(L"Description", &name, 0);
            if (hr < 0)
                hr = pbag->Read(L"FriendlyName", &name, 0);
            USB_DEV usb_dev;
			
			string Str;
			Str = _com_util::ConvertBSTRToString(name.bstrVal);
			usb_dev.strUsbName = Str;
            if (hr >= 0)
            {
                CComVariant vWaveInId;
                if (SUCCEEDED(pbag->Read(L"DevicePath", &vWaveInId, NULL)))
                {
                    //这里截取所用到的信息
					string str = _com_util::ConvertBSTRToString(vWaveInId.bstrVal);
                  string strPidVid = str.substr(8, 17);
                  string strAdress = str.substr(33, 8);
                  usb_dev.strUsbProperty = strPidVid + strAdress;
                    g_usbDevices.push_back(usb_dev);

                }


            }
            VariantClear(&name);

            pbag->Release();
        }
    }
    enum_moniker->Release();
    dev_enum->Release();
    return;
}

搜索COM口信息

void MainWindow::GetComProperty()
{
    //   得到设备信息集
    //GUID_DEVCLASS_PORTS对应端口
    HDEVINFO   hDevInfo = SetupDiGetClassDevs(
        (LPGUID)&GUID_DEVCLASS_PORTS,
        NULL,
        0,
        DIGCF_PRESENT/*   |   DIGCF_ALLCLASSES*/);

    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        printf("Error!   SetupDiGetClassDevs()   return   %d\n", GetLastError());
        SetupDiDestroyDeviceInfoList(hDevInfo);
        return;
    }

    TCHAR   szBuf[MAX_PATH];
    SP_DEVINFO_DATA   spDevInfoData = { sizeof(SP_DEVINFO_DATA) };

    //   开始列举设备
    for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)
    {
        _COM_DEV com_dev;
        //   得到设备实例的唯一标识ID(由注册表路径组成)
        if (SetupDiGetDeviceInstanceId(
            hDevInfo,
            &spDevInfoData,
            szBuf,
            MAX_PATH,
            NULL))
        {
            printf("%03d   :   InstanceId   =   %s\n", i, szBuf);
            string str = TCHAR2STRING(szBuf);
            string strPidVid = str.substr(4, 17);
            string strAdress = str.substr(29, 8);
            str = strPidVid + strAdress;
            transform(str.begin(),str.end(),str.begin(), ::tolower);
            com_dev.strComProperty = str;

        }

        //   得到设备型号
        if (SetupDiGetDeviceRegistryProperty(
            hDevInfo,
            &spDevInfoData,
            SPDRP_FRIENDLYNAME,
            NULL,
            (PBYTE)szBuf,
            MAX_PATH,
            NULL))
        {
            printf("%03d   :   FriendName   =   %s\n", i, szBuf);
            string str = TCHAR2STRING(szBuf);
            string strComName = str.substr(12);
            com_dev.strComName = strComName;
            g_comDevices.push_back(com_dev);
        }

    }
}

上面涉及到数据类型转换TCHAR2STRING函数  TCHAR转string

string TCHAR2STRING(TCHAR *STR)

{

    int iLen = WideCharToMultiByte(CP_ACP, 0,STR, -1, NULL, 0, NULL, NULL);

    char* chRtn =new char[iLen*sizeof(char)];

    WideCharToMultiByte(CP_ACP, 0, STR, -1, chRtn, iLen, NULL, NULL);

    std::string str(chRtn);

    return str;

}

然后将得到的信息对比得到对应关系存储在结构体容器中

void UCContarst()
{
	
    int num = 0;
    for (int i = 0; i < g_usbDevices.size();i++)
    {
        for (int j = 0; j < g_comDevices.size(); j++)
        {
            if (g_usbDevices[i].strUsbProperty == g_comDevices[j].strComProperty)
            {
                DEVICES devices;
                devices.DevicesNum = num;
                devices.strCom = g_comDevices[j].strComName;
                devices.strName = g_usbDevices[i].strUsbName;
                g_Devices.push_back(devices);
                num++;
            }
        }

    }
}

下面分别是QT和MFC将搜索到的com口显示在下拉列表,注意在每次点击刷新需要清楚列表并清空容器

void MainWindow::on_pushButton_Serch_clicked()
{
        ui->comboBox_COM->clear(); //清除列表
		GetUsbProperty();
		GetComProperty();
        UCContarst();
        for (int i = 0; i < g_Devices.size();i++)
        {
            string str = g_Devices[i].strCom;
            QString qstr = QString::fromStdString(str);
           ui->comboBox_COM->addItem(qstr);
        }
        g_usbDevices.clear();
        g_comDevices.clear();
        g_Devices.clear();
}

MFC

void CUToComDlg::OnBnClickedBtnSerch()
{
	((CComboBox*)GetDlgItem(IDC_COMBO_COM))->ResetContent();//消除现有所有内容
	GetUsbProperty();
	GetComProperty();
	UCContarst();
	for (int i = 0; i < g_Devices.size();i++)
	{
		CString str = g_Devices[i].strCom;
		m_com.InsertString(i, str);
	}
	g_usbDevices.clear();
	g_comDevices.clear();
	g_Devices.clear();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值