標籤:串口 串口註冊表
<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 longDWORD 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);}
Windows自動識別串口的實現