⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mywin32port.cpp

📁 多线程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/************************************************************************/
// 函数名称: 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 + -