版权声明:原创博文,转载请注明出处! https://blog.csdn.net/sunriver2000/article/details/82718495
步骤
1、 头文件添加声明。
protected:
//实现串口热插拔
afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
2、源文件添加消息映射。
BEGIN_MESSAGE_MAP(CFixtureConfig, CDialog)
ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()
3、源文件添加代码实现。
BOOL CFixtureConfig::OnDeviceChange(UINT nEventType, DWORD dwData)
{
switch (nEventType)
{
//串口被移除
case DBT_DEVICEREMOVECOMPLETE:
//串口插入或者变为有效
case DBT_DEVICEARRIVAL:
EnumSerialPort(m_saTmpCom);
break;
default:
break;
}
return TRUE;
}
4、枚举串口。
a、注册表枚举法。
BOOL CFixtureConfig::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("[Main] 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;
}
b、穷举遍历法。
具体方法见这篇文章:打开串口号大于9的串口,CreateFile返回失败!
5、备注:EnumSerialPort()函数枚举出来的串口为系统所有可用串口的集合。如何从中找出发生热拔插的那个串口,还需要对可用串口队列做动态分选,分选算法这里就不赘述了。