mfc开发串口,自动获取可用串口,采用注册表方式

注意:这个程序是在上章采用查询法的基础上进行修改的,需要用到上一章的程序,没有的话请看上一张

一、删除采用查询法的一些程序

删除ShangWeiJiDlg.h里面的

	void AddCom(void);
	void EnumerateSerialPorts(CUIntArray& ports, CUIntArray& portse, CUIntArray& portsu);//获取可用串口函数
	afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
		void RefreshCom(void);

删除ShangWeiJiDlg.cpp里面的函数

void CShangWeiJiDlg::AddCom(void)
{

	EnumerateSerialPorts(ports, portse, portsu);
	unsigned short uicounter;
	unsigned short uisetcom;
	CString str;

	//获取可用串口个数
	uicounter = portse.GetSize();
	//如果个数大于0
	if (uicounter > 0)
	{
		//初始化串口列表框
		for (int i = 0; i < uicounter; i++)
		{
			uisetcom = portse.ElementAt(i);
			str.Format(_T("COM%d "), uisetcom);
			m_COM.AddString(str);
		}
	}
}

void CShangWeiJiDlg::EnumerateSerialPorts(CUIntArray& ports, CUIntArray& portse, CUIntArray& portsu)
{
	//清除串口数组内容
	ports.RemoveAll();//所有存在串口
	portse.RemoveAll();//可用串口
	portsu.RemoveAll();//已占用串口

	//因为至多有255个串口,所以依次检查各串口是否存在
	//如果能打开某一串口,或打开串口不成功,但返回的是 ERROR_ACCESS_DENIED错误信息,
	//都认为串口存在,只不过后者表明串口已经被占用
	//否则串口不存在
	for (int i = 1; i < 256; i++)
	{
		//Form the Raw device name
		CString sPort;
		sPort.Format(_T("\\\\.\\COM%d"), i);

		//Try to open the port
		BOOL bSuccess = FALSE;
		HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
		if (hPort == INVALID_HANDLE_VALUE)
		{
			DWORD dwError = GetLastError();

			if (dwError == ERROR_ACCESS_DENIED)
			{
				bSuccess = TRUE;
				portsu.Add(i);       //已占用的串口
			}
		}
		else
		{
			//The port was opened successfully
			bSuccess = TRUE;
			portse.Add(i);      可用的串口
			//Don't forget to close the port, since we are going to do nothing with it anyway
			CloseHandle(hPort);
		}

		//Add the port number to the array which will be returned
		if (bSuccess)
			ports.Add(i);   //所有存在的串口
	}
}


BOOL CShangWeiJiDlg::OnDeviceChange(UINT nEventType, DWORD dwData)
{
	//DEV_BROADCAST_DEVICEINTERFACE* dbd = (DEV_BROADCAST_DEVICEINTERFACE*) dwData;
	switch (nEventType)
	{
	case DBT_DEVICEREMOVECOMPLETE://移除设备
	case DBT_DEVICEARRIVAL://添加设备
		RefreshCom();//刷新组合框的内容
		break;

	default:
		break;
	}

	return TRUE;

}

void CShangWeiJiDlg::RefreshCom(void)
{
	int count = m_COM.GetCount();

	for (int i = 0; i < count; i++)
	{
		m_COM.DeleteString(count - 1 - i);
	}
	AddCom();
	m_COM.SetCurSel(0);
}

删除引用的头文件,不删除也不影响,但是为了后期的方便,最好删除

#include <Dbt.h>

二、加入注册表获取函数

将BOOL CShangWeiJiDlg::OnInitDialog()函数里面的

	AddCom();//向组合框中添加串口设备

换成

FindCommPort(&m_COM);

将void CShangWeiJiDlg::OnBnClickedBtnopen()函数里面的

		//当前端口号
		int curPort = portse.ElementAt(m_COM.GetCurSel());//根据索引找到对应的com口编号
		m_Comm1.put_CommPort(curPort);//端口号

换成

		//拿到COM口索引
		int COM=0;
		int index = m_COM.GetCurSel();
		CString str;
		m_COM.GetLBText(index, str);//根据索引获取内容,得到对应的com口名称

		/*转换COM口名称为数值*/
		char a;
		for (int i = 0; i <str.GetLength(); i++)//GetLength()是获取str里面字符的数量
		{
			a = str.GetAt(i);//GetAt()是读取具体某一位的字符
			if (a < 0x3a && a>0x2f)//判断是否为数字,是的话就进去,不是的话就跳过
			{
				a -= 0x30;//-0x30就可使ASCii数字转换成数值
				COM += a;//将值传递给COM
				COM = COM * 10;//COM左移一位,当最后一位的时候也乘了10,所以最后需要除掉
			}
		}
		COM /= 10;//因为个位的时候也乘了10,所以这里除去10

		m_Comm1.put_CommPort(COM); //选择com,可根据具体情况更改

将ShangWeiJiDlg.h里面函数声明

	void FindCommPort(CComboBox *pComboBox);

将ShangWeiJiDlg.cpp里面加入

/* -------- 从注册表里搜寻安装的串口 -----------------------
Win2k/XP和Win98/Me的注册表值不同,所以用枚举
把串口名字写入一个ComboBox控件里
*/
void CShangWeiJiDlg::FindCommPort(CComboBox *pComboBox)
{
	HKEY hKey;
#ifdef _DEBUG
	ASSERT(pComboBox != NULL);
	pComboBox->AssertValid();
#endif
	if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
		TEXT("Hardware\\DeviceMap\\SerialComm"),
		NULL,
		KEY_READ,
		&hKey) == ERROR_SUCCESS) // 打开串口注册表
	{
		int i = 0;
		TCHAR portName[256], commName[256];
		DWORD dwLong, dwSize;

		while (1)
		{
			dwLong = dwSize = sizeof(portName);

			if (::RegEnumValue(hKey,
				i,
				portName,
				&dwLong,
				NULL,
				NULL,
				(PUCHAR)commName,
				&dwSize) == ERROR_NO_MORE_ITEMS) // 枚举串口
				break;
			pComboBox->AddString(commName); // commName就是串口名字
			i++;
		}
		if (pComboBox->GetCount() == 0)
		{
			::AfxMessageBox(_T("在HKEY_LOCAL_MACHINE:Hardware\\DeviceMap\\SerialComm里找不到串口!!!"));
		}
		RegCloseKey(hKey);
	}
}

然后就可以运行啦,这里最主要的就是void CShangWeiJiDlg::FindCommPort(CComboBox *pComboBox)这个里面的处理函数,它就是在注册表查找的函数。

写好的程序连接

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值