文章目录
- [1 添加 Combobox 控件](#1 添加 Combobox 控件)
- [2 添加控件变量 m_combobox1](#2 添加控件变量 m_combobox1)
- [3.头文件 添加两个函数声明](#3.头文件 添加两个函数声明)
- [4. 实现函数 (两种方法实现 自动查找串口号)](#4. 实现函数 (两种方法实现 自动查找串口号))
- [5 调用 及运行结果](#5 调用 及运行结果)
1 添加 Combobox 控件
2 添加控件变量 m_combobox1
在Combobox 控件右键添加 控件变量 m_combobox1;
添加成功后,可以看到以下两个地方多了两行代码;
cpp
CComboBox m_combobox1;

cpp
DDX_Control(pDX, IDC_COMBO2, m_combobox1);

3.头文件 添加两个函数声明
cpp
BOOL GetComPort2(int FindComNum);
BOOL GetComPort();

4. 实现函数 (两种方法实现 自动查找串口号)
以下两个 GetComPort函数,任意一个都可以
cpp
BOOL CMFCApplication1Dlg::GetComPort()
{
long lReg;
HKEY hKey;
DWORD MaxValueLength;
DWORD dwValueNumber;
lReg = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
0, KEY_QUERY_VALUE, &hKey);
if (lReg != ERROR_SUCCESS) //成功时返回ERROR_SUCCESS,
{
AfxMessageBox(TEXT("Open Registry Error!\n"));
return FALSE;
}
lReg = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&dwValueNumber, &MaxValueLength, NULL, NULL, NULL);
if (lReg != ERROR_SUCCESS) //没有成功
{
AfxMessageBox(TEXT("Getting Info Error!\n"));
return FALSE;
}
TCHAR* pValueName, * pCOMNumber;
DWORD cchValueName, dwValueSize = 10;
for (int i = 0; i < dwValueNumber; i++)
{
cchValueName = MaxValueLength + 1;
dwValueSize = 10;
pValueName = (TCHAR*)VirtualAlloc(NULL, cchValueName, MEM_COMMIT, PAGE_READWRITE);
lReg = RegEnumValue(hKey, i, pValueName,
&cchValueName, NULL, NULL, NULL, NULL);
if ((lReg != ERROR_SUCCESS) && (lReg != ERROR_NO_MORE_ITEMS))
{
AfxMessageBox(TEXT("Enum Registry Error or No More Items!\n"));
return FALSE;
}
pCOMNumber = (TCHAR*)VirtualAlloc(NULL, 6, MEM_COMMIT, PAGE_READWRITE);
lReg = RegQueryValueEx(hKey, pValueName, NULL,
NULL, (LPBYTE)pCOMNumber, &dwValueSize);
if (lReg != ERROR_SUCCESS)
{
AfxMessageBox(TEXT("Can not get the name of the port"));
return FALSE;
}
CString str(pCOMNumber);
m_combobox1.AddString(str); //把获取的值加入到ComBox控件中
m_combobox1.SelectString(0, str);// 把获取的串口,给combobox的控件选择第一个串口号
//m_combobox1.SetCurSel(0);//让combo box的control控件选择第一个串口号(第一个不一定是获取到的那个)
VirtualFree(pValueName, 0, MEM_RELEASE);
VirtualFree(pCOMNumber, 0, MEM_RELEASE);
}
return TRUE;
}
两个 GetComPort函数,任意一个都可以
cpp
/*查找串口号,FindComNum=0,从COM 1~16 搜索,非0时,判断其是否存在*/
BOOL CMFCApplication1Dlg::GetComPort2(int FindComNum)
{
CString comPortStr;
CString comStr;
int iTmp;
int jTmp;
//m_com = 0;
int kTmp = 0;
HANDLE m_hCom;
if (FindComNum == 0) // 如果串口存在,则执行相应的初始化(采用控件)
{
jTmp = 1;
iTmp = 16;
comPortStr.Empty();//清除
for (; jTmp <= iTmp; jTmp++)
{
if (jTmp < 10)
{
comStr.Format(_T("COM%d"), jTmp);
}
else
{
comStr.Format(_T("\\\\.\\COM%d"), jTmp);//大于10就要改变输入方式,否则找不到
}
m_hCom = CreateFile(comStr, GENERIC_READ |
GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, NULL); // 这里的CreateFile函数起了很大的作用,可以用来创建系统设备文件,如果该设备不存在或者被占用,则会返回一个错误,
//即下面的 INVALID_HANDLE_VALUE ,据此可以判断可使用性。详细参见MSDN中的介绍。
if (m_hCom != INVALID_HANDLE_VALUE) // 如果没有该设备,或者被其他应用程序在用
{
/*查找可用串口*/
comStr.Format(_T("COM%d"), jTmp);
comPortStr += comStr; //全局记录字符串,edit用于显示
comPortStr += " ";
kTmp++;
if (kTmp % 8 == 0)
comPortStr += "\r\n ";
m_combobox1.AddString(comStr);
if (kTmp == 1)
m_combobox1.SelectString(0, comStr);// 把获取的串口,给combobox的控件选择第一个串口号
//m_combobox1.SetCurSel(0);//让combo box的control控件选择第一个串口号(第一个不一定是获取到的那个)
}
SetCommMask(m_hCom, 0);// 关闭文件句柄,后面我们采用控件,不用API
CloseHandle(m_hCom);
}
if (jTmp)
return TRUE;
else
return FALSE;
}
else
{
if (FindComNum < 10)
{
comStr.Format(_T("COM%d"), FindComNum);
}
else
{
comStr.Format(_T("\\\\.\\COM%d"), FindComNum);//大于10就要改变输入方式,否则找不到
}
m_hCom = CreateFile(comStr, GENERIC_READ |
GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, NULL); // 这里的CreateFile函数起了很大的作用,可以用来创建系统设备文件,如果该设备不存在或者被占用,则会返回一个错误,
//即下面的 INVALID_HANDLE_VALUE ,据此可以判断可使用性。详细参见MSDN中的介绍。
if (m_hCom != INVALID_HANDLE_VALUE) // 如果没有该设备,或者被其他应用程序在用
{
return FALSE;
}
else
{
SetCommMask(m_hCom, 0);// 关闭文件句柄,后面我们采用控件,不用API
CloseHandle(m_hCom);
}
}
return TRUE;
}
void CMFCApplication1Dlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
GetComPort2(0);
//GetComPort();
}
5 调用 及运行结果
本人的计算机当前串口COM5 和两个虚拟串口COM1和COM2
在按键里面 调用函数,也可以写在OnInitDialog();里
cpp
void CMFCApplication1Dlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
GetComPort2(0);
//GetComPort();
}
运行结果

可以看到三个串口都自动检测到了
Visual studio C++ MFC应用程序自动探测串口号
