【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实现自动查找串口号

相关推荐
幸幸子.24 分钟前
LeetCode 组合总数
c++·算法·leetcode
☆璇36 分钟前
【C++】哈希
c++·算法·哈希算法
菜就多练,以前是以前,现在是现在2 小时前
Codeforces Round 1042 (Div. 3)
c++·算法
学习编程的gas2 小时前
C++多态:理解面向对象的“一个接口,多种实现”
开发语言·c++
FirstFrost --sy3 小时前
C++ stack and queue
开发语言·c++·queue·stack·priority_queue
daiyanyun4 小时前
Ubuntu 20.04 虚拟机安装完整教程:从 VMware 到 VMware Tools
linux·c语言·c++·ubuntu
GalaxyPokemon4 小时前
Linux的pthread怎么实现的?(包括到汇编层的实现)
运维·开发语言·c++
菜鸟555554 小时前
河南萌新联赛2025第五场 - 信息工程大学
c++·算法·思维·河南萌新联赛
·Alone5 小时前
C++ list模拟实现
开发语言·c++
科大饭桶5 小时前
Linux系统编程Day13 -- 程序地址空间(进阶)
linux·运维·c语言·数据结构·c++