?? mywin32port.cpp
字號:
/************************************************************************/
// 函數名稱: OpenMyWin32Port(HWND hWnd,CString szPort,long dwBaudRate, char btParity ,char btSize,
// char btStopBits,long ReadIntervalTimeout,long ReadTotalTimeoutMultiplier,
// long ReadTotalTimeoutConstant,long WriteTotalTimeoutMultiplier,
// long WriteTotalTimeoutConstant,long dwCommMask )
// 函數描述: 根據指定的參數打開串口并開啟串口讀、寫及解析線程
// 入口參數:
// HWND hWnd 傳入的窗口句柄
// CString szPort 待打開串口ID號 1--COM1:、2--COM2:...
// long dwBaudRate 待打開串口數據傳輸率 4800、9600、19200...
// char btParity 待打開串口奇偶校驗 默認為無校驗。
// char btSize 待打開串口數據位 默認為8
// char btStopBits 待打開串口停止位 默認為1
// long ReadIntervalTimeout
// long ReadTotalTimeoutMultiplier
// long ReadTotalTimeoutConstant
// long WriteTotalTimeoutMultiplier
// long WriteTotalTimeoutConstant 串口通訊占用端口超時結構參數
// long dwCommMask 待打開串口響應事件
// 出口參數:
// 返 回 值: 串口打開成功或已打開,返回TRUE;否則返回FALSE
// 其 它:
/************************************************************************/
BOOL MyWin32Port::OpenMyWin32Port(HWND hWnd,CString szPort,long dwBaudRate, char btParity /* = NOPARITY */,char btSize /* = 8 */,
char btStopBits /* = ONESTOPBIT */,long ReadIntervalTimeout, long ReadTotalTimeoutMultiplier,
long ReadTotalTimeoutConstant,long WriteTotalTimeoutMultiplier,
long WriteTotalTimeoutConstant,long dwCommMask /* = EV_RXCHAR|EV_TXEMPTY */)
{
DCB dcb ;
long dwError = 0 ;
COMMTIMEOUTS CommTimeOuts ;
// 判斷待打開的串口是否已經被占用
if( FALSE != m_bIsOpen )
{
AfxMessageBox("串口已打開或未找到!") ;
return FALSE ;
}
// 確定待打開的串口名稱完整性(COM1:)
if( _T( ":" ) != szPort.Right(1) )
{
szPort += _T( ":" ) ;
}
// 設置串口通訊占用端口的句柄為占用模式
m_hCom = INVALID_HANDLE_VALUE ;
// 根據輸入的串口通訊參數打開串口
m_hCom = CreateFile( szPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ) ;
// 如果打開串口失敗返回0
if( INVALID_HANDLE_VALUE == m_hCom )
{
return FALSE ;
}
// 設置串口通訊占用端口超時結構參數
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 0 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
CommTimeOuts.WriteTotalTimeoutConstant = 5000 ;
// 設置串口通訊占用端口超時結構
SetCommTimeouts(m_hCom,&CommTimeOuts) ;
// 設置串口通訊占用端口DCB結構
dcb.DCBlength = sizeof( DCB ) ;
GetCommState( m_hCom, &dcb ) ;
dcb.BaudRate = dwBaudRate ;
dcb.ByteSize = btSize ;
if (1==btStopBits)
{
dcb.StopBits = ONESTOPBIT;
}
else if (2== btStopBits)
{
dcb.StopBits = TWOSTOPBITS;
}
else if (5 == btStopBits)
{
dcb.StopBits = ONE5STOPBITS;
}
else
{
dcb.StopBits = ONESTOPBIT;
}
switch(btParity)
{
case 'N': //無奇偶校驗位
dcb.Parity = NOPARITY;
break;
case 'O':
dcb.Parity = ODDPARITY;
break;
case 'E':
dcb.Parity = EVENPARITY;
break;
case 'M':
dcb.Parity = MARKPARITY;
break;
case 'S':
dcb.Parity = SPACEPARITY;
break;
default:
dcb.Parity = NOPARITY ;
break;
}
// 如果設置串口通訊占用端口選項參數失敗直接返回0
if( 0 == SetCommState(m_hCom,&dcb) || 0 == SetupComm(m_hCom,10000,10000) || 0 == SetCommMask(m_hCom,dwCommMask) )
{
// 獲取錯誤標示
dwError = GetLastError() ;
// 關閉串口通訊并釋放其占用端口
m_hWnd = NULL;
CloseMyWin32Port() ;
return 0 ;
}
// 清空串口通訊占用端口的緩沖區
PurgeComm(m_hCom,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT) ;
//啟動接收線程
if (!StartReceiveThread())
{
CloseMyWin32Port() ;//關閉串口
return FALSE;
}
//啟動解析線程
if (!StartInfoProcessThread())
{
CloseMyWin32Port() ;//關閉串口
return FALSE;
}
// 設置串口通訊是否占用端口的標識
m_hWnd = hWnd ;
m_bIsOpen = TRUE ;
return TRUE;
}
/************************************************************************/
// 函數名稱: CloseMyWin32Port()
// 函數描述: 關閉串口
// 入口參數:
// 出口參數:
// 返 回 值:
// 其 它:
/************************************************************************/
void MyWin32Port::CloseMyWin32Port()
{
// 如果當前串口通訊未占用任何端口則直接返回
if (INVALID_HANDLE_VALUE == m_hCom )
{
return ;
}
//終止接收線程
EndReceiveThread();
//終止解析線程
EndInfoProcessThread();
//清空接收隊列
EnterCriticalSection( &g_cslistReceiveInfoMutex );
if (g_listReceiveInfo.GetCount()>0)
{
g_listReceiveInfo.RemoveAll();
}
LeaveCriticalSection( &g_cslistReceiveInfoMutex );
// 關閉串口通訊占用端口的句柄
if (!CloseHandle(m_hCom))
{
// 設置串口通訊占用端口的句柄
m_hCom = INVALID_HANDLE_VALUE ;
}
// 初始化串口通訊是否占用端口的標識
m_bIsOpen = FALSE ;
return;
}
/************************************************************************/
// 函數名稱: StartReceiveThread()
// 函數描述: 啟動接收線程
// 入口參數:
// 出口參數:
// 返 回 值: 啟動成功返回TRUE;否則返回FALSE
// 其 它:
/************************************************************************/
BOOL MyWin32Port::StartReceiveThread()
{
//啟動工作線程
m_hReceiveThread = AfxBeginThread(ReceiveThread,this);
if( m_hReceiveThread == NULL )
{
TRACE( _T("啟動接收線程失敗,錯誤號:%d"), GetLastError() );
return FALSE;
}
return TRUE;
}
/************************************************************************/
// 函數名稱: EndReceiveThread()
// 函數描述: 終止接收線程
// 入口參數:
// 出口參數:
// 返 回 值: 成功返回TRUE;否則返回FALSE
// 其 它:
/************************************************************************/
BOOL MyWin32Port::EndReceiveThread()
{
if (NULL==m_hReceiveThread)
{
return FALSE;
}
//設置接收線程終止事件
SetEvent(m_hReceiveCloseEvent);
//設置所有事件無效
SetCommMask(m_hCom,0);
//清空所有將要讀的數據
PurgeComm(m_hCom,PURGE_RXCLEAR);
//等待10秒,如果接收線程沒有退出,則強制退出
if (WaitForSingleObject(m_hReceiveThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hReceiveThread,0);
}
//置標志
m_hReceiveThread = NULL;
return TRUE;
}
/************************************************************************/
// 函數名稱: StartInfoProcessThread()
// 函數描述: 啟動解析線程
// 入口參數:
// 出口參數:
// 返 回 值: 啟動成功返回TRUE;否則返回FALSE
// 其 它:
/************************************************************************/
BOOL MyWin32Port::StartInfoProcessThread()
{
m_hInfoProcessThread = AfxBeginThread(InfoProcessThread,this);
if (NULL == m_hInfoProcessThread)
{
TRACE(_T("啟動解析線程失敗,錯誤號:%d"),GetLastError());
return FALSE;
}
return TRUE;
}
/************************************************************************/
// 函數名稱: EndInfoProcessThread()
// 函數描述: 終止解析線程
// 入口參數:
// 出口參數:
// 返 回 值: 成功返回TRUE;否則返回FALSE
// 其 它:
/************************************************************************/
BOOL MyWin32Port::EndInfoProcessThread()
{
if (NULL==m_hInfoProcessThread)
{
return FALSE;
}
//設置解析線程退出事件
SetEvent(m_hInfoProcessCloseEvent);
//等待10秒,如果解析線程沒有退出,則強制退出
if (WaitForSingleObject(m_hInfoProcessThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hInfoProcessThread,0);
}
//置標志
m_hInfoProcessThread = NULL;
return TRUE;
}
/************************************************************************/
// 函數名稱: Process( char* pContent, int nLength )
// 函數描述: 信息處理
// 入口參數:
// char* pContent 待處理的字符串
// int nLength 待處理的字符串長度
// 出口參數:
// 返 回 值: 成功返回TRUE;否則返回FALSE
// 其 它:
/************************************************************************/
BOOL MyWin32Port::Process( char* pContent, int nLength )
{
if ((NULL == m_hWnd) ||(NULL==pContent) || (nLength<=3) )
{
return FALSE;
}
if (m_pCurParsedContent)
{
delete m_pCurParsedContent;
m_pCurParsedContent = NULL;
}
m_pCurParsedContent = new BYTE[nLength+1];
memcpy(m_pCurParsedContent,pContent,nLength*sizeof(BYTE));
m_pCurParsedContent[nLength] = '\0';
WPARAM wParam = (WPARAM)m_pCurParsedContent;
LPARAM lParam = (LPARAM)nLength;
::SendMessage(m_hWnd,WM_FRAME_NOTIFY,wParam,lParam); //給界面程序發送通知消息
return TRUE;
}
////////////////////////////導出函數相關/////////////////////////////////
/************************************************************************/
// 函數名稱: GetFrameTypeID(BYTE* pData,int realLen)
// 函數描述: 根據傳入的字符串判斷信息相應的類型
// 入口參數:
// BYTE* pData 輸入的待解析的字符串
// int iDataLen pData字符串的長度
// 出口參數:
// 返 回 值: 信息的類型
// 其 它:
/************************************************************************/
EYCDataType DLL_EXPORT GetFrameTypeID (BYTE *pData, int &realLen)
{
if ((NULL==pData) || (realLen<=0))
{
return YC_NULL;
}
EYCDataType enumYCDataType;
char frameType = pData[2];
switch(frameType)
{
case 1:
enumYCDataType = YC_FIRSTFRAME;
break;
case 2:
enumYCDataType = YC_SECONDFRAME;
break;
case 3:
enumYCDataType = YC_THIRDFRAME;
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -