现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

Qt通过注册表枚举串口(winXP和win7测试通过)

2015-01-04 06:25 工业·编程 ⁄ 共 1899字 ⁄ 字号 暂无评论

源文件:

#include "prjini.h"
#include <qsettings.h>

#include <QStringList>
#if defined(Q_OS_WIN32)
#include <qt_windows.h>//必须添加windows的头文件
#endif

 

QStringList QPrjIni::getCOMPorts_win(void)//Qt通过windows相关的注册表函数实现枚举串口
{
    QStringList comList;

#if defined(Q_OS_WIN32)

    HKEY hKey;
    LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM\\"), 0, KEY_READ, &hKey);
    if (ret != ERROR_SUCCESS)
    {
        return comList;//错误:无法打开有关的hKEY
    }

    DWORD dwIndex = 0;
    LONG Status = 0;
    wchar_t ckeyName[512] = {0};
    char ckeyValue[100] = {0};
    DWORD szName = 0;
    DWORD szValue = 0;
    DWORD type = 0;
    QString str1;
    QString str2;

    while (1)
    {
        szName = sizeof(ckeyName);//注意,因为szName每读一次key,数值就变化一次,所以每次必须重新初始化,否则长度若不足,会出现ERROR_MORE_DATA的错误
        szValue = sizeof(ckeyValue);//与szName相同
        Status = RegEnumValue(hKey, dwIndex++, ckeyName, &szName, 0, &type, (BYTE*)ckeyValue, &szValue);

        if (Status == ERROR_SUCCESS)
        {
            //初始化
            str1 = "";
            str2 = "";

            //求出键的名称
            for (DWORD i = 0; i < szName; i++)
            {
                str1.append(ckeyName[i]);
            }

            //求出键的数值
            for (DWORD i = 0; i < szValue; i++)
            {
                if (ckeyValue[i] != 0)//必须跳过0,例如"COM1"在ckeyValue数组储存的是"C0O0M010"
                {
                    str2.append(ckeyValue[i]);
                }
            }

            //根据键的数值判断是否COM
            if (str2.indexOf("COM") != -1)
            {
                comList.append(str2);
            }
        }
        else//ERROR_MORE_DATA(234),ERROR_NO_MORE_ITEMS(259)
        {
            break;
        }
    }

    RegCloseKey(hKey);

#endif

    return comList;
}

 

也许有人会问,为什么不使用Qt4自身的函数读注册表?原因如下:

Qt4在读取注册表时,对于有路径分隔符“\”,“/”的value都无法读取,应该属于Qt4的一个bug。

例如注册表键名称为"\Device\Serial0"的数值,读取恒等于空。

QSettings reg("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM", QSettings::NativeFormat);

QStringList keyList = reg.childKeys();

QString tmp;

foreach(QString key, keyList)
{

tmp = reg.value(key).toString();//tmp恒等于空

}

给我留言

留言无头像?