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 }