用QT做上位机,使用串口通讯时,想自动扫描串口设备,即在下拉列表框中,只显示已有的串口。
本来挺简单的,只要轮询HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM就能找到已有的串口,但QT的QSettings有个bug,如果键名里有斜杠'/',则读出的键值就是空的。参考别人使用API函数读取键值的文章,写了下面这个函数。
UINT32 comPortInfo(QStringList *qslKeyValList)
{
//1.从注册表中取出 键名
QString qsRegPath = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM";
QSettings *reg = new QSettings(qsRegPath,QSettings::NativeFormat);
QStringList qsListKeys = reg->allKeys(); //childKeys();
QList<int> qlTmp;
//2.再依次取出 键值
for (UINT32 i=0; i < qsListKeys.size(); i++)
{
HKEY hKey;
wchar_t wsKeyName[256]; //键名数组
char sKeyVal[32]; //键值数组
DWORD ulKeyNameSize = sizeof(wsKeyName);
DWORD ulKeyValSize = sizeof(sKeyVal);
RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),0,KEY_READ,&hKey);
RegEnumValue(hKey, /*要查询的已打开的键的句柄*/
i, /*索引号*/
wsKeyName, /*返回所读取的名称*/
&ulKeyNameSize, /*返回读取名称的长度,不含chr(0)*/
0, /*保留*/
0, /*返回所读取的数据类型*/
(BYTE*)sKeyVal, /*返回所读取的数据*/
&ulKeyValSize); /*返回所读取的数据长度*/
//取出类似 COM3 COM20 这样的键值
//只取第3位以后的数字,放入list (方便排序)
qlTmp.append( QString::fromUtf16((ushort*)sKeyVal).mid(3).toUInt() );
}
//3.排序
// 因为字符串排序 "COM12" < "COM3", 所以不能简单地QStringList.sort()
// 故先提取出数字, 再按数字排序, 再附加上前缀COM
qSort(qlTmp);
for (UINT32 i=0; i<qsListKeys.size(); i++)
{
qslKeyValList->append(QString("COM%1").arg(qlTmp[i]));
}
//qDebug() << *qslKeyValList;
return qsListKeys.size();使用方法:
// 检查本机串口设备
QStringList qslKeyValList;
UINT32 uiComCount = comPortInfo(&qslKeyValList);
if(uiComCount == 0)
QMessageBox::about(NULL, "错误", "本机无串口设备,请检查串口线");
qDebug() << QString("=== 本机有%1个串口:").arg(uiComCount) << qslKeyValList;
本文介绍了如何使用QT程序自动扫描并显示计算机已有的串口设备,通过遍历注册表HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM来获取串口号,并排除QT中QSettings类处理斜杠路径时的bug,最终实现串口设备的自动扫描和显示。
4337

被折叠的 条评论
为什么被折叠?



