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

📄 scommtestdlg.cpp

📁 非常实用的串口通信程序 并且在中间使用了托盘技术 (站长,源程序个数怎么计算啊,其实这里面含有两个源程序,一个是串口通信,一个是托盘程序 )
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		                                                 
	{		
		m_RXDataAgain="1";		
	}

	//*********************************
	//以下所有的验证以长度正确为优先,体现出优先等级。
	//如此不会再出现Mid()的index>Lengthd事情了;
	//********************************
	if(m_StrRXData1.GetLength()==24) 
	{
		//2、验证是否有非“0”,“1”字符;
		for(int i=0;i<count;i++)
		{
			if (m_StrRXData1[i]!='0' && m_StrRXData1[i]!='1')
			{ 
				bitscount++;				
			}
		}
		CheckChar.Format("PLC--->PC的数据含有%d个不规范的字符(非0、1字符)\n请求重发",bitscount);
		
		if(bitscount>0)
		{    
		
		    //数据有误,建立请求重发的数据流,注:没有定位数据,只有三字节;
		    //同时置已经收到的字符无效;放到这里的末端处理;
            m_RXDataAgain="1";
		} 
		
		if(bitscount==0)//条件优先级:即检查乱码要优先于检查校验和		
		{
			//3、验证校验和
			int ncheck;
			CString checksum,checksum1;
			ncheck=
				atoi(Binary2Decimal(m_StrRXData1.Left(8)).GetBuffer(0))
				^atoi(Binary2Decimal(m_StrRXData1.Mid(8,8)).GetBuffer(0));
			    //首先转换成CString的int型--〉int
			if(atoi(Binary2Decimal(m_StrRXData1.Right(8)).GetBuffer(0))!=ncheck)
			{
		
				m_RXDataAgain="1";//请求重发,校验和不正确
		                          //其实检验的话,校验应该放最后,才算!
		                          //这样才合理!!!!
			}
		}
	}
			
	//4、设置一个flag值,表示新的数据已到,是否正确;
	if(m_RXDataAgain=="1")//表明收到的数据错误
	{
		m_StrRXData1="";//既然数据错误,那么就为空,重发一次;	    
	}	
}

//检查发送的发送的数据
void CSCommTestDlg::CheckSXData(ControlData *controldata)
{
	if(controldata->SXData.bNewData!=0&&controldata->SXData.bNewData!=1)
		AfxMessageBox("内存数据有误,PC-->PLC的bNewData非0、1值");
	if(controldata->SXData.bShutterOpen!=0
		&&controldata->SXData.bShutterOpen!=1)
		AfxMessageBox("内存数据有误,PC-->PLC的bShutterOpen非0、1值");
	if(controldata->SXData.nCTCount>16)
		AfxMessageBox("内存数据有误,CT点超出16点");
    //发生错误,只能让主程序改了。
}



void CSCommTestDlg::OnSelchangeComcombo() 
{
	// TODO: Add your control notification handler code here
	OnPortOk();

	
}

//对端口设置参数的组合框处理
void CSCommTestDlg::OnSelchangeBaudratecombo() 
{
	// TODO: Add your control notification handler code here
	OnPortOk();
}

void CSCommTestDlg::OnSelchangeDatabitscombo() 
{
	// TODO: Add your control notification handler code here
	OnPortOk();	
}

void CSCommTestDlg::OnSelchangeParitycombo() 
{
	// TODO: Add your control notification handler code here
	OnPortOk();
}



void CSCommTestDlg::OnSelchangeStopbitscombo() 
{
	// TODO: Add your control notification handler code here
	OnPortOk();	
}

//读内存映射文件,读出数据;
ControlData* CSCommTestDlg::ReadMemoryFile()
{
	ControlData* lpcontroldata;    
	//1、先打开一个内存映射文件,获得指针,读出数据
	HANDLE hmemoshare;
	hmemoshare=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,
		                          PAGE_READWRITE,0,sizeof(ControlData),"ControlDataFile");
	if(hmemoshare==NULL)
	{
		AfxMessageBox("创建内存映射文件失败");
	}
	lpcontroldata=(ControlData*)MapViewOfFile(hmemoshare,FILE_MAP_ALL_ACCESS,0,0,0);
	if(lpcontroldata==NULL)
	{
		AfxMessageBox("创建内存映射文件视图失败");
	}
    
	//读出数据:
    m_ControlData.SXData=lpcontroldata->SXData;
	
    return(lpcontroldata);

}

//可视化:手动选择发送的命令字节;
//当然,如要更高级,可以在有CT点时弹出新的对话框,输入CT数据,再发送;
void CSCommTestDlg::OnButtonSXDemandOk() 
{
	// TODO: Add your control notification handler code here

	CString ctpoint,shutteropen,sendagain;
	//初始化:
	ctpoint="0";//字节中的第6位
	shutteropen="0";//字节中的第7位
	sendagain="0";//字节中的第4位 

     if(m_ctrlCTPoint.GetCheck())
	 {
		//MessageBox("选择了有CT点");
		ctpoint="1";	
	 }
	else
	{
	//	MessageBox("没选CT点");
		ctpoint="0";
	}
	
	
	if(m_ctrlSendAgain.GetCheck())
	{
		sendagain="1";
	}
	else
		sendagain="0";

	if(m_ctrlShutterOpen.GetCheck())
		shutteropen="1";
	else
		shutteropen="0";

	//CSpinButtonCtrl* ppSpin=
	//	  (CSpinButtonCtrl*)GetDlgItem(IDC_SPIN1);
    m_nCTPoint=pSpin->GetPos();
    CString temps81;
	temps81.Format("%d",m_nCTPoint);
	temps81=ChangetoByteLength(Decimal2Binary(temps81),8);
	m_SXSelDemand=shutteropen+ctpoint+"0"+sendagain+temps81.Right(4);//刚好8位

    CString temps82,temps83,temps84,temps85,temps86,temps87;
	//制定数据,准备发送;
	if(m_nCTPoint==0)	
	{   //没有CT点,发3个字节;
        temps82.Format("%d",3^atoi(Binary2Decimal(m_SXSelDemand).GetBuffer(0))) ;
		temps83="00000011"+m_SXSelDemand+ChangetoByteLength(Decimal2Binary(temps82),8);
		m_CtrlComm.SetOutput(COleVariant(temps83));
	}
	if(m_nCTPoint>0)// && m_ctrlCTPoint.GetCheck())
	{
		
		//有CT点,发7个字节;
		//*****************************************************************************
		//CT定位数取自内存映射文件,当然我可以弹出一个对话框,让用户可视化输入,高明!!!
		//*****************************************************************************
		
		for(int i=0;i<m_nCTPoint;i++)
		{
			temps86.Format("%d",m_ControlData.SXData.nCTPos[i]);
			temps86=ChangetoByteLength(Decimal2Binary(temps86),32);//CT点数据
			int check=
			 atoi(Binary2Decimal("00000111").GetBuffer(0))
			^atoi(Binary2Decimal(m_SXSelDemand).GetBuffer(0))
			^atoi(Binary2Decimal(temps86.Left(8)).GetBuffer(0))
			^atoi(Binary2Decimal(temps86.Mid(8,8)).GetBuffer(0))
			^atoi(Binary2Decimal(temps86.Mid(16,8)).GetBuffer(0))
			^atoi(Binary2Decimal(temps86.Right(8)).GetBuffer(0));
			temps84.Format("%d",check);
		    temps84=Decimal2Binary(temps84);	
		    temps85=ChangetoByteLength(temps84,8);//校验和;
			temps87="00000111"+m_SXSelDemand+temps86+temps85;			                  
			m_CtrlComm.SetOutput(COleVariant(temps87));//放入缓冲区
		}		
		
	}
}

void CSCommTestDlg::DynShowRXData(CString str)
{
    CString strDynShowRXData,tempsz;
	CString temps71,temps72;
	CString temps73,temps74,temps75,temps76,temps77,temps78;
	int bitscount=0;
	//分别存储总的数据,长度,X射线开关,数据有误重发,皮带速度,校验和正确否,乱码,字节数
    temps71="";
	temps72="";
	temps73="";
	temps74="";
	temps75="";
	temps76="";
	temps77="";
	temps78="";
	temps71="来自PLC的数据显示 :\n";//开头保留;
	strDynShowRXData=m_ForDynShow;//从对话框中拿字符数据
    //注意:下面所有的一切,都是在得到24位的前提下运行;否则会Access Violation
	if(strDynShowRXData.GetLength()==24)
	{
		temps72.Format("数据总长度为:%d位\n",24);
		for(int i=0;i<24;i++)
		{
			if (strDynShowRXData[i]!='0' && strDynShowRXData[i]!='1')
			{ 
				bitscount++;				
			}
		}
	
		if(bitscount==0)//表示没有乱码
		{    
			temps77.Format("");
			if(Binary2Decimal(strDynShowRXData.Left(8))!="3")
				temps78.Format("字节数与命令长度表示不符合\n");
			//显示射线开关状态
			if(strDynShowRXData.Mid(8,8).Left(1)=="1")
				temps73.Format("打开X射线\n");   
			else 
				temps73.Format("关闭X射线\n");	
		
            //显示PLC请求DR重发
			if(strDynShowRXData.Mid(8,8).Mid(1,1)=="1")
				temps74.Format("PLC请求DR重发\n");
			else 
				temps74.Format("PLC没有请求DR重发\n");	
			
			//显示皮带速度
			CString strcount;
			strcount=Binary2Decimal(strDynShowRXData.Mid(8,8).Right(4));
			if(strcount>="0"&& strcount<="15")
				temps75.Format("皮带速度为: %.1f\n",m_ControlData.RXData.fSpeed);
			else 
				temps75.Format("皮带速度有误,\n接收到的数据被忽略;\n请求PLC重发\n");

			//显示校验和
			int ncheck;
			CString checksum,checksum1;
			ncheck=
				atoi(Binary2Decimal(strDynShowRXData.Left(8)).GetBuffer(0))
				^atoi(Binary2Decimal(strDynShowRXData.Mid(8,8)).GetBuffer(0));			    
			if(atoi(Binary2Decimal(strDynShowRXData.Right(8)).GetBuffer(0))==ncheck)
				temps76.Format("检验和正确\n");
			else	
				temps76.Format("检验和错误,\n接收到的数据被忽略;\n请求PLC重发\n");
		}
		else
			temps77.Format("数据有%d个乱码,\n接收到的数据被忽略;\n请求PLC重发\n",bitscount);
	}
	else 
		temps72.Format("数据长度非24位;\n接收到的数据被忽略;\n请求PLC重发\n");
	//显示总的状态
	tempsz.Format("%s\n%s%s%s\n%s\n%s\n%s\n%s\n",
		      temps71,temps72,temps77,temps78,temps73,temps74,temps75,temps76);
    
	m_cnRXDataShow.SetWindowText(tempsz);
	tempsz="";
	
}

void CSCommTestDlg::OnCheckSendagain() 
{
	// TODO: Add your control notification handler code here
  
    m_ctrlSendAgain.SetCheck(m_ctrlSendAgain.GetCheck());

}

//*************************************************************************
//以下是系统托盘程序
//*************************************************************************


void CSCommTestDlg::quitfuc()
{	
	//if(AfxMessageBox("这是DR<-->PLC的串口通信程序\n真的要退出吗?",MB_OKCANCEL)==IDOK)
	if(MessageBox("这是DR<-->PLC的串口通信程序\n真的要退出吗?",
		"Notice:",MB_YESNO|MB_ICONWARNING)==IDYES)
	{
		tnid.hIcon=hIcon[0];
		int i=::Shell_NotifyIcon(NIM_DELETE,&tnid);
		EndDialog(0);
	}
}

void CSCommTestDlg::hidefuc()
{
	ShowWindow(SW_HIDE);

}

void CSCommTestDlg::showfuc()
{
	ShowWindow(SW_SHOWNORMAL);

}

void CSCommTestDlg::MyFuc(DWORD lp, DWORD wp)
{
	CMenu  menu1; 
	CMenu *menu;
	CPoint point;
	switch(wp)
	{
		case WM_LBUTTONDBLCLK:
			ShowWindow(SW_SHOWNORMAL);			   
			
		break;
		case WM_RBUTTONDOWN:
			GetCursorPos(&point);
			menu1.LoadMenu(IDR_POPUP);
			menu=menu1.GetSubMenu(0);
			menu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,point.x,point.y,this);
		break;
		default:break;
	
	}

}


void CSCommTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
//	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
//	{
//		CAboutDlg dlgAbout;
//		dlgAbout.DoModal();
//	}
	
//	else
//	{
		CDialog::OnSysCommand(nID, lParam);
//	}


}


int CSCommTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	ShowWindow(SW_HIDE);
	return 0;
}

void CSCommTestDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	//quitfuc();
	if(MessageBox("这是DR<-->PLC的串口通信程序\n真的要关闭吗?",
		"Notice:",MB_YESNO|MB_ICONWARNING)==IDYES)
	{
		tnid.hIcon=hIcon[0];
		int i=::Shell_NotifyIcon(NIM_DELETE,&tnid);
		EndDialog(0);
	}

}
void CSCommTestDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	ShowWindow(SW_HIDE);
}

void CSCommTestDlg::OnOK() 
{
	// TODO: Add extra validation here
	OnClose();
}

⌨️ 快捷键说明

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