www.pudn.com > voice.rar > robotDoc.cpp


// robotDoc.cpp : implementation of the CRobotDoc class 
// 
 
#include "stdafx.h" 
#include "robot.h" 
#include"SetupDlg.h" 
#include "robotDoc.h" 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CRobotDoc 
 
IMPLEMENT_DYNCREATE(CRobotDoc, CDocument) 
 
BEGIN_MESSAGE_MAP(CRobotDoc, CDocument) 
	//{{AFX_MSG_MAP(CRobotDoc) 
	ON_COMMAND(ID_SETUPCOMM, OnSetupcomm) 
	ON_COMMAND(ID_CLOSECOMM, OnClosecomm) 
	ON_COMMAND(ID_OPENCOMM, OnOpencomm) 
	ON_UPDATE_COMMAND_UI(ID_OPENCOMM, OnUpdateOpencomm) 
	ON_UPDATE_COMMAND_UI(ID_CLOSECOMM, OnUpdateClosecomm) 
	ON_COMMAND(ID_ANJIANCTRL, OnAnjianctrl) 
	ON_UPDATE_COMMAND_UI(ID_ANJIANCTRL, OnUpdateAnjianctrl) 
	ON_COMMAND(ID_VOICECTRL, OnVoicectrl) 
	ON_UPDATE_COMMAND_UI(ID_VOICECTRL, OnUpdateVoicectrl) 
	ON_COMMAND(ID_HELP, OnHelp) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CRobotDoc construction/destruction 
 
CRobotDoc::CRobotDoc() 
{ 
	// TODO: add one-time construction code here 
	m_bConnected=FALSE; 
	m_pThread=NULL; 
	m_nBaud =244; 
	m_nDataBits = 8; 
	m_nParity = 1; 
	m_sPort = "COM1"; 
	m_nStopBits = 0; 
	m_bctrlmodal=FALSE; 
	m_uCurrentBtn=ID_CLOSECOMM; 
} 
 
CRobotDoc::~CRobotDoc() 
{ 
	if(m_bConnected) 
	CloseConnection(); 
	// 删除事件句柄 
	if(m_hPostMsgEvent) 
	CloseHandle(m_hPostMsgEvent); 
	if(m_osRead.hEvent) 
	CloseHandle(m_osRead.hEvent); 
	if(m_osWrite.hEvent) 
	CloseHandle(m_osWrite.hEvent); 
} 
 
BOOL CRobotDoc::OnNewDocument() 
{ 
	if (!CDocument::OnNewDocument()) 
		return FALSE; 
 
	// TODO: add reinitialization code here 
	// (SDI documents will reuse this document) 
	// 为WM_COMMNOTIFY消息创建事件对象,手工重置,初始化为有信号的 
	if((m_hPostMsgEvent=CreateEvent(NULL, TRUE, TRUE, NULL))==NULL) 
		return FALSE; 
	memset(&m_osRead, 0, sizeof(OVERLAPPED)); 
	memset(&m_osWrite, 0, sizeof(OVERLAPPED)); 
	// 为重叠读创建事件对象,手工重置,初始化为无信号的 
	if((m_osRead.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL) 
		return FALSE; 
	// 为重叠写创建事件对象,手工重置,初始化为无信号的 
	if((m_osWrite.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL) 
		return FALSE; 
	return TRUE; 
} 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CRobotDoc serialization 
 
void CRobotDoc::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		// TODO: add storing code here 
	} 
	else 
	{ 
		// TODO: add loading code here 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CRobotDoc diagnostics 
 
#ifdef _DEBUG 
void CRobotDoc::AssertValid() const 
{ 
	CDocument::AssertValid(); 
} 
 
void CRobotDoc::Dump(CDumpContext& dc) const 
{ 
	CDocument::Dump(dc); 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CRobotDoc commands 
 
void CRobotDoc::OnSetupcomm()  
{ 
	// TODO: Add your command handler code here 
	CSetupDlg dlg; 
	CString str; 
	dlg.m_bConnected=m_bConnected; 
	dlg.m_sPort=m_sPort; 
	str.Format("%d",m_nBaud); 
	dlg.m_sBaud=str; 
	str.Format("%d",m_nDataBits); 
	dlg.m_sDataBits=str; 
	dlg.m_nParity=m_nParity; 
	dlg.m_nStopBits=m_nStopBits; 
	//dlg.m_nFlowCtrl=m_nFlowCtrl; 
	//dlg.m_bEcho=m_bEcho; 
//	dlg.m_bNewLine=m_bNewLine; 
	if(dlg.DoModal()==IDOK) 
	{ 
		m_sPort=dlg.m_sPort; 
		m_nBaud=atoi(dlg.m_sBaud); 
		m_nDataBits=atoi(dlg.m_sDataBits); 
		m_nParity=dlg.m_nParity; 
		m_nStopBits=dlg.m_nStopBits; 
	//	m_nFlowCtrl=dlg.m_nFlowCtrl; 
	//	m_bEcho=dlg.m_bEcho; 
	//	m_bNewLine=dlg.m_bNewLine; 
		if(m_bConnected) 
			if(!ConfigConnection()) 
				AfxMessageBox("Can't realize the settings!"); 
	} 
} 
 
void CRobotDoc::OnClosecomm()  
{ 
	// TODO: Add your command handler code here 
	m_uCurrentBtn=ID_CLOSECOMM; 
	CloseConnection(); 
} 
 
void CRobotDoc::OnOpencomm()  
{ 
	// TODO: Add your command handler code here 
	m_uCurrentBtn=ID_OPENCOMM; 
	if(!OpenConnection()) 
		AfxMessageBox("Can't open connection"); 
} 
 
void CRobotDoc::OnUpdateOpencomm(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	//pCmdUI->Enable(!m_bConnected); 
		pCmdUI->SetRadio(pCmdUI->m_nID == m_uCurrentBtn); 
} 
 
void CRobotDoc::OnUpdateClosecomm(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
//	pCmdUI->Enable(m_bConnected); 
	pCmdUI->SetRadio(pCmdUI->m_nID == m_uCurrentBtn); 
} 
 
void CRobotDoc::OnAnjianctrl()  
{ 
	// TODO: Add your command handler code here 
	 
} 
 
void CRobotDoc::OnUpdateAnjianctrl(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	 
} 
 
void CRobotDoc::OnVoicectrl()  
{ 
	// TODO: Add your command handler code here 
//	WinExec(NULL,NULL,_T("dutty.exe"),NULL,_T("D:\\Program Files\\Dutty\\Dutty.exe"),NULL); 
	WinExec(_T("D:\\Program Files\\Dutty\\Dutty.exe"),SW_SHOW); 
	m_bctrlmodal=TRUE; 
	//STARTUPINFO stinfo;   //启动窗口的信息  
      //PROCESSINFO procinfo;  //进程的信息     
	   //CreateProcess(NULL,_T("dutty.exe"),NULL,NULL.FALSE, NORMAL_PRIORITY_ CLASS,NULL,NULL, &stinfo,&procinfo);  
} 
 
void CRobotDoc::OnUpdateVoicectrl(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(!m_bctrlmodal); 
} 
UINT CommProc(LPVOID pParam) 
{ 
	OVERLAPPED os; 
	DWORD dwMask, dwTrans; 
	COMSTAT ComStat; 
	DWORD dwErrorFlags; 
	CRobotDoc *pDoc=(CRobotDoc*)pParam; 
	memset(&os, 0, sizeof(OVERLAPPED)); 
	os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL); 
	if(os.hEvent==NULL) 
	{ 
		AfxMessageBox("Can't create event object!"); 
		return (UINT)-1; 
	} 
	while(pDoc->m_bConnected) 
	{ 
		ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat); 
		if(ComStat.cbInQue)         //查询输入缓冲区中是否有字符 ,若有 
		{ 
			// 等待WM_COMMNOTIFY消息被处理完 
			WaitForSingleObject(pDoc->m_hPostMsgEvent, INFINITE); 
			ResetEvent(pDoc->m_hPostMsgEvent); 
			PostMessage(pDoc->m_hTermWnd, WM_COMMNOTIFY, EV_RXCHAR, 0); 
			// 通知视图 
			continue; 
		} 
		dwMask=0; 
		if(!WaitCommEvent(pDoc->m_hCom, &dwMask, &os)) // 重叠操作 
		{ 
			//通信事件 
			if(GetLastError()==ERROR_IO_PENDING) 
				// 无限等待重叠操作结果 
				GetOverlappedResult(pDoc->m_hCom, &os, &dwTrans, TRUE); 
			else 
			{ 
				CloseHandle(os.hEvent); 
				return (UINT)-1; 
			} 
		} 
	} 
	CloseHandle(os.hEvent); 
	return 0; 
} 
BOOL CRobotDoc::OpenConnection() 
{ 
	COMMTIMEOUTS TimeOuts; 
	POSITION firstViewPos; 
	CView *pView; 
	firstViewPos=GetFirstViewPosition(); 
	pView=GetNextView(firstViewPos); 
	m_hTermWnd=pView->GetSafeHwnd(); 
	if(m_bConnected) 
		return FALSE; 
	m_hCom=CreateFile(m_sPort, GENERIC_READ|GENERIC_WRITE,0,NULL, 
		OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,  
		NULL); // 重叠方式 
	if(m_hCom==INVALID_HANDLE_VALUE) 
		//AfxMessageBox("dfhksdjfhsjkfhks",MB_OK); 
		return FALSE; 
	SetupComm(m_hCom,1024,1024); 
	SetCommMask(m_hCom, EV_RXCHAR);///////////////////!!!!!!!!!!! 
	// 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作 
	TimeOuts.ReadIntervalTimeout=MAXDWORD;  
	TimeOuts.ReadTotalTimeoutMultiplier=0;  
	TimeOuts.ReadTotalTimeoutConstant=0;  
	/* 设置写超时以指定WriteComm成员函数中的 
	GetOverlappedResult函数的等待时间*/ 
	TimeOuts.WriteTotalTimeoutMultiplier=50;  
	TimeOuts.WriteTotalTimeoutConstant=2000; 
	SetCommTimeouts(m_hCom, &TimeOuts); 
	if(ConfigConnection()) 
	{ 
		m_pThread=AfxBeginThread(CommProc, this, THREAD_PRIORITY_NORMAL,  
			0, CREATE_SUSPENDED, NULL); // 创建并挂起线程 
		if(m_pThread==NULL) 
		{ 
			CloseHandle(m_hCom); 
			return FALSE; 
		} 
		else 
		{ 
			m_bConnected=TRUE; 
			m_pThread->ResumeThread(); // 恢复线程运行 
		} 
	} 
	else 
	{ 
		CloseHandle(m_hCom); 
		return FALSE; 
	} 
	return TRUE; 
} 
void CRobotDoc::CloseConnection() 
{ 
	if(!m_bConnected) return; 
	m_bConnected=FALSE; 
	//结束CommProc线程中WaitSingleObject函数的等待 
	SetEvent(m_hPostMsgEvent);  
	//结束CommProc线程中WaitCommEvent的等待 
	SetCommMask(m_hCom, 0);  
	//等待辅助线程终止 
	WaitForSingleObject(m_pThread->m_hThread, INFINITE); 
	m_pThread=NULL; 
	CloseHandle(m_hCom); 
} 
BOOL CRobotDoc::ConfigConnection()///设置DCB 
{ 
	DCB dcb; 
	if(!GetCommState(m_hCom, &dcb)) 
		return FALSE; 
	dcb.fBinary=TRUE; 
	dcb.BaudRate=m_nBaud; // 波特率 
	dcb.ByteSize=m_nDataBits; // 每字节位数 
	dcb.fParity=TRUE; 
	switch(m_nParity) // 校验设置 
	{ 
	case 0: dcb.Parity=NOPARITY; 
		break; 
	case 1: dcb.Parity=EVENPARITY; 
		break; 
	case 2: dcb.Parity=ODDPARITY; 
		break; 
	default:; 
	} 
	switch(m_nStopBits) // 停止位 
	{ 
	case 0: dcb.StopBits=ONESTOPBIT; 
		break; 
	case 1: dcb.StopBits=ONE5STOPBITS; 
		break; 
	case 2: dcb.StopBits=TWOSTOPBITS; 
		break; 
	default:; 
	} 
	// 硬件流控制设置 
//	dcb.fOutxCtsFlow=m_nFlowCtrl==1; 
//	dcb.fRtsControl=m_nFlowCtrl==1?RTS_CONTROL_HANDSHAKE:RTS_CONTROL_ENABLE; 
	// XON/XOFF流控制设置 
//	dcb.fInX=dcb.fOutX=m_nFlowCtrl==2; 
//	dcb.XonChar=XON; 
//	dcb.XoffChar=XOFF; 
//	dcb.XonLim=50; 
//	dcb.XoffLim=50; 
	return SetCommState(m_hCom, &dcb); 
} 
DWORD CRobotDoc::ReadComm(unsigned char *buf,DWORD dwLength) 
{ 
	DWORD length=0; 
	COMSTAT ComStat; 
	DWORD dwErrorFlags; 
	ClearCommError(m_hCom,&dwErrorFlags,&ComStat); // 清除错误标志 
	length=min(dwLength, ComStat.cbInQue); 
	ReadFile(m_hCom,buf,length,&length,&m_osRead);// 将指定数量的字符从串行口输出 
	return length; 
} 
// 将指定数量的字符从串行口输出 
DWORD CRobotDoc::WriteComm(unsigned char *buf,DWORD dwLength) 
{ 
	BOOL fState; 
	DWORD length=dwLength; 
	COMSTAT ComStat; 
	DWORD dwErrorFlags; 
	ClearCommError(m_hCom,&dwErrorFlags,&ComStat); // 清除错误标志 
	fState=WriteFile(m_hCom,buf,length,&length,&m_osWrite); 
	if(!fState){ 
		if(GetLastError()==ERROR_IO_PENDING) 
		{ 
			GetOverlappedResult(m_hCom,&m_osWrite,&length,TRUE);// 等待 
		} 
		else 
			length=0; 
	} 
	return length; 
} 
// 工作者线程,负责监视串行口 
 
void CRobotDoc::OnHelp()  
{ 
	// TODO: Add your command handler code here 
      //ShellExecute(NULL,NULL,_T("Jqrhelp.chm"),NULL,_T("e:\\机器人"),NULL); 
}