📄 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 + -