⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialcommdlg.cpp

📁 MSComm控件编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	DWORD style=WS_VISIBLE|WS_CHILD;
	if (!m_COM.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM))
	{
		::AfxMessageBox("Failed to create OLE Communications Control\n");
		return -1;// fail to create
	}
	
	return 0;
}

void CSerialCommDlg::OnClearSend() 
{	
	this->m_szSendData.Empty();
	this->UpdateData(FALSE);
}

void CSerialCommDlg::OnSend() 
{
	if(m_COM.GetPortOpen())
	{
		UpdateData(TRUE);	//读取编辑框内容
		if (!m_szSendData.IsEmpty())
		{
			CByteArray hexdata;
			int len = String2Hex(m_szSendData, hexdata); //此处返回的len可以用于计算发送了多少个十六进制数
			m_COM.SetOutput(COleVariant(hexdata)); //发送十六进制数据
			m_nSendCount += len;
			this->UpdateData(FALSE);
			//debug start
			/*
			CString msg;
			int length = len;//String2Hex(m_szSendData, hexdata);
			msg.Format("length = %d : ", length);
			for (int i = 0; i < length; i++)
			{
				CString tmp;
				tmp.Format("%02X", hexdata.GetAt(i));
				msg += tmp;
			}			
			::AfxMessageBox(msg);
			*/
			//debug end
			//m_COM.SetOutput(COleVariant(m_szSendData));//发送数据
		}
		else
		{
			::AfxMessageBox("没有可以发送的数据");
		}
	}
	else 
	{
		::AfxMessageBox("请先打开串行口");
	}
}

void CSerialCommDlg::OnClearRecv() 
{
	m_iRecvDataCount = 0;
	this->m_szRecvData.Empty();
	this->UpdateData(FALSE);
}

void CSerialCommDlg::OnSave() 
{
	::AfxMessageBox("保存数据未处理");
}

void CSerialCommDlg::OnCancel() 
{
		
	if(m_COM.GetPortOpen())		//已经打开串口
	{
		m_COM.SetPortOpen(FALSE);	//关闭串口	
		m_szStatus = "关闭";
		this->UpdateData(FALSE);
	}

	CDialog::OnCancel();
}

int CSerialCommDlg::String2Hex(CString str, CByteArray &senddata)
{
	int hexdata, lowhexdata;
	int hexdatalen = 0;
	int len = str.GetLength();
	senddata.SetSize(len / 2);
	for(int i = 0; i < len; )
	{
		char lstr, hstr = str[i];
		if(hstr == ' ')
		{
			i++;
			continue;
		}
		i++;
		if(i >= len)
			break;
		lstr = str[i];
		hexdata = ConvertHexChar(hstr);
		lowhexdata = ConvertHexChar(lstr);
		if((hexdata == 16) || (lowhexdata == 16))
			break;
		else 
			hexdata=hexdata*16+lowhexdata;
		i++;
		senddata[hexdatalen]=(char)hexdata;
		hexdatalen++;
	}
	senddata.SetSize(hexdatalen);
	return hexdatalen;
	
}

char CSerialCommDlg::ConvertHexChar(char ch)
{
	if((ch >= '0' ) && (ch <= '9'))
	{
		return ch - '0';//0x30;
	}
	else if((ch >= 'A' ) && (ch <= 'F'))
	{
		return ch - 'A' + 10;
	}
	else if(( ch >= 'a') &&( ch <= 'f'))
	{
		return ch - 'a' + 10;
	}
	else 
	{
		return (-1);
	}
}

void CSerialCommDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	
	int temp1,temp2;
	temp1 = m_Recv_Ctrl.GetScrollPos(SB_VERT);
	switch (nSBCode)
	{
	case SB_THUMBPOSITION :
		m_Recv_Ctrl.SetScrollPos(SB_VERT, nPos);
		break;
	case SB_LINEDOWN:
		{
			int min = 0;
			int max = 10;
			temp2 = (max - min) / 10;
			if ((temp1 - temp2) > min)
			{
				temp1 -= temp2;
			}
			else
			{
				temp1 = min;
			}
			m_Recv_Ctrl.SetScrollPos(SB_VERT, temp1);
		}
		break;
	default:
		break;
	}
	
	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CSerialCommDlg::OnOpenClose() 
{
	if (!m_COM.GetPortOpen())			//not opened
	{
		if (m_COM.GetPortOpen())
		{
			m_COM.SetPortOpen(FALSE);	//先关闭
		}
		this->UpdateData(TRUE);			//读取内容		
		if (m_szCOMName.IsEmpty()  ||			m_szParity.IsEmpty()   ||
			m_szDataBits.IsEmpty() ||			m_szStopBits.IsEmpty() ||
			m_szBaud.IsEmpty())
		{
			::AfxMessageBox("请设置好通信参数");
			return ;
		}
		CString	szSetting;
		szSetting = m_szBaud + ",";
		CString parity;
		if (m_szParity == "None")
			parity = "n";
		else if (m_szParity == "Odd")
			parity = "o";
		else if (m_szParity == "Even")
			parity = "e";
		else if (m_szParity == "Mark")
			parity = "m";
		else if (m_szParity == "Space")
			parity = "s";
		else
		{
			::AfxMessageBox("请设置好校验方式");
			return ;
		}
		szSetting += parity + ",";
		szSetting += m_szDataBits + ",";
		szSetting += m_szStopBits;		
		//::AfxMessageBox(szSetting);

		if (m_szCOMName == "COM1")
		{
			m_COM.SetCommPort(1);     			
		}
		else if (m_szCOMName == "COM2")
		{
			m_COM.SetCommPort(2);  
		}
		else
		{
			::AfxMessageBox("COM端口不对");
			m_COM.SetPortOpen(FALSE);	//串口
			m_szStatus = "关闭";
			this->UpdateData(FALSE);
			return ;
		}
		m_COM.SetPortOpen(TRUE);		//打开串口
		m_szStatus = "打开";
		this->UpdateData(FALSE);
		m_COM.SetSettings(szSetting);		
		//::AfxMessageBox("after SetSettings()");
		m_COM.SetInputMode(1);			//1:表示以二进制方式检取数据
		m_COM.SetRThreshold(1);			//为1表示有一个字符引发一个事件
		m_COM.SetSThreshold(1); 		//参数1表示每当串口接收缓冲区中有
										//多于或等于1个字符时将引发一个接收数据的OnComm事件
		//::AfxMessageBox("after SetSThreshold()");
		//m_COM.SetInBufferSize(16);		//设置输入缓冲区的大小,Bytes
		//m_COM.SetOutBufferSize(16);		//设置输入缓冲区的大小,Bytes
		m_COM.SetInputLen(0);			//设置当前接收区数据长度为0
		//::AfxMessageBox("after SetInputLen()");
		m_COM.GetInput();				//先预读缓冲区以清除残留数据
		
		this->GetDlgItem(IDC_OPEN_CLOSE)->SetWindowText("关闭串口");
	}
	else
	{
		m_COM.SetPortOpen(FALSE);		//关闭串口	
		m_szStatus = "关闭";
		this->UpdateData(FALSE);
		this->GetDlgItem(IDC_OPEN_CLOSE)->SetWindowText("打开串口");
	}
}

void CSerialCommDlg::OnSelchangeBaud() 
{
	SettingChanged();
}

void CSerialCommDlg::OnSelchangeComName() 
{
	SettingChanged();
}

void CSerialCommDlg::OnSelchangeDataBit() 
{
	SettingChanged();
}

void CSerialCommDlg::OnSelchangeParity() 
{
	SettingChanged();
}

void CSerialCommDlg::OnSelchangeStopBit() 
{
	SettingChanged();
}

void CSerialCommDlg::SettingChanged()
{
	if (m_ctrlCOMName.SetCurSel(m_ctrlCOMName.GetCurSel()) == CB_ERR ||
		m_ctrlBaud.SetCurSel(m_ctrlBaud.GetCurSel()) == CB_ERR ||
		m_ctrlDataBits.SetCurSel(m_ctrlDataBits.GetCurSel()) == CB_ERR ||
		m_ctrlParity.SetCurSel(m_ctrlParity.GetCurSel()) == CB_ERR ||
		m_ctrlStopBits.SetCurSel(m_ctrlStopBits.GetCurSel()) == CB_ERR)
	{
		::AfxMessageBox("error occur in SettingChanged()");
		return ;
	}

	if (m_COM.GetPortOpen())			//opened
	{		
		this->UpdateData(TRUE);			//读取内容		
		if (m_szCOMName.IsEmpty()  ||			m_szParity.IsEmpty()   ||
			m_szDataBits.IsEmpty() ||			m_szStopBits.IsEmpty() ||
			m_szBaud.IsEmpty())
		{
			::AfxMessageBox("请设置好通信参数");
			return ;
		}
		CString	szSetting;
		szSetting = m_szBaud + ",";
		CString parity;
		if (m_szParity == "None")
			parity = "n";
		else if (m_szParity == "Odd")
			parity = "o";
		else if (m_szParity == "Even")
			parity = "e";
		else if (m_szParity == "Mark")
			parity = "m";
		else if (m_szParity == "Space")
			parity = "s";
		else
		{
			::AfxMessageBox("请设置好校验方式");
			parity = "n";
			return ;
		}
		
		szSetting += parity + ",";
		szSetting += m_szDataBits + ",";
		szSetting += m_szStopBits;		
		//::AfxMessageBox(szSetting);

		if (m_szCOMName == "COM1" || 
			m_szCOMName == "COM2")
		{
			m_COM.SetPortOpen(FALSE);		//先关闭
			if (m_szCOMName == "COM1")		m_COM.SetCommPort(1);     			
			if (m_szCOMName == "COM2")		m_COM.SetCommPort(2); 
		}
		else
		{
			::AfxMessageBox("COM端口不对");
			//m_COM.SetPortOpen(FALSE);	//打开串口
			return ;
		}
		
		m_COM.SetPortOpen(TRUE);		//打开串口
		m_szStatus = "打开";
		this->UpdateData(FALSE);
		m_COM.SetSettings(szSetting);			
		m_COM.SetInputMode(1);			//1:表示以二进制方式检取数据
		m_COM.SetRThreshold(1);			//为1表示有一个字符引发一个事件
		m_COM.SetSThreshold(1); 		//参数1表示每当串口接收缓冲区中有
										//多于或等于1个字符时将引发一个接收数据的OnComm事件
		m_COM.SetInputLen(0);			//设置当前接收区数据长度为0
		m_COM.GetInput();				//先预读缓冲区以清除残留数据
		//m_COM.SetInBufferSize(16);		//设置输入缓冲区的大小,Bytes
		//m_COM.SetOutBufferSize(16);		//设置输入缓冲区的大小,Bytes
	}
	else
	{
		this->UpdateData(TRUE);			//读取内容
	}
}

void CSerialCommDlg::OnClearCount() 
{
	m_nSendCount = 0;
	m_nRecvCount = 0;
	UpdateData(FALSE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -