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

文章目录

  • [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应用程序自动探测串口号

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

相关推荐
whoarethenext6 分钟前
使用 C++ 和 OpenCV 进行表面划痕检测
开发语言·c++·opencv·划痕检测
tomato0920 分钟前
Codeforces Round 1037 (Div. 3)(补题)
c++
遇见尚硅谷39 分钟前
C语言:20250719笔记
c语言·开发语言·数据结构·c++·算法
mit6.8241 小时前
7.17 滑动窗口 |assign |memo |pii bfs |位运算
c++·算法
丁劲犇1 小时前
Qt Graphs 模块拟取代 charts 和 data visualization还有很长的路要走
c++·qt·qml·visualization·charts·graphs
mit6.8242 小时前
异步解决一切问题 |消息队列 |减少嵌套 |hadoop |rabbitmq |postsql
c++
我要成为c嘎嘎大王3 小时前
【C++】初识C++(2)
开发语言·c++
C语言小火车3 小时前
【面试题】大厂高压面经实录丨第二期
c语言·开发语言·数据结构·c++·算法
落羽的落羽3 小时前
【C++】红黑树,“红“与“黑”的较量
开发语言·c++
十五年专注C++开发5 小时前
pugiXML:一个轻量级、高性能的 C++ XML 解析库
xml·c++·跨平台·cmake