📄 pc2pcview.cpp
字号:
}
dwFileLen=arrRcvData[1]+arrRcvData[2]*256+arrRcvData[3]*65536+arrRcvData[4]*16777216;
myFile.SetLength(dwFileLen);
uintStxCurNo=1;
bytRcvStatus=1;
bytResendCount=0;
arrSendData[0]=6;
Write(arrSendData,1);
break;
}
case 100://超时错误
{
//接收0态时,对超时不作处理
break;
}
}
break;
}
case 1:
{
switch(lParam)
{
case EV_RXCHAR://收到字符
{
switch(Detect(1))
{
case 0://收到指定数量的字符
{
break;
}
case 4://超时错误
{
DisRcv(4);
return -1;
break;
}
case 8://无效,输入缓冲区中字符数量为0
{
return 0;
break;
}
}
switch(Read(myByte,1))
{
case 0:
{
break;
}
case 4:
{
DisRcv(4);
return -1;
break;
}
case 16:
{
DisRcv(16);
return -1;
break;
}
}
switch(myByte[0])//判断是STX还是ETX
{
case 2://首字符是STX
{
//读取数据
arrRcvData[0]=myByte[0];
uintRcvLen=1028;
switch(Detect(1027))
{
case 0://收到指定数量的字符
{
//跳出switch,继续下面的操作
break;
}
case 4://超时错误
{
DisRcv(4);
return -1;
break;
}
case 8://无效,输入缓冲区中字符数量为0
{
return 0;
break;
}
}///
switch(Read(myByte,1027))
{
case 0:
{
break;
}
case 4:
{
DisRcv(4);
return -1;
break;
}
case 16:
{
DisRcv(16);
return -1;
break;
}
}
for(i=0;i<=1026;i++)
{
arrRcvData[i+1]=myByte[i];//保存数据至arrRcvData[]数组中
}
uintStxCurNo=arrRcvData[1]+arrRcvData[2]*256;
if(uintStxCurNo==1)
{
myEdit.SetSel(1000000,1000000);
myEdit.ReplaceSel("正在接收数据……\15\12");
}
strDis.Format("已接收(%.0f%%)",(float)((uintStxCurNo+1)*1024)/dwFileLen*100);
m_pStatus->SetPaneText(0,strDis); //将传输进度显示在状态条上
myFile.Seek((uintStxCurNo-1)*1024,CFile::begin);
myFile.Write(&arrRcvData[3],1024);
bytResendCount=0;
arrSendData[0]=6;
Write(arrSendData,1);
break;
}
case 3://首字符是ETX
{
//读取数据
arrRcvData[0]=myByte[0];
switch(Read(myByte,2))
{
case 0:
{
break;
}
case 4:
{
DisRcv(4);
return -1;
break;
}
case 16:
{
DisRcv(16);
return -1;
break;
}
}
arrRcvData[1]=myByte[0];
arrRcvData[2]=myByte[1];
uintRcvLen=1+2+2+(arrRcvData[1]+arrRcvData[2]*256)+1;//数据总长度
switch(Read(myByte,uintRcvLen-3))
{
case 0:
{
break;
}
case 4:
{
DisRcv(4);
return -1;
break;
}
case 16:
{
DisRcv(16);
return -1;
break;
}
}
for(i=0;(UINT)i<=uintRcvLen-2;i++)
{
arrRcvData[i+3]=myByte[i];
}
//至此,完整数据已经读入arrRcvData[]中。
uintStxCurNo=arrRcvData[3]+arrRcvData[4]*256;
if(uintStxCurNo==1)
{
myEdit.SetSel(1000000,1000000);
myEdit.ReplaceSel("正在接收数据……\15\12");
}
myFile.Seek((uintStxCurNo-1)*1024,CFile::begin);
myFile.Write(&arrRcvData[5],arrRcvData[1]+arrRcvData[2]*256);
myEdit.SetSel(1000000,1000000);
myEdit.ReplaceSel("接收完毕!\15\12\15\12");
strDis="已接收完毕";
m_pStatus->SetPaneText(0,strDis); //将传输进度显示在状态栏上
bytRcvStatus=0;
bytActStatus=10;
bytSendStatus=0;
bytResendCount=0;
arrSendData[0]=6;
Write(arrSendData,1);
if(myFile.m_pStream!=NULL)
{
myFile.Close();//关闭打开的文件
}
break;
}
}
break;
}
case 100://超时错误
{
break;
}
}
break;
}
}
break;
}
}
return 0;
}
void CPC2PCView::OnUpdateSendfile(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (blnOpened)//根据串口是否打开,决定是否允许“发送文件”命令
{
if(!((bytSendStatus+bytRcvStatus)>0))//当前既没开始发送,也没开始接收
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
else
{
pCmdUI->Enable(false);
}
}
void CPC2PCView::OnUpdateSetupcom(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (!blnOpened)//根据串口是否打开,决定是否允许“设置”命令
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
void CPC2PCView::OnUpdateOpencom(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (!blnOpened && blnSeted)//根据串口是否打开,决定是否允许“打开”命令
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
void CPC2PCView::OnUpdateClosecom(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (blnOpened)//根据串口是否打开,决定是否允许“关闭”命令
{
if(!((bytSendStatus+bytRcvStatus)>0))//当前既没开始发送文件,也没开始接收文件
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
else
{
pCmdUI->Enable(false);
}
}
int CPC2PCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CEditView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
CEdit& myEdit=this->GetEditCtrl( );
myEdit.SetReadOnly (true); //将显示区域设为只读
hWnd=GetSafeHwnd(); //获取当前窗口的句柄
blnOpened=false; //串口已经打开标志
blnSeted=false; //已经设置过通信参数
bytRcvStatus=0; //初始化时,接收状态为等待ENQ
dwTimeoutValue=1500; //初始化事件线程超时时间
bytActStatus=10; //初始化为接收态
blnNoTimeout=true;
uintStxCurNo=0;
bytTimeoutCounter=0;
return 0;
}
bool CPC2PCView::DisSend(BYTE bytType)//发送态显示信息函数,bytType决定显示信息的内容
{
CString strDis;
CEdit& myEdit=this->GetEditCtrl();
myEdit.SetReadOnly(true);
myEdit.SetSel(1000000,1000000);
switch(bytType)
{
case 1:
{
strDis="取消操作!\15\12";
break;
}
case 2:
{
strDis="收到无效的命令!\15\12";
break;
}
case 4:
{
strDis="对方无响应,超时错误!\15\12";
break;
}
case 8:
{
strDis="重试次数多于3次!\15\12";
break;
}
}
myEdit.ReplaceSel(strDis);
bytSendStatus=0;//恢复发送0态
bytActStatus=10;//恢复为接收态
bytRcvStatus=0;
bytResendCount=0;//重试次数初始化为0
if(myFile.m_pStream!=NULL)
{
myFile.Close();//关闭打开的文件
}
Beep(1000,50);
return true;
}
bool CPC2PCView::DisRcv(BYTE bytType)//接收态显示信息函数,bytType决定显示信息的内容
{
CString strDis;
CEdit& myEdit=this->GetEditCtrl();
myEdit.SetReadOnly(true);
myEdit.SetSel(1000000,1000000);
switch(bytType)
{
case 1:
{
strDis="取消操作!\15\12";
break;
}
case 2:
{
strDis="收到无效的命令!\15\12";
break;
}
case 4:
{
strDis="对方无响应,超时错误!\15\12";
break;
}
case 8:
{
strDis="重试次数多于3次!\15\12";
break;
}
}
myEdit.ReplaceSel(strDis);
bytRcvStatus=0; //恢复接收0态
bytActStatus=10; //恢复为接收态
bytSendStatus=0; //发送态恢复为0态
bytResendCount=0; //重试次数初始化为0
if(myFile.m_pStream!=NULL)
{
myFile.Close(); //关闭打开的文件
}
return true;
}
BYTE CPC2PCView::Read(BYTE arrBin[],int count)//读数据函数,arrBin[]存放数据,count是读的个数
{ //成功返回0,读失败返回16,超时错误返回4
DWORD dwRes;
DWORD dwRead;
Rol.hEvent=CreateEvent(NULL, //创建Rol.hEvent为无信号状态
TRUE,
FALSE,
NULL);
if (ReadFile(hCom,
arrBin,
count, //读取count个字节
NULL,
&Rol))
{
//串口接收的数据已经成功读出,并存放在arrBin[]数组中
return 0;
}
else
{
dwRes = WaitForSingleObject(Rol.hEvent,
2000); //设置2秒的读超时
switch(dwRes)
{
case WAIT_OBJECT_0:
{
if (!GetOverlappedResult(hCom,
&Rol,
&dwRead, //实际读取字节数存放在dwRead中
TRUE))
{
//读操作失败。使用GetLastError()函数可以获取错误消息
return 16;
}
else
{
//串口接收的数据已经成功读出,并存放在arrBin[]数组中
return 0;
}
break;
}
case WAIT_TIMEOUT:
{
//读操作出现超时错误。
return 4;
}
}
}
return 0;
}
//发送数据函数,arrBin[]存放数据,count是发送个数
//发送态时,发送数据调用这个函数
//接收态时,响应时调用这个函数发送响应代码ACK、NAK或CAN
bool CPC2PCView::Write(BYTE arrBin[],int count)
{
DWORD dwWrite;
Wol.hEvent=CreateEvent(NULL, //创建Wol.hEvent事件句柄,并设置为无信号状态
TRUE,
FALSE,
NULL);
WriteFile(hCom, //写数据,通过Wol结构获取操作结果
arrBin,
count,
NULL,
&Wol);
if(GetOverlappedResult(hCom,&Wol,&dwWrite,true))
{
return true;
}
return false;
}
//检测串口输入缓冲区中是否有指定个数的数据
//返回0-有,4-超时错误,8-无效
BYTE CPC2PCView::Detect(int count)
{
DWORD dwErrors;
COMSTAT Rcs;
CString strDis,strDis1;
BYTE bytTimeCount;
ClearCommError(hCom, //串口句柄
&dwErrors, //存放出错信息的掩码组合
&Rcs); //COMSTAT类型结构变量
if(Rcs.cbInQue==0)
return 8;
bytTimeCount=0;
while(bytTimeCount<4)
{
ClearCommError(hCom, //串口句柄
&dwErrors, //存放出错信息的掩码组合
&Rcs); //COMSTAT类型结构变量
if(Rcs.cbInQue>=(UINT)count)
{
return 0;//在输入缓冲区中找到指定数量的字符
}
Sleep(500);
bytTimeCount++;
}
if((bytTimeCount>=4)&&(Rcs.cbInQue>0))//超时错误
{
return 4;//未找到
}
return 8;//无效状态,输入缓冲区中为0个字符
}
void CPC2PCView::OnDestroy()
{
CEditView::OnDestroy();
// TODO: Add your message handler code here
}
void CPC2PCView::OnUpdateAppExit(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if (!blnOpened) //根据串口是否打开,决定是否允许“退出”命令
{
pCmdUI->Enable(true);
}
else
{
pCmdUI->Enable(false);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -