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

📄 mainfrm.cpp

📁 用多线程技术编写串行通信协议
💻 CPP
字号:
// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "comdebug.h"
#include "MainFrm.h"
#include "comdebugDoc.h"
#include "comdebugView.h"
#include "comreadthread.h"
#include "SendView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND(ID_BUTTONSEND, OnButtonsend)
	ON_COMMAND(ID_BUTTONSENDANDREC, OnButtonsendandrec)
	ON_COMMAND(ID_BUTTONCLOSE, OnButtonclose)
	ON_COMMAND(ID_MENUITEM_COM1, OnMenuitemCom1)
	ON_COMMAND(ID_MENUITEMPRO, OnMenuitempro)
	ON_COMMAND(ID_MENUITEM_COM2, OnMenuitemCom2)
	ON_COMMAND(ID_MENUITEM485, OnMenuitem485)
	ON_COMMAND(ID_MENUITEMMULTI, OnMenuitemmulti)
	ON_COMMAND(ID_MENUITEMRTS, OnMenuitemrts)
	ON_UPDATE_COMMAND_UI(ID_BUTTONCLOSE, OnUpdateButtonclose)
	ON_UPDATE_COMMAND_UI(ID_BUTTONSEND, OnUpdateButtonsend)
	ON_UPDATE_COMMAND_UI(ID_BUTTONSENDANDREC, OnUpdateButtonsendandrec)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here
	
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	// TODO: Delete these three lines if you don't want the toolbar to
	//  be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	return 0;
}

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
	CCreateContext* pContext)
{
  	if(!m_wndSplitter.CreateStatic(this,1,2))
		{
		    AfxMessageBox(_T("Failed to create split bar"));
		    return FALSE;
		}
		if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CSendView),CSize(250,0),pContext))
		{
			AfxMessageBox(_T("Failed to create view"));
			return FALSE;
		}
    	if(!m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CComdebugView),CSize(250,0),pContext))
		{
			AfxMessageBox(_T("Failed to create view"));
			return FALSE;
		}
        m_wndSplitter.SetActivePane(0,0,NULL);
		 return TRUE;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers


void CMainFrame::OnButtonsend() 
{
	CString  sendstr,str;
    int   sendnum=0,i;
	sendflag=1;
	m_wndSplitter.SetActivePane(0,0,NULL);
    CSendView *psendview=(CSendView *)GetActiveView();
	str=psendview->LockBuffer();
	if(str.IsEmpty())
	{
		MessageBox(_T("请输入发送的信息"));
		sendstr.Empty();
		goto end;
	}
	str.TrimLeft();
	str.TrimRight();

	UCHAR sendarry[1024];

	unsigned char highbyte,lowbyte;
	int findresult;
	findresult=str.Find(_T("@"));
	if(findresult<0)
	{
			MessageBox(_T("请选择发送行"));								
			sendstr.Empty();
			goto end;
	}
	else						
	str=str.Right(str.GetLength()-findresult-1);
	findresult=str.Find(_T("\x0d\x0a"));
	if(findresult>=0)						
		sendstr=str.Left(findresult);
	else
	    sendstr=str;
	sendstr.TrimLeft();
	sendstr.TrimRight();
	for( i=0;i<sendstr.GetLength();i++)
	{
         if(!iswspace(sendstr[i])&!isxdigit(sendstr[i]))
		 {
              MessageBox(_T("发送串中有无效的字符"));
		      sendstr.Empty();
			  goto end;
         }
        if(isxdigit(sendstr[i]))
		 {
              if(isdigit(sendstr[i]))
	             highbyte=sendstr[i]-0x30;
			  if(isalpha(sendstr[i]))
			     highbyte=(sendstr[i]&0x0f)+9;
			  if(i<(sendstr.GetLength()-1))
			  {	 
			     if(isxdigit(sendstr[i+1]))
				 {
			          if(isdigit(sendstr[i+1]))
					    lowbyte=sendstr[i+1]-0x30;
				      if(isalpha(sendstr[i+1]))
					    lowbyte=(sendstr[i+1]&0x0f)+9;
					   sendarry[sendnum]=highbyte*16+lowbyte;
					   i++;													
				 }
                 else
                   sendarry[sendnum]=highbyte;
			  }
			  else
			  sendarry[sendnum]=highbyte;	
			  sendnum++;
		}
	}
	if(!sendnum)
	{
		MessageBox(_T("发送串中无有效的字符"));
		sendstr.Empty();
	    goto end;
	}
   	m_wndStatusBar.SetPaneText(2,_T("通信状态:发送"),TRUE);							     
	::PurgeComm(hcomm,PURGE_TXCLEAR);
	if(!::SetCommState(hcomm,&comdcb))
	{
		CString str;
		str.Format("SetCommState() %d",::GetLastError());
		MessageBox(str);
	}
	DWORD nbyte;
	if(m_bIs485)
	{
		comdcb.fRtsControl=RTS_CONTROL_ENABLE;
		::SetCommState(hcomm,&comdcb);
		::Sleep(5);
	}
	if(multiflag==1)
	{
		DWORD	fparity=comdcb.fParity;
		BYTE parity=comdcb.Parity;
		comdcb.fParity=TRUE;
		comdcb.Parity=MARKPARITY;

		::SetCommState(hcomm,&comdcb);
		::WriteFile(hcomm,sendarry,1,&nbyte,NULL);
		comdcb.Parity=SPACEPARITY;
		::SetCommState(hcomm,&comdcb);
		::WriteFile(hcomm,sendarry+1,sendnum-1,&nbyte,NULL);
		comdcb.Parity=parity;
		comdcb.fParity=fparity;
	}
	else
		WriteFile(hcomm,sendarry,sendnum,&nbyte,NULL);
	    ::PurgeComm(hcomm,PURGE_TXCLEAR);//写完后要清除缓冲区
                                        //读完后也要清掉缓冲区
end:	m_wndStatusBar.SetPaneText(2,_T("通信状态:停止"),TRUE); 

	sendflag=0; 
	m_strSend=sendstr;
	return ;	
}

void CMainFrame::OnButtonsendandrec() 
{
	CString sendstr;
	::PurgeComm(hcomm,PURGE_RXCLEAR);
	m_strSend.Empty();
    OnButtonsend();
	if(m_strSend.IsEmpty())
		return;
	m_wndSplitter.SetActivePane(0,1,NULL);
	recevieflag=1;
	readendflag=1;
	m_wndStatusBar.SetPaneText(2,_T("通信状态:发送与接收"),TRUE);
	CComdebugView *pcomdebugview=(CComdebugView *)GetActiveView();
	CComdebugDoc *pcomdebugdoc=(CComdebugDoc *)pcomdebugview->GetDocument();
	pcomdebugview->instrsize.cy=0;
	if(!pcomdebugdoc->inputdata.IsEmpty())
	{
		pcomdebugdoc->inputdata+=_T("\r\n\r\n\r\n");
		pcomdebugdoc->linenum+=3;
	}
		pcomdebugdoc->inputdata+=_T("*Send order\r\n*HEX code-:");
		pcomdebugdoc->inputdata+=m_strSend;
		pcomdebugdoc->linenum++;
	paintcase=PAINT_COMMUICAT;
	pcomdebugview->Invalidate(TRUE);
	pcomdebugdoc->inputdata+=_T("\r\n");
	pcomdebugdoc->linenum++;
  	pcomdebugdoc->inputdata+=_T("*Receive Information\r\n");
	pcomdebugdoc->linenum++;
	::AfxBeginThread(comreadthread,this);	
}

void CMainFrame::OnButtonclose() 
{
	readendflag=0;	
}

void CMainFrame::OnMenuitemCom1() 
{
	HANDLE hcomm_temp=::CreateFile(_T("COM1"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
	DWORD err=::GetLastError() ;
	if(err==NULL)
		::CloseHandle(hcomm_temp);
	else
	{
		if(commflag==1)
		{
			free(lpcommprop);
			::CloseHandle(hcomm);
			commflag=0;
			cominfo.Empty();
			m_wndStatusBar.SetPaneText(3,cominfo,TRUE);
		}
		else
		    MessageBox(_T("不能打开串口1"));
		return;
	}
	if(commflag)
	{
		free(lpcommprop);
		::CloseHandle(hcomm);
	}
	commflag=1;
	Opencomx();
	scancominfo();
	m_wndStatusBar.SetPaneText(3,cominfo,TRUE);		
}
BOOL CMainFrame::Opencomx()
{
	CString commstr;
	if(commflag==1)
		commstr=_T("COM1");
	if(commflag==2)
		commstr=_T("COM2");
	hcomm=::CreateFile(commstr,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);	
	lpcommprop=(LPCOMMPROP)malloc(sizeof(COMMPROP));
	lpcommprop->wPacketLength=sizeof(COMMPROP);
	::GetCommProperties(hcomm,lpcommprop);
	WORD dwsize=lpcommprop->wPacketLength;
	free(lpcommprop);
	lpcommprop=(LPCOMMPROP)malloc(dwsize);
	lpcommprop->wPacketLength=dwsize;
	::GetCommProperties(hcomm,lpcommprop);
	
	if(!proflag)
	{
		if(!::GetCommState(hcomm,&comdcb))
		{
			CString str;
			str.Format("GetCommState() %d",::GetLastError());
			MessageBox(str);
		}
		comdcb.BaudRate=CBR_9600;
		comdcb.fParity=FALSE;
		comdcb.fOutxCtsFlow=FALSE;
		comdcb.fOutxDsrFlow=FALSE;
		comdcb.fDtrControl=DTR_CONTROL_DISABLE;
		comdcb.fRtsControl=RTS_CONTROL_DISABLE;

		comdcb.ByteSize=8;
		comdcb.StopBits=ONESTOPBIT ;
		proflag=~proflag;
	}
	if(!::SetCommState(hcomm,&comdcb))
	{
		CString str;
		str.Format("SetCommState() %d",::GetLastError());
		MessageBox(str);
	}

	return 1;
}

void CMainFrame::scancominfo()
{
	cominfo.Empty();
	cominfo.Format("%d,",comdcb.BaudRate); 
	switch(comdcb.ByteSize)
	{
		case 4:cominfo+=_T("4,");break;
		case 5:cominfo+=_T("5,");break;
		case 6:cominfo+=_T("6,");break;		
		case 7:cominfo+=_T("7,");break;
		case 8:cominfo+=_T("8,");break;
	}
	switch(comdcb.Parity)
	{
		case EVENPARITY:cominfo+=_T("e,");break;
		case MARKPARITY:cominfo+=_T("m,");break;
		case NOPARITY:  cominfo+=_T("n,");break;
		case ODDPARITY: cominfo+=_T("o,");break;
		case SPACEPARITY:cominfo+=_T("s,");break;
	}
	switch(comdcb.StopBits)
	{
		case ONESTOPBIT:cominfo+=_T("1");break;
		case ONE5STOPBITS:cominfo+=_T("1.5");break;
		case TWOSTOPBITS: cominfo+=_T("2");break;
	}
	switch(commflag)
	{
		case 0:break;
		case 1:cominfo+=_T(",com1");break;
		case 2:cominfo+=_T(",com2");break;
	
	}
	if(multiflag)
		cominfo+=_T(",多机通信");
}

void CMainFrame::OnMenuitempro() 
{
	COMMCONFIG cc;
	cc.dcb=comdcb;
	CString commstr;
	if(commflag==1)
		commstr=_T("COM1");
	if(commflag==2)
		commstr=_T("COM2");
	::CommConfigDialog(commstr,NULL,&cc);
	comdcb=cc.dcb;
	SetCommState(hcomm,&comdcb);
	scancominfo();
	m_wndStatusBar.SetPaneText(3,cominfo,TRUE);		
}

void CMainFrame::OnMenuitemCom2() 
{
	HANDLE hcomm_temp=::CreateFile(_T("COM2"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
	DWORD err=::GetLastError() ;
	if(err==NULL)
		::CloseHandle(hcomm_temp);
	else
	{
		if(commflag==2)
		{
			free(lpcommprop);
			::CloseHandle(hcomm);
			commflag=0;
			cominfo.Empty();
			m_wndStatusBar.SetPaneText(3,cominfo,TRUE);
		}	
		else 
		  MessageBox(_T("不能打开串口2"));
		return;
	}
	if(commflag)
	{
		free(lpcommprop);
		::CloseHandle(hcomm);
	}
	commflag=2;
	Opencomx();
	scancominfo();
	m_wndStatusBar.SetPaneText(3,cominfo,TRUE);	
}

void CMainFrame::OnMenuitem485() 
{
	m_bIs485=~m_bIs485;		
}

void CMainFrame::OnMenuitemmulti() 
{
	if(multiflag==0)
	{
		multiflag=1;
	}
	else 
	{
		multiflag=0;
	}
	scancominfo();
	m_wndStatusBar.SetPaneText(3,cominfo,TRUE);		
}

void CMainFrame::OnMenuitemrts() 
{
	m_bEnableRTS=~m_bEnableRTS;
	if(m_bEnableRTS)
	{
		comdcb.fRtsControl=RTS_CONTROL_ENABLE;
		::SetCommState(hcomm,&comdcb);
	}
	else
	{
		comdcb.fRtsControl=RTS_CONTROL_DISABLE;
		::SetCommState(hcomm,&comdcb);
	}			
}

void CMainFrame::OnUpdateButtonclose(CCmdUI* pCmdUI) 
{
     if(!commflag)
		pCmdUI->Enable(FALSE);
}

void CMainFrame::OnUpdateButtonsend(CCmdUI* pCmdUI) 
{
	 if(!commflag)
		pCmdUI->Enable(FALSE);
}

void CMainFrame::OnUpdateButtonsendandrec(CCmdUI* pCmdUI) 
{
 if(!commflag)
		pCmdUI->Enable(FALSE);	
}



⌨️ 快捷键说明

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