www.pudn.com > evc_Chuankou.rar > ChuankouDlg.cpp


// ChuankouDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "Chuankou.h" 
#include "ChuankouDlg.h" 
#include "SIPAPI.H" 
#include "Baue.h" 
#include "About.h" 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
#define TASKBAR_ICON	WM_USER+0x111 
///////////////////////////////////////////////////////////////////////////// 
// CChuankouDlg dialog 
 
CChuankouDlg::CChuankouDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CChuankouDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CChuankouDlg) 
	m_16 = FALSE; 
	m_strRecv = _T(""); 
	//}}AFX_DATA_INIT 
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 
 
void CChuankouDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CChuankouDlg) 
	DDX_Check(pDX, IDC_CHECK1, m_16); 
	DDX_Text(pDX, IDC_EDIT1, m_strRecv); 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CChuankouDlg, CDialog) 
	//{{AFX_MSG_MAP(CChuankouDlg) 
	ON_BN_CLICKED(IDC_BUTTON_EXIT, OnButtonExit) 
	ON_BN_CLICKED(IDC_BUTTON_RESET, OnButtonReset) 
	ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend) 
	ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnButtonClose) 
	ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen) 
	ON_BN_CLICKED(IDC_CHECK1, OnCheck1) 
	ON_EN_SETFOCUS(IDC_EDIT2, OnSetfocusEdit2) 
	ON_EN_KILLFOCUS(IDC_EDIT2, OnKillfocusEdit2) 
	ON_WM_TIMER() 
	ON_BN_CLICKED(IDC_BUTTON5, OnButton5) 
	ON_BN_CLICKED(IDC_BUTTON6, OnButton6) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CChuankouDlg message handlers 
 
BOOL CChuankouDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
 
	// Set the icon for this dialog.  The framework does this automatically 
	//  when the application's main window is not a dialog 
	SetIcon(m_hIcon, TRUE);			// Set big icon 
	SetIcon(m_hIcon, FALSE);		// Set small icon 
	 
	CenterWindow(GetDesktopWindow());	// center to the hpc screen 
	ShowWindow( SW_SHOWMAXIMIZED );//SW_MAXIMIZE);//全屏显示 
	m_Cortrol=false; 
	m_dis=false; 
	m_hComm = INVALID_HANDLE_VALUE; 
	OnButtonReset();  
/* 
	NOTIFYICONDATA nd ; 
	nd.cbSize = sizeof(NOTIFYICONDATA); 
	nd.hWnd	  = m_hWnd ; 
	nd.uID    = 1 ; 
	nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ; 
	nd.uCallbackMessage = TASKBAR_ICON ; 
	nd.hIcon  = AfxGetApp()->LoadIcon(IDI_ICON1); 
	lstrcpy(nd.szTip,_T("serial port")); 
 
	Shell_NotifyIcon(NIM_ADD,&nd); 
//	CAbout dlg; 
//	dlg.Create(IDD_DIALOG_ABOUT,NULL); 
//	dlg.GetWindowRect(&m_rect); 
//	CenterWindow(); 
//	SetTimer(1,500,NULL); 
*/	return TRUE;  // return TRUE  unless you set the focus to a control 
} 
 
 
 
void CChuankouDlg::OnButtonExit()  
{ 
	if(m_Cortrol) 
	{ 
	OnButtonClose(); 
	} 
	CDialog::OnOK(); 
	exit(1); 
} 
 
void CChuankouDlg::OnButtonReset()  
{	con=0; 
	m_len=0; 
	//((CEdit*)GetDlgItem(IDC_EDIT1))->SetWindowText(_T(""));	 
	//((CEdit*)GetDlgItem(IDC_EDIT2))->SetWindowText(_T("")); 
	((CEdit*)GetDlgItem(IDC_EDIT3))->SetWindowText(_T("0")); 
	((CEdit*)GetDlgItem(IDC_EDIT4))->SetWindowText(_T("0"));	 
} 
 
void CChuankouDlg::OnButtonSend()  
{ 
	if(!m_Cortrol) 
	{ 
		AfxMessageBox(_T("串口没有打开!")); 
		return; 
	} 
	BYTE *pData; 
	UpdateData(true); 
	((CEdit*)GetDlgItem(IDC_EDIT2))->GetWindowText(m_strSend); 
	if(m_strSend==_T("")) 
	{ 
	return; 
	} 
	if(m_16) 
	{ 
		CByteArray hexdata; 
		int len=String2Hex(m_strSend,hexdata);  
		bufLen=len; 
		pData=new BYTE[len]; 
		for(int k=0;kSetWindowText(LEN); 
	//ReadPort(); 
} 
/* 
void CChuankouDlg::ReadPort() 
{ 
	BYTE *pData; 
	pData=new BYTE[bufLen]; 
	if (!m_ceSeries.ReadPort(m_ceSeries.m_hComm,pData,bufLen)) 
	{ 
		AfxMessageBox(L"读串口失败\r\n\r请检查串口连接!"); 
		m_ceSeries.ClosePort(); 
		return; 
	} 
	CString str; 
	str.Format(_T("%s"),pData); 
	UpdateData(true); 
	if(m_16) 
	{ 
		CByteArray hexdata; 
		int len=String2Hex(str,hexdata);  
		//bufLen=len; 
		pData=new BYTE[len]; 
		for(int k=0;kSetWindowText(str);	 
	delete pData; 
	pData=NULL; 
	return; 
 
} 
*/ 
void CChuankouDlg::OnButtonClose()  
{ 
	ClosePort(); 
	((CButton*)GetDlgItem(IDC_BUTTON_CLOSE))->EnableWindow(false);	 
	((CButton*)GetDlgItem(IDC_BUTTON_OPEN))->EnableWindow(true); 
	m_Cortrol=false; 
} 
 
void CChuankouDlg::OnButtonOpen()  
{ 
	CBaue dlg; 
	if (dlg.DoModal() == IDOK) 
	{ 
		if (!OpenPort(this,1,dlg.m_baud,0,8,0)) 
		{ 
			MessageBox(L"Open Series port failed!",L"error",MB_ICONEXCLAMATION); 
			return; 
		} 
	} 
	((CButton*)GetDlgItem(IDC_BUTTON_OPEN))->EnableWindow(false); 
	((CButton*)GetDlgItem(IDC_BUTTON_CLOSE))->EnableWindow(true); 
	m_Cortrol=true; 
//	OpenThind(this); 
} 
 
int CChuankouDlg::String2Hex(CString str, CByteArray &senddata) 
{ 
	int hexdata,lowhexdata; 
	int hexdatalen=0; 
	int len=str.GetLength(); 
	senddata.SetSize(len/2); 
	for(int i=0;i=len) 
	break; 
	lstr=str[i]; 
//	AfxMessageBox(str[i]); 
	hexdata=ConvertHexChar(hstr); 
	lowhexdata=ConvertHexChar(lstr); 
	if((hexdata==16)||(lowhexdata==16)) 
	break; 
	else  
	hexdata=hexdata*16+lowhexdata; 
	i++; 
	senddata[hexdatalen]=(char)hexdata; 
	hexdatalen++; 
	} 
	senddata.SetSize(hexdatalen);  
	return hexdatalen; 
	 
} 
 
char CChuankouDlg::ConvertHexChar(TCHAR ch) 
{ 
	if((ch>='0')&&(ch<='9')) 
		return ch-0x30; 
	else if((ch>='A')&&(ch<='F')) 
		return ch-'A'+10; 
	else if((ch>='a')&&(ch<='f')) 
		return ch-'a'+10; 
	else return(-1); 
} 
 
void CChuankouDlg::OnSeriesRead(CWnd* pWnd,BYTE* buf,int bufLen) 
{ 
	CString str,str1,str2; 
	//BYTE *pData; 
	CChuankouDlg *pDlg = (CChuankouDlg *)pWnd; 
	CEdit * pEdit; 
	pEdit = (CEdit*)pDlg->GetDlgItem(IDC_EDIT1); 
	CEdit * pEdit2; 
	pEdit2 = (CEdit*)pDlg->GetDlgItem(IDC_EDIT4); 
	CString strRecv;// 
	pDlg->m_len+=bufLen; 
	if(pDlg->m_dis) 
	{ 
 
		for(int k=0;km_len); 
	CString strOld; 
	pEdit->GetWindowText(strOld); 
	pEdit->SetWindowText(strOld + strRecv); 
    pEdit2->SetWindowText(str2); 
	delete[] buf; 
	 
} 
BOOL CChuankouDlg::OpenPort(CWnd* pPortOwner, 
						 UINT portNo	,			/*串口号*/ 
						 UINT baud		,			/*波特率*/ 
						 UINT parity	,			/*奇偶校验*/ 
						 UINT databits	,			/*数据位*/ 
						 UINT stopbits			   /*停止位*/ 
						 ) 
{ 
	 
	DCB commParam; 
	TCHAR szPort[15];	 
	 
	// 已经打开的话,直接返回 
	if (m_hComm != INVALID_HANDLE_VALUE) 
	{ 
		return TRUE; 
	} 
	ASSERT(pPortOwner != NULL); 
	ASSERT(portNo > 0 && portNo < 5); 
	 
	//设置串口名 
	wsprintf(szPort, L"COM%d:", portNo); 
	//打开串口 
	m_hComm = CreateFile( 
		szPort, 
		GENERIC_READ | GENERIC_WRITE,	//允许读和写 
		0,								//独占方式(共享模式) 
		NULL, 
		OPEN_EXISTING,					//打开而不是创建(创建方式) 
		0, 
		NULL  
		); 
	 
	if (m_hComm == INVALID_HANDLE_VALUE) 
	{ 
		// 无效句柄,返回。		 
		TRACE(_T("CreateFile 返回无效句柄")); 
		return FALSE; 
		 
	} 
	 
	// 得到打开串口的当前属性参数,修改后再重新设置串口。 
	// 设置串口的超时特性为立即返回。 
	 
	if (!GetCommState(m_hComm,&commParam)) 
	{		 
		return FALSE; 
	} 
	 
	commParam.BaudRate = baud;					// 设置波特率  
	commParam.fBinary = TRUE;					// 设置二进制模式,此处必须设置TRUE 
	commParam.fParity = TRUE;					// 支持奇偶校验  
	commParam.ByteSize = databits;				// 数据位,范围:4-8  
	commParam.Parity = NOPARITY;				// 校验模式 
	commParam.StopBits = stopbits;				// 停止位  
	 
	commParam.fOutxCtsFlow = FALSE;				// No CTS output flow control  
	commParam.fOutxDsrFlow = FALSE;				// No DSR output flow control  
	commParam.fDtrControl = DTR_CONTROL_ENABLE;  
	// DTR flow control type  
	commParam.fDsrSensitivity = FALSE;			// DSR sensitivity  
	commParam.fTXContinueOnXoff = TRUE;			// XOFF continues Tx  
	commParam.fOutX = FALSE;					// No XON/XOFF out flow control  
	commParam.fInX = FALSE;						// No XON/XOFF in flow control  
	commParam.fErrorChar = FALSE;				// Disable error replacement  
	commParam.fNull = FALSE;					// Disable null stripping  
	commParam.fRtsControl = RTS_CONTROL_ENABLE;  
	// RTS flow control  
	commParam.fAbortOnError = FALSE;			// 当串口发生错误,并不终止串口读写 
	 
	if (!SetCommState(m_hComm, &commParam)) 
	{ 
		TRACE(_T("SetCommState error"));		 
		return FALSE; 
	} 
	 
	 
    //设置串口读写时间 
	COMMTIMEOUTS CommTimeOuts; 
	GetCommTimeouts (m_hComm, &CommTimeOuts); 
	CommTimeOuts.ReadIntervalTimeout = MAXDWORD;   
	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;   
	CommTimeOuts.ReadTotalTimeoutConstant = 0;     
	CommTimeOuts.WriteTotalTimeoutMultiplier = 10;   
	CommTimeOuts.WriteTotalTimeoutConstant = 1000;   
	 
	if(!SetCommTimeouts( m_hComm, &CommTimeOuts )) 
	{ 
		TRACE( _T("SetCommTimeouts 返回错误") ); 
		return FALSE; 
	} 
	 
	m_pPortOwner = pPortOwner;	 
	 
	//指定端口监测的事件集 
	SetCommMask (m_hComm, EV_RXCHAR); 
	 
	//分配设备缓冲区 
	SetupComm(m_hComm,1024,1024); 
	 
	//初始化缓冲区中的信息 
	PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR); 
	 
	m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 
//	m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 
	//创建读串口线程 
	m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID); 
	//创建写串口线程 
//	m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID); 
	 
	TRACE(_T("串口打开成功")); 
	 
	return TRUE; 
} 
//串口读线程函数 
DWORD CChuankouDlg::ReadThreadFunc(LPVOID lparam) 
{ 
	CChuankouDlg *ceSeries = (CChuankouDlg*)lparam; 
	 
	DWORD	evtMask; 
	BYTE * readBuf = NULL;//读取的字节 
	DWORD actualReadLen=0;//实际读取的字节数 
	DWORD willReadLen; 
	 
	DWORD dwReadErrors; 
	COMSTAT	cmState; 
	 
	// 清空缓冲,并检查串口是否打开。 
	ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);  
	 
//	AfxMessageBox(_T("1")); 
	//清空串口 
	PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR ); 
	 
	SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR ); 
	while (TRUE) 
	{   	 
		if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0)) 
		{			 
			SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR ); 
			//表示串口收到字符		 
			if (evtMask & EV_RXCHAR)  
			{ 
			//	AfxMessageBox(_T("3")); 
				ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState); 
				willReadLen = cmState.cbInQue ; 
				if (willReadLen <= 0) 
				{ 
					continue; 
				} 
				 
				readBuf = new BYTE[willReadLen]; 
				ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0); 
				 
				//如果读取的数据大于0, 
				if (actualReadLen>0) 
				{ 
				//	ceSeries->read(ceSeries->m_pPortOwner,readBuf,actualReadLen); 
				//	AfxMessageBox(_T("ol")); 
					//触发读取回调函数 
					ceSeries->OnSeriesRead(ceSeries->m_pPortOwner,readBuf,actualReadLen); 
				//	AfxMessageBox(_T("ol")); 
				} 
			} 
		} 
		//如果收到读线程退出信号,则退出线程 
		if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0) 
		{//	AfxMessageBox(_T("exit")); 
			break; 
		} 
	} 
	return 0; 
} 
//关闭读线程 
void CChuankouDlg::CloseReadThread() 
{ 
	SetEvent(m_hReadCloseEvent); 
	//设置所有事件无效无效 
	SetCommMask(m_hComm, 0); 
	//清空所有将要读的数据 
    PurgeComm( m_hComm,  PURGE_RXCLEAR ); 
    //等待10秒,如果读线程没有退出,则强制退出 
    if (WaitForSingleObject(m_hReadThread,10000) == WAIT_TIMEOUT) 
	{	 
		TerminateThread(m_hReadThread,0); 
	} 
	m_hReadThread = NULL; 
} 
void CChuankouDlg::ClosePort() 
{	 
	//表示串口还没有打开 
	if (m_hComm == INVALID_HANDLE_VALUE) 
	{ 
		return ; 
	} 
	//关闭读线程 
	CloseReadThread(); 
	//关闭串口 
	if (!CloseHandle (m_hComm)) 
	{ 
		m_hComm = INVALID_HANDLE_VALUE; 
		return ; 
	} 
	m_hComm = INVALID_HANDLE_VALUE; 
//	AfxMessageBox(_T("ClosePort")); 
} 
//私用方法,用于向串口写数据,被写线程调用 
BOOL CChuankouDlg::WritePort(HANDLE hComm,const BYTE *buf,DWORD bufLen) 
{ 
//	AfxMessageBox( _T("WritePort") ); 
	DWORD dwNumBytesWritten; 
	DWORD dwHaveNumWritten =0 ; //已经写入多少 
	 
	ASSERT(hComm != INVALID_HANDLE_VALUE); 
	do 
	{ 
	//	AfxMessageBox( _T("gogo") ); 
		if (WriteFile (hComm,					//串口句柄  
			buf+dwHaveNumWritten,				//被写数据缓冲区  
			bufLen- dwHaveNumWritten,          //被写数据缓冲区大小 
			&dwNumBytesWritten,					//函数执行成功后,返回实际向串口写的个数	 
			NULL))								//此处必须设置NULL 
		{ 
			dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten; 
			//写入完成 
			if (dwHaveNumWritten == bufLen) 
			{ 
			//	AfxMessageBox( _T("yes ok") ); 
				return TRUE; 
			} 
		//	Sleep(10); 
		} 
		else 
		{ 
			return FALSE; 
		} 
	}while (TRUE); 
	 
	return TRUE;	 
} 
 
void CChuankouDlg::OpenThind(CWnd* pPortOwner) 
{	m_pPortOwner = pPortOwner;	 
	m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 
	//创建读串口线程 
	m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID); 
 
} 
 
void CChuankouDlg::OnCheck1()  
{ 
	UpdateData(true); 
	if(m_16) 
	{ 
	m_dis=true; 
	} 
	else{ 
	m_dis=false; 
	} 
} 
 
void CChuankouDlg::OnSetfocusEdit2()  
{ 
	SipShowIM(SIPF_ON); 
	 
} 
 
void CChuankouDlg::OnKillfocusEdit2()  
{ 
	SipShowIM(SIPF_OFF); 
	 
} 
 
void CChuankouDlg::OnTimer(UINT nIDEvent)  
{ 
	//ShowWindow(false); 
	KillTimer(1); 
	 
	CDialog::OnTimer(nIDEvent); 
} 
 
void CChuankouDlg::OnButton5()  
{ 
	((CEdit*)GetDlgItem(IDC_EDIT1))->SetWindowText(_T(""));	 
	 
} 
 
void CChuankouDlg::OnButton6()  
{ 
	((CEdit*)GetDlgItem(IDC_EDIT2))->SetWindowText(_T("")); 
	 
}