使用Microsoft Communications Control, version 6.0 控件,在一个窗口的 OnInitDialog()中初始化控件并调用 if(!pMsComm->get_PortOpen() )//打开串口 语句,其中pMsComm为Microsoft Communications Control, version 6.0 控件关联变量。该语句在失败时会抛出一个异常,该异常在与被如下代码捕获,
RESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg, WPARAM wParam = 0, LPARAM lParam = 0) { _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData(); MSG oldState = pThreadState->m_lastSentMsg; // save for nesting pThreadState->m_lastSentMsg.hwnd = hWnd; pThreadState->m_lastSentMsg.message = nMsg; pThreadState->m_lastSentMsg.wParam = wParam; pThreadState->m_lastSentMsg.lParam = lParam; #ifdef _DEBUG _AfxTraceMsg(_T("WndProc"), &pThreadState->m_lastSentMsg); #endif // Catch exceptions thrown outside the scope of a callback // in debug builds and warn the user. LRESULT lResult; TRY { #ifndef _AFX_NO_OCC_SUPPORT // special case for WM_DESTROY if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL)) pWnd->m_pCtrlCont->OnUIActivate(NULL); #endif // special case for WM_INITDIALOG CRect rectOld; DWORD dwStyle = 0; if (nMsg == WM_INITDIALOG) _AfxPreInitDialog(pWnd, &rectOld, &dwStyle); // delegate to object's WindowProc lResult = pWnd->WindowProc(nMsg, wParam, lParam); // more special case for WM_INITDIALOG if (nMsg == WM_INITDIALOG) _AfxPostInitDialog(pWnd, rectOld, dwStyle); } CATCH_ALL(e) { lResult = AfxProcessWndProcException(e, &pThreadState->m_lastSentMsg); TRACE(traceAppMsg, 0, "Warning: Uncaught exception in WindowProc (returning %ld).\n", lResult); DELETE_EXCEPTION(e); } END_CATCH_ALL pThreadState->m_lastSentMsg = oldState; return lResult; }导 致OnInitDialog()在串口初始化之后的代码都没有执行。使得依赖这些代码的代码出现以未初始化为主要特征的异常。一个改进的方式是事先检测串口有没有效果。
因此在网上查找了一些资料,总结出在串口初始化之前可以使用如下代码:
HANDLE m_hCom; CString com; com.Format("\\\\.\\COM%d",(int)(pMsComm->get__CommPort())); m_hCom = CreateFile(com, 0, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); // 这里的CreateFile函数起了很大的作用,可以用来创建系统设备文件,如果该设备不存在或者被占用,则会返回一个错误,即下面的 INVALID_HANDLE_VALUE ,据此可以判断可使用性。详细参见MSDN中的介绍。 if(m_hCom == INVALID_HANDLE_VALUE) // 如果没有该设备,或者被其他应用程序在用 ******************* { int errornum=GetLastError(); if(errornum==2) com.Format("端口%d 不存在",(int)(pMsComm->get__CommPort())); else if(errornum==5) com.Format("端口%d被占用",(int)(pMsComm->get__CommPort())); AfxMessageBox(com); CloseHandle(m_hCom); // 关闭文件句柄,后面我们采用控件,不用API return ;//这是因为串口初始化封装在另一个函数里面在OnInitDialog调用。 } CloseHandle(m_hCom); // 关闭文件句柄,后面我们采用控件,不用API
使用该代码获取串口是否可用。如果必须要开启串口,可以单独写个 线程,在线程里面循环检测该代码。