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

📄 comassistdlg.cpp

📁 参考萧峰工作室的串口例程,使用mscomm 6.0编写,创新之处在于程序启动时自动检测并安装ocx控件,自动检测串口,单个文件方便使用,不需要手动安装ocx控件,另外也有许多细小功能的增加,如16进制
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		strPortName.Format(_T("COM%d"),i+1);
		//if( CheckPort(strPortName) ) // 检测串口是否可用
		if( QueryComm(strPortName) )   // 检测串口是否存在		
		{
			((CComboBox*)GetDlgItem(IDC_COMBO_COMN))->AddString(strPortName);
			
			if(!bFirst)
				m_strPortName=strPortName;
			bFirst=TRUE;
		}
	}
	
	GetSetting(); // 从 COMAssist.ini 恢复默认设置
	
	UpdateData(FALSE);
}

BOOL CCOMAssistDlg::CheckPort(CString strPortName)
{
	HANDLE hComm = CreateFile(strPortName,					// communication port string (COMX)
							  GENERIC_READ | GENERIC_WRITE,	// read/write types
							  0,							// comm devices must be opened with exclusive access
							  NULL,							// no security attributes
							  OPEN_EXISTING,				// comm devices must use OPEN_EXISTING
							  FILE_FLAG_OVERLAPPED,			// Async I/O
							  0);							// template must be 0 for comm devices
	
	if(hComm == INVALID_HANDLE_VALUE)
	// if(hComm == (HANDLE)8002)
	{
		return FALSE;
	}
	
	if( !CloseHandle(hComm) )
		return FALSE;
	
	return TRUE; // 此串口存在
}

BOOL CCOMAssistDlg::OpenPort(UINT nPortName, CString strSetting)
{
	CString strInfo;
	
	if(m_ctrlComm.GetPortOpen())
		m_ctrlComm.SetPortOpen(FALSE);
	
	m_ctrlComm.SetCommPort(nPortName);	// 选择串口
	m_ctrlComm.SetOutBufferSize(512);
	m_ctrlComm.SetInBufferSize(1024);	
	if( !m_ctrlComm.GetPortOpen() )		// 串口关闭
		m_ctrlComm.SetPortOpen(TRUE);	// 打开串口
	else // 串口已占用
	{
		strInfo.Format(_T("COM%d"),nPortName);
		MessageBox(_T("打开串口失败!"),strInfo,MB_ERR_INVALID_CHARS);
		return FALSE;
	}
	
	m_ctrlComm.SetSettings(strSetting/*"9600,n,8,1"*/); // 波特率9600,无校验,8个数据位,1个停止位
	m_ctrlComm.SetInputMode(1);  // 1:表示以二进制方式检取数据
	m_ctrlComm.SetRThreshold(1); // 参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
	m_ctrlComm.SetInputLen(0);   // 设置当前接收区数据长度为0
	m_ctrlComm.GetInput();		 // 先预读缓冲区以清除残留数据
	
	return TRUE;
}

BOOL CCOMAssistDlg::ClosePort(void)
{
	if(m_ctrlComm.GetPortOpen())
		m_ctrlComm.SetPortOpen(FALSE);
	
	return TRUE;
}

// 预留接收后的数据处理过程
void CCOMAssistDlg::HandleCommand(BYTE* rxdata, UINT len)
{
	unsigned int i;
	CString strtemp;
	
	for(i=0;i<len;i++)					// 将数组转换为Cstring型变量
	{
		BYTE bt=*(char*)(rxdata+i);     // 字符型
		if(m_bReceivedHex)
			strtemp.Format(_T("%02X "),bt); // 将字符送入临时变量strtemp存放
		else
			strtemp.Format(_T("%c"),bt);
		m_strReceive+=strtemp;			// 加入接收编辑框对应字符串    
	}
	
	m_nRxLength+=len;
	m_strRceivedBytes.Format(_T("%d"),m_nRxLength);
	
	if(m_bAutoNewLine && m_bReceiveOver)
		m_strReceive+=_T("\r\n");
	
	SetTimer(TIMER_EVENT_AUTONEWLINE,TIMER_TIMEOUT_RX,NULL);
	m_bReceiveOver=FALSE;
	
	UpdateData(FALSE);
}

UINT CCOMAssistDlg::QueryComm(CString strPortName)
{
	CHAR_T TargetPath[100];
	
	memset(TargetPath,0,sizeof(TargetPath));
	UINT len=QueryDosDevice(strPortName,TargetPath,sizeof(TargetPath));
	
	return len;
}

BOOL CCOMAssistDlg::OnOpenComm(void)
{
	UpdateData(TRUE);
	
	UINT nPortName=1;
	CString strSetting;
	CString temp;
	
	char chPort[8];
	CString strPortN=m_strPortName.Mid(3);
	for(int i=0; i<strPortN.GetLength(); i++)
		chPort[i]=(char)strPortN[i];
	nPortName=atoi(chPort);
	strSetting.Empty();
	strSetting+=m_strBaudRate;
	switch(m_nCheckBit)
	{
		case 0: strSetting+=_T(",n"); break;
		case 1: strSetting+=_T(",o"); break;
		case 2: strSetting+=_T(",e"); break;
		case 3: strSetting+=_T(",m"); break;
		case 4: strSetting+=_T(",s"); break;
		default: strSetting+=_T(",n"); break;
	}
	temp.Format(_T(",%d"),m_nDataBits+5);
	strSetting+=temp;
	temp.Format(_T(",%d"),m_nStopBits+1);
	strSetting+=temp;
	
	if(!m_ctrlComm.GetPortOpen())
	{
		OpenPort(nPortName, strSetting/*_T("9600,n,8,1")*/);
		GetDlgItem(IDC_BUTTON_OPENCOM)->SetWindowText(_T("关闭"));
		m_strPortState=_T("已打开");
	}
	else
	{
		ClosePort();
		GetDlgItem(IDC_BUTTON_OPENCOM)->SetWindowText(_T("打开"));
		m_strPortState=_T("已关闭");
	}
	m_strCurrentOpenPort=m_strPortName;

	UpdateData(FALSE);
	
	return TRUE;
}

void CCOMAssistDlg::OnCheckSendHex()
{
	UpdateData(TRUE);
}

void CCOMAssistDlg::OnCheckRcvHex()
{
	UpdateData(TRUE);
}

// 窗口置顶
void CCOMAssistDlg::OnCheckWndTop()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	
	CRect rect;
	GetWindowRect(&rect);
	if(m_bWindowTop)
		SetWindowPos(&this->wndTopMost, rect.left, rect.top, rect.right, rect.bottom, SWP_NOSIZE);
	else
		SetWindowPos(&this->wndNoTopMost, rect.left, rect.top, rect.right, rect.bottom, SWP_NOSIZE);
}

void CCOMAssistDlg::OnCheckAutoNewLine() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
}

void CCOMAssistDlg::OnCheckAutoSendPeriodically() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	
	char chPeriod[16];
	for(int i=0; i<m_strSendPeriod.GetLength(); i++)
		chPeriod[i]=(char)m_strSendPeriod[i];
	int period=atoi(chPeriod);
	if(m_bAutoSend)
		SetTimer(TIMER_EVENT_AUTOSEND,period,NULL);
	else
		KillTimer(TIMER_EVENT_AUTOSEND);
}

void CCOMAssistDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent==TIMER_EVENT_AUTONEWLINE)
	{
		m_bReceiveOver=TRUE;
		KillTimer(TIMER_EVENT_AUTONEWLINE);
	}
	
	if(nIDEvent==TIMER_EVENT_AUTOSEND)
	{
		OnButtonManualSend();
	}
	
	CDialog::OnTimer(nIDEvent);
}

// 过滤16进制字符串中的非16进制字母
CString CCOMAssistDlg::FilterHexStr(CString strHex)
{
	int i;
	char ch;
	CString str;
	
	strHex.MakeUpper();
	while( (i=strHex.Find(_T("0X")))>=0 )
		strHex.Delete(i, 2);
	
	str.Empty();
	for(i=0; i<strHex.GetLength(); i++) // 检查是否都是合法的16进制字符: 0~F
	{
		ch=(char)strHex.GetAt(i);
		if(ch>=48&&ch<=57 || ch>=65&&ch<=70 || ch>=97&&ch<=102)
		{
			str += ch;
		}
	}
	
	if(str.GetLength()%2) // 如果不足一个16进制值,最后一个字符去掉
		str.Delete(str.GetLength()-1);
	
	return str;
}

// 将合法的16进制字符串转换为整数数组
UINT CCOMAssistDlg::HexStr2ByteArray(CString strHex, CByteArray* byteData)
{
	int i,j;
	CString str,strtemp;
	unsigned char ch;
	unsigned char temp[2];
	
	ASSERT(byteData);
	
	str = strHex;
	str.MakeUpper();
	
	// 将16进制字符串转为整型数组
	for(i=0; i<str.GetLength()/2; i++)
	{
		for(j=0; j<2; j++)
		{
			ch=(char)str.GetAt(2*i+j);
			
			if(ch>=_T('0')&&ch<=_T('9'))
				temp[j]=ch-_T('0');
			else if(ch>=_T('A')&&ch<=_T('F'))
				temp[j]=ch-_T('A')+10;
		}
		byteData->SetAt(i,(temp[0]*16+temp[1]));
	}
	
	return str.GetLength()/2;
}

void CCOMAssistDlg::SaveSetting(void)
{
	UpdateData(TRUE);
	
	CString strSettingPath;
	CHAR_T syspath[64];
	memset(syspath,0,sizeof(syspath));
	//GetSystemDirectory(syspath,sizeof(syspath));
	GetWindowsDirectory(syspath,sizeof(syspath));
	
	strSettingPath.Empty();
	strSettingPath+=syspath;
	strSettingPath+=g_strSetting;
	
	CString strDataBits,strCheckBit,strStopBits;
	strDataBits.Format(_T("%d"),m_nDataBits);
	strCheckBit.Format(_T("%d"),m_nCheckBit);
	strStopBits.Format(_T("%d"),m_nStopBits);
	::WritePrivateProfileString(_T("Comm"),_T("PortName"),m_strPortName,strSettingPath);
	::WritePrivateProfileString(_T("Comm"),_T("BaudRate"),m_strBaudRate,strSettingPath);	
	::WritePrivateProfileString(_T("Comm"),_T("DataBits"),strDataBits,strSettingPath);
	::WritePrivateProfileString(_T("Comm"),_T("CheckBit"),strCheckBit,strSettingPath);
	::WritePrivateProfileString(_T("Comm"),_T("StopBits"),strStopBits,strSettingPath);
	
	CString strSendHex,strReceiveHex,strWindowsTop,strAutoNewLine;
	strSendHex.Format(_T("%d"),m_bSendHex);
	strReceiveHex.Format(_T("%d"),m_bReceivedHex);
	strWindowsTop.Format(_T("%d"),m_bWindowTop);
	strAutoNewLine.Format(_T("%d"),m_bAutoNewLine);
	::WritePrivateProfileString(_T("Others"),_T("SendHex"),strSendHex,strSettingPath);
	::WritePrivateProfileString(_T("Others"),_T("ReceiveHex"),strReceiveHex,strSettingPath);	
	::WritePrivateProfileString(_T("Others"),_T("WindowTop"),strWindowsTop,strSettingPath);
	::WritePrivateProfileString(_T("Others"),_T("AutoNewLine"),strAutoNewLine,strSettingPath);
	::WritePrivateProfileString(_T("Others"),_T("AutoSendPeriod"),m_strSendPeriod,strSettingPath);
	::WritePrivateProfileString(_T("Others"),_T("LastSavePath"),m_strLastSavePath,strSettingPath);
}

void CCOMAssistDlg::GetSetting(void)
{
	CString strSettingPath;
	CHAR_T syspath[64];
	memset(syspath,0,sizeof(syspath));
	//GetSystemDirectory(syspath,sizeof(syspath));
	GetWindowsDirectory(syspath,sizeof(syspath));
	
	strSettingPath.Empty();
	strSettingPath+=syspath;
	strSettingPath+=g_strSetting;
	
	CHAR_T strPortName[16],strBaudRate[16];
	int nDataBits=3,nCheckBit=0,nStopBits=0;
	memset(strPortName,0,sizeof(strPortName));
	memset(strBaudRate,0,sizeof(strBaudRate));
	::GetPrivateProfileString(_T("Comm"),_T("PortName"),_T("COM1"),strPortName,sizeof(strPortName),strSettingPath);
	::GetPrivateProfileString(_T("Comm"),_T("BaudRate"),_T("19200"),strBaudRate,sizeof(strBaudRate),strSettingPath);
	nDataBits=GetPrivateProfileInt(_T("Comm"),_T("DataBits"),3,strSettingPath);
	nCheckBit=GetPrivateProfileInt(_T("Comm"),_T("CheckBit"),0,strSettingPath);
	nStopBits=GetPrivateProfileInt(_T("Comm"),_T("StopBits"),0,strSettingPath);
	
	int bSendHex=1,bReceiveHex=1,bWindowsTop=0,bAutoNewLine=1;
	bSendHex=GetPrivateProfileInt(_T("Others"),_T("SendHex"),1,strSettingPath);
	bReceiveHex=GetPrivateProfileInt(_T("Others"),_T("ReceiveHex"),1,strSettingPath);
	bWindowsTop=GetPrivateProfileInt(_T("Others"),_T("WindowTop"),0,strSettingPath);
	bAutoNewLine=GetPrivateProfileInt(_T("Others"),_T("AutoNewLine"),0,strSettingPath);
	
	CHAR_T strLastSavePath[256],strAutoSendPeriod[16];
	memset(strLastSavePath,0,sizeof(strLastSavePath));	
	memset(strAutoSendPeriod,0,sizeof(strAutoSendPeriod));
	::GetPrivateProfileString(_T("Others"),_T("LastSavePath"),_T(""),strLastSavePath,sizeof(strLastSavePath),strSettingPath);
	::GetPrivateProfileString(_T("Others"),_T("AutoSendPeriod"),_T("1000"),strAutoSendPeriod,sizeof(strAutoSendPeriod),strSettingPath);
	
	m_strPortName=strPortName;
	m_strBaudRate=strBaudRate;
	m_strSendPeriod=strAutoSendPeriod;
	m_nDataBits=nDataBits;
	m_nCheckBit=nCheckBit;
	m_nStopBits=nStopBits;
	
	m_bSendHex=bSendHex;
	m_bReceivedHex=bReceiveHex;
	m_bWindowTop=bWindowsTop;
	m_bAutoNewLine=bAutoNewLine;
	
	m_strLastSavePath=strLastSavePath;
	
	CRect rect;
	GetWindowRect(&rect);
	if(m_bWindowTop)
		SetWindowPos(&this->wndTopMost, rect.left, rect.top, rect.right, rect.bottom, SWP_NOSIZE);
	else
		SetWindowPos(&this->wndNoTopMost, rect.left, rect.top, rect.right, rect.bottom, SWP_NOSIZE);
}

// 将一个2进制文件转为hex格式的16进制文件
BOOL CCOMAssistDlg::Convert2Hex(CString strSrcFilename, CString strDstFilename)
{
	CFile file0,file1;
	if(!file0.Open(strSrcFilename, CFile::modeRead))
	{
		AfxMessageBox(_T("打开源文件出错!"));
		return FALSE;
	}
	if(!file1.Open(strDstFilename, CFile::modeCreate|CFile::modeWrite))
	{
		AfxMessageBox(_T("打开目的文件出错!"));
		return FALSE;
	}
	
	CHAR_T buf_r;
	CString buf_w;
	ULONGLONG len=file0.GetLength();	
	for(ULONGLONG i=1; i<=len; i++)
	{
		file0.Read(&buf_r,1);
		buf_w.Format(_T("0x%02X, "), buf_r);
		file1.Write(buf_w,6);
		if(i%10==0)
			file1.Write(_T("\r\n"),2);
	}
	
	file1.Flush();	
	file0.Close();
	file1.Close();
	
	return TRUE;
}

⌨️ 快捷键说明

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