📄 comassistdlg.cpp
字号:
{
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 + -