If you have experience in hardware programming, you will not be unfamiliar with serial port operations. Currently, most devices and computers communicate through serial ports. For lower-computer communication, it is often necessary to traverse all serial ports of the Local Machine and confirm the serial port on which the target device is connected through the message. The general method is to traverse from COM1 to com10, because there should not be so many serial ports on a machine, this should cover all available serial ports. However, this method seems too violent. Is there any way to obtain all the available serial ports of the Local Machine? Of course, the answer is yes.
We know how many available serial ports are available on the local machine if we open the Windows Hardware manager. The hardware device system such as serial port will naturally manage the information. Is there any interface function or some way to obtain the information? The first thing that comes to mind is the Windows registry, which can solve this problem. In HKEY_LOCAL_MACHINE, We can find such a table item level by level hardware \ devicemap \ serialcomm. Obviously, the serial port information is recorded here. You only need to use some basic registry functions to obtain all the information of the local serial port. Here we will get the serial port name and add it to a piece of code in ComboBox.
void CEnumComDlg::FindComPort(){HKEY hKey;if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Hardware\\DeviceMap\\SerialComm"), NULL, KEY_READ, &hKey)==ERROR_SUCCESS){TCHARszPortName[256], szComName[256];DWORDdwLong, dwSize;intnCount= 0;CComboBox*pCombo= (CComboBox*)GetDlgItem(IDC_COMBO_COM);pCombo->ResetContent();while(true){dwLong= dwSize= 256;if(RegEnumValue(hKey, nCount, szPortName, &dwLong, NULL, NULL, (PUCHAR)szComName, &dwSize)==ERROR_NO_MORE_ITEMS)break;pCombo->InsertString(nCount, szComName);nCount++;}RegCloseKey(hKey);pCombo->SetCurSel(0);}}
In this way, the problem about the serial port is solved, but we will continue to discuss it and see if it can be improved. We know that the number of serial ports on the local machine is limited. Currently, most machines have only one serial port, but no serial ports on the notebook. So what if we need to control the instrument through multiple serial ports? If you have any experience in this area, you should know that you can use USB serial port to expand your machine. Now the problem arises. If we have obtained the current serial port information of the local machine through the above function, and now we have added a serial port through the USB serial port adapter, so will we never be able to use this serial port? Is there any way to monitor system hardware changes? A message wm_devicechange is required to solve this problem. When the system hardware changes, the system will send this message to the application to inform the System of the hardware changes, through this message, we can promptly update the serial port information. The sample code is as follows:
BOOL CEnumComDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData){if(nEventType==DBT_DEVNODES_CHANGED)FindComPort();returnTRUE;}
Here we should say that we have solved the problem of enumeration serial port. I have made a simple small example. The above code is taken from this example, if you are interested, you can download it from my resources. In addition, we will discuss how to solve similar problems in WindowsCE. Ce provides a set of more general hardware operation interface functions findfirstdevice and findnextdevice. These functions are used in a similar way as file operation functions with similar names and can access all system devices, the following code implements the functions implemented above for your reference only.
DEVMGR_DEVICE_INFORMATIONddiFind= {0};ddiFind.dwSize= sizeof(DEVMGR_DEVICE_INFORMATION);HANDLEhDevFind= FindFirstDevice(DeviceSearchByLegacyName, L"COM*", &ddiFind);CStringstrCom;m_comboComList.ResetContent();do{strCom= ddiFind.szLegacyName;strCom= strCom.Left(strCom.GetLength()-1);m_comboComList.AddString(strCom);}while(FindNextDevice(hDevFind, &ddiFind));if(hDevFind!=INVALID_HANDLE_VALUE)FindClose(hDevFind);
It should be said that the solution to this problem is complete. If you have any better solutions for such problems, please kindly advise.