<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">* Windows自动识别串口的实现,以下是基于MFC开发的,以下所说都是建立在串口注册表上说的</span>
*实现Windows系统下自动识别串口需要调用三个Windows API函数,它们是:
//主要用于打开串口
1. LONG RegOpenKeyEx(
<span style="white-space:pre"> </span> HKEY hKey,<span style="white-space:pre"> </span>//主键,即串口信息存放的文件夹
<span style="white-space:pre"> </span> LPCTSTR lpSubKey,<span style="white-space:pre"> </span>//子键,串口所在的具体文件夹
<span style="white-space:pre"> </span> DWORD ulOptions,<span style="white-space:pre"> </span>//保留值,不用管,必须设置为0
REGSAM samDesired,<span style="white-space:pre"> </span>//访问权限
PHKEY phkResult<span style="white-space:pre"> </span>//返回的串口句柄,以下两个函数使用
<span style="white-space:pre"> </span> );
//主要用于获得在当前串口注册表中有多少个串口
2. LONG RegQueryInfoKey(
<span style="white-space:pre"> </span>HKEY hKey,<span style="white-space:pre"> </span>//RegOpenKeyEx的五个参数返回的子键句柄
<span style="white-space:pre"> </span>LPTSTR lpClass,<span style="white-space:pre"> </span>//NULL
<span style="white-space:pre"> </span>LPDWORD lpcClass,<span style="white-space:pre"> </span>//NULL
<span style="white-space:pre"> </span>LPDWORD lpReserved,<span style="white-space:pre"> </span>//NULL
<span style="white-space:pre"> </span>LPDWORD lpcSubKeys,<span style="white-space:pre"> </span>//子键的数量
<span style="white-space:pre"> </span>LPDWORD lpcMaxSubKeyLen,<span style="white-space:pre"> </span>//最大子键的长度
<span style="white-space:pre"> </span>LPDWORD lpcMaxClassLen,<span style="white-space:pre"> </span>//NULL
<span style="white-space:pre"> </span>LPDWORD lpcValues,<span style="white-space:pre"> </span>//串口的数量
<span style="white-space:pre"> </span>LPDWORD lpcMaxValueNameLen,<span style="white-space:pre"> </span>//最大值名的长度
<span style="white-space:pre"> </span>LPDWORD lpcMaxValueLen,<span style="white-space:pre"> </span>//最大串口的长度
<span style="white-space:pre"> </span>LPDWORD lpcbSecurityDescriptor,<span style="white-space:pre"> </span>//NULL
<span style="white-space:pre"> </span>PFILETIME lpftLastWriteTime<span style="white-space:pre"> </span>//NULL
<span style="white-space:pre"> </span>);
//主要用于获得串口名,如"COM3"等
3. LONG RegEnumValue( <span style="white-space:pre"> </span> HKEY hKey,<span style="white-space:pre"> </span>//串口子键句柄 <span style="white-space:pre"> </span> DWORD dwIndex,<span style="white-space:pre"> </span>//在注册表中的索引 <span style="white-space:pre"> </span> LPTSTR lpValueName,<span style="white-space:pre"> </span>//值名 <span style="white-space:pre"> </span> LPDWORD lpcValueName,<span style="white-space:pre"> </span>//值名的长度 <span style="white-space:pre"> </span> LPDWORD lpReserved,<span style="white-space:pre"> </span>//NULL <span style="white-space:pre"> </span> LPDWORD lpType,<span style="white-space:pre"> </span>//串口的数据类型 <span style="white-space:pre"> </span> LPBYTE lpData,<span style="white-space:pre"> </span>//串口名 <span style="white-space:pre"> </span> LPDWORD lpcbData<span style="white-space:pre"> </span>//串口名的长度 <span style="white-space:pre"> </span> );
struct UartInfo
{
DWORD UartNum;
WCHAR UartName[20];
};
//获取串口列表
BOOL EnumComs(struct UartInfo **UartCom, LPDWORD UartComNumber, CnuprogDlg *pMainDlg)
{
//LPCTSTR 即const char *
*UartComNumber = 0;
HKEY hNewKey;
LONG lResult=RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_ALL_ACCESS, &hNewKey);
if(lResult != ERROR_SUCCESS)
{
pMainDlg->AddToInfOut(_T("打开COM注册表失败!!!"),1,1);
return FALSE;
}
else
{
pMainDlg->AddToInfOut(_T("打开COM注册表成功!!!"),1,1);
}
//DWORD即unsigned long
DWORD ValuesNumber;
DWORD MaxValueNameLen;
DWORD MaxValueLen;
CString str;
//检索指定的子键下有多少个值项
lResult = RegQueryInfoKey(
hNewKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&ValuesNumber,
&MaxValueNameLen,
&MaxValueLen,
NULL,
NULL
);
if(lResult != ERROR_SUCCESS)
{
RegCloseKey(hNewKey);
//pMainDlg->AddToInfOut(_T("检索连接在PC上的串口数量失败!!!"),1,1);
return FALSE;
}
else
{
// str.Format(_T("连接在PC上的串口数量是:%ld"), ValuesNumber);
// pMainDlg->AddToInfOut(str,1,1);
*UartCom =(struct UartInfo *)malloc( ValuesNumber * sizeof(struct UartInfo));
}
DWORD index;
DWORD uartindex = 0;
//CHAR ValueName[MAX_VALUE_NAME];
WCHAR ValueName[100];
//DWORD ValueNameSize = MAX_VALUE_NAME;
DWORD ValueNameSize;
DWORD DataType;
BYTE DataBuffer[100];
DWORD DataLen = 100;
//LPTSTR 即 char *, LPBYTE即 char *
//检索每个值项,获取值名,数据类型,数据
for(index = 0; index < ValuesNumber; index++)
{
memset(ValueName, 0, sizeof(ValueName));
memset(DataBuffer, 0, sizeof(DataBuffer));
ValueNameSize = 100;
DataLen = 100;
lResult = RegEnumValue(hNewKey,index,ValueName,&ValueNameSize,NULL, &DataType, DataBuffer, &DataLen);
if (lResult == ERROR_SUCCESS )
{
switch(DataType)
{
case REG_NONE: // No value type (0)
break;
case REG_SZ: //Unicode nul terminated string (1)
break;
case REG_EXPAND_SZ: // Unicode nul terminated string (2)
break;
case REG_BINARY: // Free form binary (3)
break;
case REG_DWORD: // 32-bit number (4)
break;
case REG_MULTI_SZ: // Multiple Unicode strings (7)
break;
default:
break;
}
memcpy((*UartCom)[uartindex].UartName, DataBuffer, DataLen);
(*UartCom)[uartindex].UartNum = ValuesNumber;
uartindex++;
}
else if(lResult == ERROR_NO_MORE_ITEMS)
{
//pMainDlg->AddToInfOut(_T("检索串口完毕!!!"),1,1);
}
else
{
DWORD dw = GetLastError();
// str.Format(_T("检索串口出错: 0x%08x"), dw);
// pMainDlg->AddToInfOut(str,1,1);
return FALSE;
}
}
*UartComNumber = uartindex;
return TRUE;
}DWORD UartComNumber = 0;
struct UartInfo *pUartCom;
BOOL bResult;
bResult = EnumComs(&pUartCom, &UartComNumber, pMainDlg);
DWORD index;
if(bResult)
{
pMainDlg->AddToInfOut(_T("获取串口列表成功"),1,1);
}
else
{
pMainDlg->AddToInfOut(_T("获取串口列表失败"),1,1);
}
for( index= 0;index < UartComNumber; index++)
{
pMainDlg->m_ComboBox.AddString(pUartCom[index].UartName);
}原文地址:http://blog.csdn.net/wzc18743083828/article/details/42008501