使用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;
#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
使用该代码获取串口是否可用。如果必须要开启串口,可以单独写个 线程,在线程里面循环检测该代码。