VC MFC 实现枚举串口号,并支持串口热插拔功能

直接上代码

头文件  全局变量声明

//需要头文件
#include <dbt.h>

//声明全局变量
static const GUID GUID_DEVINTERFACE_LIST[] =
{
    // GUID_DEVINTERFACE_USB_DEVICE
    { 0xA5DCBF10, 0x6530, 0x11D2,{ 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } },
    // GUID_DEVINTERFACE_HID, 
    { 0x4D1E55B2, 0xF16F, 0x11CF,{ 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } },
};


CStringArray m_strArrSerialPort;

 

枚举串口号

BOOL xxxDlg::EnumSerialPort(CStringArray &saCom)
{
    HKEY                hKey;
    DWORD                dwIndex;
    LONG                lResult;
    DWORD                dwType;
    DWORD                dwKeyNameLen;
    CHAR                szKeyName[256];
    DWORD                dwKeyDataLen;
    UCHAR                szKeyData[80];
    CString                strCom, str;
    LPCTSTR                lpSubKey;

    saCom.RemoveAll();

    lpSubKey = _T("HARDWARE\\DEVICEMAP\\SERIALCOMM\\");

    lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey);

    if (lResult != ERROR_SUCCESS)
    {
        str.Format(_T("RegOpenKeyEx()函数打开失败!"));
        AfxMessageBox(str);
        return FALSE;
    }

    dwIndex = 0;

    while (1)
    {
        memset(szKeyName, 0x0, sizeof(szKeyName));
        memset(szKeyData, 0x0, sizeof(szKeyData));

        dwKeyNameLen = sizeof(szKeyName);
        dwKeyDataLen = sizeof(szKeyData);

        lResult = RegEnumValue(hKey, dwIndex++, szKeyName, &dwKeyNameLen, NULL, &dwType, szKeyData, &dwKeyDataLen);

        if ((lResult == ERROR_SUCCESS) || (lResult == ERROR_MORE_DATA))
        {
            strCom = (char *)szKeyData;
            saCom.Add(strCom);
        }
        else
        {
            break;
        }
    }

    RegCloseKey(hKey);

    return true;
}

串口插拔消息响应函数

 1 BOOL xxxDlg::OnDeviceChange(UINT nEventType, DWORD dwData)
 2 {
 3     switch (nEventType)
 4     {
 5         //串口被移除  
 6     case DBT_DEVICEREMOVECOMPLETE:
 7         EnumSerialPort(m_strArrSerialPort);
 8         ShowSerialPort();
 9         break;
10         //串口插入或者变为有效
11     case DBT_DEVICEARRIVAL:
12         EnumSerialPort(m_strArrSerialPort);
13         ShowSerialPort();
14         break;
15 
16     default:
17         break;
18     }
19 
20     return TRUE;
21 }

显示到COMBO-BOX控件中

1 void xxxDlg::ShowSerialPort()
2 {
3     ((CComboBox *)GetDlgItem(IDC_COMBO_SerialPort))->ResetContent();
4     for (int i = 0; i < m_strArrSerialPort.GetSize(); i++)
5     {
6         ((CComboBox *)GetDlgItem(IDC_COMBO_SerialPort))->AddString(m_strArrSerialPort.GetAt(i));
7     }
8     ((CComboBox *)GetDlgItem(IDC_COMBO_SerialPort))->SetCurSel(0);
9 }

在OnInitDialog中增加注册插拔消息的代码   并初始化显示串口号

 1     //初始化显示串口
 2         EnumSerialPort(m_strArrSerialPort);
 3         ShowSerialPort();
 4 
 5     //注册插拔事件
 6     HDEVNOTIFY hDevNotify;
 7     DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
 8     ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
 9     NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
10     NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
11 
12     for (int i = 0; i < sizeof(GUID_DEVINTERFACE_LIST) / sizeof(GUID); i++)
13     {
14         NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
15         hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
16         if (!hDevNotify)
17         {
18             return FALSE;
19         }
20     }        

 

posted @ 2022-11-21 18:02  ckrgd  阅读(607)  评论(0编辑  收藏  举报