【38】MFC入门到精通——MFC 2种方法实现自动查找串口号 Combobox 控件

发布于:2025-07-20 ⋅ 阅读:(12) ⋅ 点赞:(0)

1 添加 Combobox 控件

2 添加控件变量 m_combobox1

在Combobox 控件右键添加 控件变量 m_combobox1;

添加成功后,可以看到以下两个地方多了两行代码;

CComboBox m_combobox1;

在这里插入图片描述

DDX_Control(pDX, IDC_COMBO2, m_combobox1);

在这里插入图片描述

3.头文件 添加两个函数声明

	BOOL GetComPort2(int FindComNum);
	BOOL GetComPort();

在这里插入图片描述

4. 实现函数 (两种方法实现 自动查找串口号)

以下两个 GetComPort函数,任意一个都可以

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函数,任意一个都可以

/*查找串口号,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();里

void CMFCApplication1Dlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	GetComPort2(0);
	//GetComPort();
}

运行结果
在这里插入图片描述

在这里插入图片描述
可以看到三个串口都自动检测到了
在这里插入图片描述

Visual studio C++ MFC应用程序自动探测串口号

【MFC串口】MFC实现自动查找串口号

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到