robotDoc.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. // robotDoc.cpp : implementation of the CRobotDoc class
  2. //
  3. #include "stdafx.h"
  4. #include "robot.h"
  5. #include"SetupDlg.h"
  6. #include "robotDoc.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CRobotDoc
  14. IMPLEMENT_DYNCREATE(CRobotDoc, CDocument)
  15. BEGIN_MESSAGE_MAP(CRobotDoc, CDocument)
  16. //{{AFX_MSG_MAP(CRobotDoc)
  17. ON_COMMAND(ID_SETUPCOMM, OnSetupcomm)
  18. ON_COMMAND(ID_CLOSECOMM, OnClosecomm)
  19. ON_COMMAND(ID_OPENCOMM, OnOpencomm)
  20. ON_UPDATE_COMMAND_UI(ID_OPENCOMM, OnUpdateOpencomm)
  21. ON_UPDATE_COMMAND_UI(ID_CLOSECOMM, OnUpdateClosecomm)
  22. ON_COMMAND(ID_ANJIANCTRL, OnAnjianctrl)
  23. ON_UPDATE_COMMAND_UI(ID_ANJIANCTRL, OnUpdateAnjianctrl)
  24. ON_COMMAND(ID_VOICECTRL, OnVoicectrl)
  25. ON_UPDATE_COMMAND_UI(ID_VOICECTRL, OnUpdateVoicectrl)
  26. ON_COMMAND(ID_HELP, OnHelp)
  27. //}}AFX_MSG_MAP
  28. END_MESSAGE_MAP()
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CRobotDoc construction/destruction
  31. CRobotDoc::CRobotDoc()
  32. {
  33. // TODO: add one-time construction code here
  34. m_bConnected=FALSE;
  35. m_pThread=NULL;
  36. m_nBaud =244;
  37. m_nDataBits = 8;
  38. m_nParity = 1;
  39. m_sPort = "COM1";
  40. m_nStopBits = 0;
  41. m_bctrlmodal=FALSE;
  42. m_uCurrentBtn=ID_CLOSECOMM;
  43. }
  44. CRobotDoc::~CRobotDoc()
  45. {
  46. if(m_bConnected)
  47. CloseConnection();
  48. // 删除事件句柄
  49. if(m_hPostMsgEvent)
  50. CloseHandle(m_hPostMsgEvent);
  51. if(m_osRead.hEvent)
  52. CloseHandle(m_osRead.hEvent);
  53. if(m_osWrite.hEvent)
  54. CloseHandle(m_osWrite.hEvent);
  55. }
  56. BOOL CRobotDoc::OnNewDocument()
  57. {
  58. if (!CDocument::OnNewDocument())
  59. return FALSE;
  60. // TODO: add reinitialization code here
  61. // (SDI documents will reuse this document)
  62. // 为WM_COMMNOTIFY消息创建事件对象,手工重置,初始化为有信号的
  63. if((m_hPostMsgEvent=CreateEvent(NULL, TRUE, TRUE, NULL))==NULL)
  64. return FALSE;
  65. memset(&m_osRead, 0, sizeof(OVERLAPPED));
  66. memset(&m_osWrite, 0, sizeof(OVERLAPPED));
  67. // 为重叠读创建事件对象,手工重置,初始化为无信号的
  68. if((m_osRead.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL)
  69. return FALSE;
  70. // 为重叠写创建事件对象,手工重置,初始化为无信号的
  71. if((m_osWrite.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL)
  72. return FALSE;
  73. return TRUE;
  74. }
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CRobotDoc serialization
  77. void CRobotDoc::Serialize(CArchive& ar)
  78. {
  79. if (ar.IsStoring())
  80. {
  81. // TODO: add storing code here
  82. }
  83. else
  84. {
  85. // TODO: add loading code here
  86. }
  87. }
  88. /////////////////////////////////////////////////////////////////////////////
  89. // CRobotDoc diagnostics
  90. #ifdef _DEBUG
  91. void CRobotDoc::AssertValid() const
  92. {
  93. CDocument::AssertValid();
  94. }
  95. void CRobotDoc::Dump(CDumpContext& dc) const
  96. {
  97. CDocument::Dump(dc);
  98. }
  99. #endif //_DEBUG
  100. /////////////////////////////////////////////////////////////////////////////
  101. // CRobotDoc commands
  102. void CRobotDoc::OnSetupcomm() 
  103. {
  104. // TODO: Add your command handler code here
  105. CSetupDlg dlg;
  106. CString str;
  107. dlg.m_bConnected=m_bConnected;
  108. dlg.m_sPort=m_sPort;
  109. str.Format("%d",m_nBaud);
  110. dlg.m_sBaud=str;
  111. str.Format("%d",m_nDataBits);
  112. dlg.m_sDataBits=str;
  113. dlg.m_nParity=m_nParity;
  114. dlg.m_nStopBits=m_nStopBits;
  115. //dlg.m_nFlowCtrl=m_nFlowCtrl;
  116. //dlg.m_bEcho=m_bEcho;
  117. // dlg.m_bNewLine=m_bNewLine;
  118. if(dlg.DoModal()==IDOK)
  119. {
  120. m_sPort=dlg.m_sPort;
  121. m_nBaud=atoi(dlg.m_sBaud);
  122. m_nDataBits=atoi(dlg.m_sDataBits);
  123. m_nParity=dlg.m_nParity;
  124. m_nStopBits=dlg.m_nStopBits;
  125. // m_nFlowCtrl=dlg.m_nFlowCtrl;
  126. // m_bEcho=dlg.m_bEcho;
  127. // m_bNewLine=dlg.m_bNewLine;
  128. if(m_bConnected)
  129. if(!ConfigConnection())
  130. AfxMessageBox("Can't realize the settings!");
  131. }
  132. }
  133. void CRobotDoc::OnClosecomm() 
  134. {
  135. // TODO: Add your command handler code here
  136. m_uCurrentBtn=ID_CLOSECOMM;
  137. CloseConnection();
  138. }
  139. void CRobotDoc::OnOpencomm() 
  140. {
  141. // TODO: Add your command handler code here
  142. m_uCurrentBtn=ID_OPENCOMM;
  143. if(!OpenConnection())
  144. AfxMessageBox("Can't open connection");
  145. }
  146. void CRobotDoc::OnUpdateOpencomm(CCmdUI* pCmdUI) 
  147. {
  148. // TODO: Add your command update UI handler code here
  149. //pCmdUI->Enable(!m_bConnected);
  150. pCmdUI->SetRadio(pCmdUI->m_nID == m_uCurrentBtn);
  151. }
  152. void CRobotDoc::OnUpdateClosecomm(CCmdUI* pCmdUI) 
  153. {
  154. // TODO: Add your command update UI handler code here
  155. // pCmdUI->Enable(m_bConnected);
  156. pCmdUI->SetRadio(pCmdUI->m_nID == m_uCurrentBtn);
  157. }
  158. void CRobotDoc::OnAnjianctrl() 
  159. {
  160. // TODO: Add your command handler code here
  161. }
  162. void CRobotDoc::OnUpdateAnjianctrl(CCmdUI* pCmdUI) 
  163. {
  164. // TODO: Add your command update UI handler code here
  165. }
  166. void CRobotDoc::OnVoicectrl() 
  167. {
  168. // TODO: Add your command handler code here
  169. // WinExec(NULL,NULL,_T("dutty.exe"),NULL,_T("D:\Program Files\Dutty\Dutty.exe"),NULL);
  170. WinExec(_T("D:\Program Files\Dutty\Dutty.exe"),SW_SHOW);
  171. m_bctrlmodal=TRUE;
  172. //STARTUPINFO stinfo;   //启动窗口的信息 
  173.       //PROCESSINFO procinfo;  //进程的信息    
  174.    //CreateProcess(NULL,_T("dutty.exe"),NULL,NULL.FALSE, NORMAL_PRIORITY_ CLASS,NULL,NULL, &stinfo,&procinfo); 
  175. }
  176. void CRobotDoc::OnUpdateVoicectrl(CCmdUI* pCmdUI) 
  177. {
  178. // TODO: Add your command update UI handler code here
  179. pCmdUI->Enable(!m_bctrlmodal);
  180. }
  181. UINT CommProc(LPVOID pParam)
  182. {
  183. OVERLAPPED os;
  184. DWORD dwMask, dwTrans;
  185. COMSTAT ComStat;
  186. DWORD dwErrorFlags;
  187. CRobotDoc *pDoc=(CRobotDoc*)pParam;
  188. memset(&os, 0, sizeof(OVERLAPPED));
  189. os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
  190. if(os.hEvent==NULL)
  191. {
  192. AfxMessageBox("Can't create event object!");
  193. return (UINT)-1;
  194. }
  195. while(pDoc->m_bConnected)
  196. {
  197. ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat);
  198. if(ComStat.cbInQue)         //查询输入缓冲区中是否有字符 ,若有
  199. {
  200. // 等待WM_COMMNOTIFY消息被处理完
  201. WaitForSingleObject(pDoc->m_hPostMsgEvent, INFINITE);
  202. ResetEvent(pDoc->m_hPostMsgEvent);
  203. PostMessage(pDoc->m_hTermWnd, WM_COMMNOTIFY, EV_RXCHAR, 0);
  204. // 通知视图
  205. continue;
  206. }
  207. dwMask=0;
  208. if(!WaitCommEvent(pDoc->m_hCom, &dwMask, &os)) // 重叠操作
  209. {
  210. //通信事件
  211. if(GetLastError()==ERROR_IO_PENDING)
  212. // 无限等待重叠操作结果
  213. GetOverlappedResult(pDoc->m_hCom, &os, &dwTrans, TRUE);
  214. else
  215. {
  216. CloseHandle(os.hEvent);
  217. return (UINT)-1;
  218. }
  219. }
  220. }
  221. CloseHandle(os.hEvent);
  222. return 0;
  223. }
  224. BOOL CRobotDoc::OpenConnection()
  225. {
  226. COMMTIMEOUTS TimeOuts;
  227. POSITION firstViewPos;
  228. CView *pView;
  229. firstViewPos=GetFirstViewPosition();
  230. pView=GetNextView(firstViewPos);
  231. m_hTermWnd=pView->GetSafeHwnd();
  232. if(m_bConnected)
  233. return FALSE;
  234. m_hCom=CreateFile(m_sPort, GENERIC_READ|GENERIC_WRITE,0,NULL,
  235. OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 
  236. NULL); // 重叠方式
  237. if(m_hCom==INVALID_HANDLE_VALUE)
  238. //AfxMessageBox("dfhksdjfhsjkfhks",MB_OK);
  239. return FALSE;
  240. SetupComm(m_hCom,1024,1024);
  241. SetCommMask(m_hCom, EV_RXCHAR);///////////////////!!!!!!!!!!!
  242. // 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作
  243. TimeOuts.ReadIntervalTimeout=MAXDWORD; 
  244. TimeOuts.ReadTotalTimeoutMultiplier=0; 
  245. TimeOuts.ReadTotalTimeoutConstant=0; 
  246. /* 设置写超时以指定WriteComm成员函数中的
  247. GetOverlappedResult函数的等待时间*/
  248. TimeOuts.WriteTotalTimeoutMultiplier=50; 
  249. TimeOuts.WriteTotalTimeoutConstant=2000;
  250. SetCommTimeouts(m_hCom, &TimeOuts);
  251. if(ConfigConnection())
  252. {
  253. m_pThread=AfxBeginThread(CommProc, this, THREAD_PRIORITY_NORMAL, 
  254. 0, CREATE_SUSPENDED, NULL); // 创建并挂起线程
  255. if(m_pThread==NULL)
  256. {
  257. CloseHandle(m_hCom);
  258. return FALSE;
  259. }
  260. else
  261. {
  262. m_bConnected=TRUE;
  263. m_pThread->ResumeThread(); // 恢复线程运行
  264. }
  265. }
  266. else
  267. {
  268. CloseHandle(m_hCom);
  269. return FALSE;
  270. }
  271. return TRUE;
  272. }
  273. void CRobotDoc::CloseConnection()
  274. {
  275. if(!m_bConnected) return;
  276. m_bConnected=FALSE;
  277. //结束CommProc线程中WaitSingleObject函数的等待
  278. SetEvent(m_hPostMsgEvent); 
  279. //结束CommProc线程中WaitCommEvent的等待
  280. SetCommMask(m_hCom, 0); 
  281. //等待辅助线程终止
  282. WaitForSingleObject(m_pThread->m_hThread, INFINITE);
  283. m_pThread=NULL;
  284. CloseHandle(m_hCom);
  285. }
  286. BOOL CRobotDoc::ConfigConnection()///设置DCB
  287. {
  288. DCB dcb;
  289. if(!GetCommState(m_hCom, &dcb))
  290. return FALSE;
  291. dcb.fBinary=TRUE;
  292. dcb.BaudRate=m_nBaud; // 波特率
  293. dcb.ByteSize=m_nDataBits; // 每字节位数
  294. dcb.fParity=TRUE;
  295. switch(m_nParity) // 校验设置
  296. {
  297. case 0: dcb.Parity=NOPARITY;
  298. break;
  299. case 1: dcb.Parity=EVENPARITY;
  300. break;
  301. case 2: dcb.Parity=ODDPARITY;
  302. break;
  303. default:;
  304. }
  305. switch(m_nStopBits) // 停止位
  306. {
  307. case 0: dcb.StopBits=ONESTOPBIT;
  308. break;
  309. case 1: dcb.StopBits=ONE5STOPBITS;
  310. break;
  311. case 2: dcb.StopBits=TWOSTOPBITS;
  312. break;
  313. default:;
  314. }
  315. // 硬件流控制设置
  316. // dcb.fOutxCtsFlow=m_nFlowCtrl==1;
  317. // dcb.fRtsControl=m_nFlowCtrl==1?RTS_CONTROL_HANDSHAKE:RTS_CONTROL_ENABLE;
  318. // XON/XOFF流控制设置
  319. // dcb.fInX=dcb.fOutX=m_nFlowCtrl==2;
  320. // dcb.XonChar=XON;
  321. // dcb.XoffChar=XOFF;
  322. // dcb.XonLim=50;
  323. // dcb.XoffLim=50;
  324. return SetCommState(m_hCom, &dcb);
  325. }
  326. DWORD CRobotDoc::ReadComm(unsigned char *buf,DWORD dwLength)
  327. {
  328. DWORD length=0;
  329. COMSTAT ComStat;
  330. DWORD dwErrorFlags;
  331. ClearCommError(m_hCom,&dwErrorFlags,&ComStat); // 清除错误标志
  332. length=min(dwLength, ComStat.cbInQue);
  333. ReadFile(m_hCom,buf,length,&length,&m_osRead);// 将指定数量的字符从串行口输出
  334. return length;
  335. }
  336. // 将指定数量的字符从串行口输出
  337. DWORD CRobotDoc::WriteComm(unsigned char *buf,DWORD dwLength)
  338. {
  339. BOOL fState;
  340. DWORD length=dwLength;
  341. COMSTAT ComStat;
  342. DWORD dwErrorFlags;
  343. ClearCommError(m_hCom,&dwErrorFlags,&ComStat); // 清除错误标志
  344. fState=WriteFile(m_hCom,buf,length,&length,&m_osWrite);
  345. if(!fState){
  346. if(GetLastError()==ERROR_IO_PENDING)
  347. {
  348. GetOverlappedResult(m_hCom,&m_osWrite,&length,TRUE);// 等待
  349. }
  350. else
  351. length=0;
  352. }
  353. return length;
  354. }
  355. // 工作者线程,负责监视串行口
  356. void CRobotDoc::OnHelp() 
  357. {
  358. // TODO: Add your command handler code here
  359.       //ShellExecute(NULL,NULL,_T("Jqrhelp.chm"),NULL,_T("e:\机器人"),NULL);
  360. }