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

📄 devserver.cpp

📁 国家环保总局污染源在线通讯协议的简化版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
///	函数返回:	成功返回TRUE失败返回FALSE。
///	参数意义:	data			MCGS传过来的MCGS_DATA结构的指针
///				byteArray		用来保存从串口读回来的数据。
///	备	  注:	此函数用于提供通用服务,建议不修改。
///	
inline BOOL CDevServer::mfReadComm(MCGS_DATA &data, CByteArray& byteArray)
{
	byteArray.SetSize(0);
	
	if (!mfIsCommDev(data)) return FALSE;
	
	DWORD dwErrorFlags = 0;
	COMSTAT ComStat;
	ClearCommError(data.m_pParentData, &dwErrorFlags, &ComStat);
	if (dwErrorFlags > 0)
	{
		///	ASSERT(FALSE);考虑到这个错误发生是正常的所以不做断言了。
		TRACE(_T("串口发生一个错误!\n"));
		return FALSE;
	}	
	
	BOOL bRes = TRUE;
	if (ComStat.cbInQue > 0) 
	{
		///	输入缓冲有数据,则读取
		DWORD dwLength = ComStat.cbInQue;
		byteArray.SetSize(dwLength);
#ifdef MCGSSET_ESET
		///	这一段是在组态和模拟运行环境下用的代码			
		
		OVERLAPPED os;
		memset(&os, 0, sizeof(OVERLAPPED));
		os.Offset = 0;
		os.OffsetHigh = 0;
		if ((os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
		{
			byteArray.SetSize(0);
			return FALSE;	
		}		
		
		BOOL fState = ReadFile(data.m_pParentData, byteArray.GetData(),
			dwLength, &dwLength, &os);		
		if (!fState) 
		{
			if (GetLastError() != ERROR_IO_PENDING)
			{ 
				///	写失败,且不是由于异步操作在后台进行引起的。
				bRes = FALSE;
			}
			else
			{
				///	异步操作在后台进行。
				DWORD dwRes = WaitForSingleObject(os.hEvent, INFINITE);
				switch(dwRes)
				{
					///	重叠操作的事件信号已经被触发了。
				case WAIT_OBJECT_0:
					{
						if (!GetOverlappedResult(data.m_pParentData,
							&os, &dwLength, FALSE))
						{
							bRes = FALSE;
						}
						else
						{
							///	写操作成功。
							bRes = TRUE;
						}
					}break;				
				default:
					{
						///	在等待事件的过程中发生了一个错误。
						bRes = FALSE;
					}break;
				}
			}							
		}		
		CloseHandle(os.hEvent);
		
#endif //MCGSSET_ESET
		
#ifdef MCGS_WCE_EMU
		///	此段暂时不会调用到
#endif //MCGS_WCE_EMU
		
#ifdef MCGS_WCE
		///	这一段时运行环境下调用的代码
		
		bRes = ReadFile(data.m_pParentData, byteArray.GetData(),
			dwLength, &dwLength,  NULL);
		
#endif //MCGS_WCE	
	}
	else
	{
		return bRes = FALSE;
	}
	
	return bRes;
}

///	函数功能:	用于把CString字符串转化为CByteArry数组。
///	函数返回:	0,转换出错,其他表示转换的字节数。
///	参数意义:	str				原CString字符串。
///				byte			目标CByteArry数组。
///	备	  注:	此函数用于提供通用服务,建议不修改。
///	
int CDevServer::SvrStr2Byte(CString &str, CByteArray &byte)
{
	byte.SetSize(0);
	
#ifdef _UNICODE
	
	int nLen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
	if (nLen == 0)
	{
		return 0;
	}
	byte.SetSize(nLen);
	if (nLen != WideCharToMultiByte(CP_ACP, 0, str, -1,
		(char*)byte.GetData(), nLen, NULL, NULL))
	{
		byte.SetSize(0);
		return 0;
	}
	byte.SetSize(nLen - 1);
	
#else
	
	byte.SetSize(str.GetLength());
	memcpy(byte.GetData(), (LPCTSTR)str, str.GetLength());
	
#endif //_UNICODE
	return byte.GetSize();
}

///	函数功能:	用于把CByteArry数组转化为CString字符串。
///	函数返回:	0,转换出错,其他表示转换的字节数。
///	参数意义:	byte			原CByteArry数组。
///				str				目标CString字符串。
///	备	  注:	此函数用于提供通用服务,建议不修改。
///	
int CDevServer::SvrByte2Str(CByteArray &byte, CString &str)
{
#ifdef _UNICODE
	byte.SetSize(byte.GetSize() + 1);
	byte[byte.GetSize() - 1] = 0;
	PWSTR pWideChar;
	int nLen = MultiByteToWideChar(CP_ACP, 0,
		(char*)byte.GetData(), -1, NULL, 0);
	if (nLen == 0)
	{
		return 0;
	}
	pWideChar = (PWSTR)HeapAlloc(GetProcessHeap(), 0, nLen*sizeof(WCHAR));
	if (pWideChar == NULL)
	{
		return 0;
	}
	if (nLen != MultiByteToWideChar(CP_ACP, 0,
		(char*)byte.GetData(), -1, pWideChar, nLen))
	{
		HeapFree(GetProcessHeap(), 0, pWideChar);
		return 0;
	}
	str = pWideChar;
	HeapFree(GetProcessHeap(), 0, pWideChar);
#else
	byte.SetSize(byte.GetSize() + 1);
	byte[byte.GetSize() - 1] = 0;
	str = (LPCTSTR)byte.GetData();
#endif //_UNICODE
	
	return byte.GetSize();
}

///	函数功能:	这个函数用于16进制值传输而不是字符串传输的协议的设备驱动。
///				把字符串转化为字节型数组。
///	函数返回:	TRUE,正确。FALSE,错误。
///	参数意义:	strProtocol		原字符串。
///				bytArProtocol	目标字节型数组。
///				
///	备	  注:	此函数用于提供通用服务,建议不修改。
///	
BOOL CDevServer::SvrHStr2HByte(CString& strProtocol, CByteArray& bytArProtocol)
{
	int nstrLen = strProtocol.GetLength();	
	int nBlockLen = 2;
	
	if (nstrLen%nBlockLen != 0 || nstrLen == 0)
	{
		ASSERT(FALSE);
		return FALSE;
	}
	
	bytArProtocol.SetSize(nstrLen/2);	
	
	for (int i = 0; i < nstrLen; i += nBlockLen)
	{
		int nData = 0;
		_stscanf(strProtocol.Mid(i, 2), _T("%x"), &nData);
		bytArProtocol.SetAt(i/2, unsigned char(nData));				
	}
	
	return TRUE;
}

///	函数功能:	这个函数用于16进制值传输而不是字符串传输的协议的设备驱动。
///				把字节型数组转化为字符串。
///	函数返回:	TRUE,正确。FALSE,错误。
///	参数意义:	bytArProtocol	原字节型数组。	
///				strProtocol		目标字符串。
///				
///	备	  注:	此函数用于提供通用服务,建议不修改。
///	
BOOL CDevServer::SvrHByte2HStr(CByteArray& bytArProtocol, CString& strProtocol)
{	
	strProtocol = _T("");
	CString strTemp = _T("");
	for (int i = 0; i < bytArProtocol.GetSize(); i ++)
	{
		strTemp.Format(_T("%.2X"), bytArProtocol.GetAt(i));				
		strProtocol += strTemp;
	}
	
	return TRUE;
}

///	函数功能:	这个函数用于将从设备读回来的字符串转化为一个 double 型的数值,即一个通道的值。
///	函数返回:	通道的值。
///	参数意义:	strProtocol		从设备读回来的字符串。
///				nDateType		该通道的数据类型:
///								0--16:	位操作的位序号。
///								80:	无符号8位二进制数。
///								81:	有符号8位二进制数。
///								82:	8位BCD码。
///								83:	无符号16位二进制数。
///								84:	有符号16位二进制数。
///								85:	16位BCD码。
///								86:	无符号32位二进制数。
///								87:	有符号32位二进制数。
///								88:	32位BCD码。
///								89:	32位浮点数。
///								100:	ASCII表示的浮点数。	
///				nBlockLen		设备中数据通常底位在前,高位在后,这是块长度,
///								1表示1个字符,通常是4个位。
///				nBytes			位操作的时候他表示字节数,nDataType = 100时他表示要用的字符串长。
///								其它时候没有意义。
///	备	  注:	此函数用于提供通用服务,建议不修改。
///				应用举例:strProtocol = _T("2345"),通常这是一个HEX的字符串,即两个字符表示一个字节。
///					转换时通常nBlockLen = 2,即高位字节在后,地位字节在前
///					如果nDataType = 85,则结果是4523。如果nDataType = 83,则结果是0X4523。
///					如果nDataType = 1,nBytes = 2 则结果是1。nDataType = 2 则结果是0。
///					如果strProtocol = _T("234.56"),nDataType = 100则结果是234.56。
double CDevServer::SvrStr2Double(CString strProtocol,
								 int nDataType,
								 int nBlockLen,
								 int nBytes)
{
	double dReturn = 0;
	CString strValue = _T("");

	///	这一段获取需要的字符串
	{
		int nStrLen = 0;
		if (nDataType < 16)
		{
			nStrLen = 2 * nBytes;
			
		}
		else if (nDataType >= 80 && nDataType < 89)
		{
			nStrLen = (int)pow(2, (nDataType - 80)/3 + 1);
		}
		else if (nDataType == 89)
		{
			///	如果是标准浮点数,那么这个字符串的长度必定是8(4个字节)。
			nStrLen = 8;
		}
		else if (nDataType == 100)
		{
			nStrLen = nBytes;
		}
		else
		{
			ASSERT(FALSE);
		}
		
		strValue = strProtocol.Left(nStrLen);
		if (nBlockLen > 0)
		{
			CString strTemp = strValue;
			strValue = _T("");
			ASSERT(nStrLen%nBlockLen == 0);		
			for (int i = 0; i < nStrLen; i += nBlockLen)
			{		
				strValue += strTemp.Mid(nStrLen - nBlockLen - i, nBlockLen);
			}
		}	
	}

	int nData = 0;
	if (nDataType < 16)
	{
		///	表示这是位操作		
		_stscanf(strValue, _T("%x"), &nData);	
		dReturn = (nData>>nBytes)&0x01;		
	}
	else if (nDataType >= 80 && nDataType < 89)
	{
		switch (nDataType)
		{
		case 80:
			{			
				_stscanf(strValue, _T("%X"), &nData);	
				dReturn = (unsigned char)(nData & 0xFF);
			}break;
		case 81:
			{			
				_stscanf(strValue, _T("%X"), &nData);	
				dReturn = (signed char)(nData & 0xFF);
			}break;
		case 82:
			{			
				_stscanf(strValue, _T("%d"), &nData);	
				dReturn = nData;
			}break;
		case 83:
			{			
				_stscanf(strValue, _T("%X"), &nData);	
				dReturn = (unsigned short)(nData & 0xFFFF);
			}break;
		case 84:
			{			
				_stscanf(strValue, _T("%X"), &nData);	
				dReturn = (signed short)(nData & 0xFFFF);
			}break;
		case 85:
			{			
				_stscanf(strValue, _T("%d"), &nData);	
				dReturn = nData;
			}break;
		case 86:
			{			
				_stscanf(strValue, _T("%X"), &nData);	
				dReturn = (DWORD)nData;
			}break;
		case 87:
			{			
				_stscanf(strValue, _T("%X"), &nData);	
				dReturn = nData;
			}break;
		case 88:
			{			
				_stscanf(strValue, _T("%d"), &nData);	
				dReturn = nData;
			}break;		
		}
	}
	else if (nDataType == 89)
	{
		///	如果是标准浮点数,那么这个字符串的长度必定是8(4个字节)。
		unsigned char cf[4];			
		for (int i = 0; i < 4; i ++)
		{				
			_stscanf(strValue.Mid(2 * i, 2), _T("%x"), &nData);
			cf[i] = nData;				
		}	
		float f = 0;
		CopyMemory(&f, cf, 4);
		dReturn = f;
		
	}
	else if (nDataType == 100)
	{
		float fData = 0;
		_stscanf(strValue, _T("%f"), &fData);	
		dReturn = fData;
	}
	else
	{
		ASSERT(FALSE);
	}

	return dReturn;
}

///	函数功能:	这个函数用于将一个 double 型的数值(即一个通道的值)转化为要写到设备的字符串。
///	函数返回:	要写到设备的字符串。
///	参数意义:	dData			一个 double 型的数值(即一个通道的值)。
///				nDataType		该通道的数据类型:
///								80:	无符号8位二进制数。
///								81:	有符号8位二进制数。
///								82:	8位BCD码。
///								83:	无符号16位二进制数。
///								84:	有符号16位二进制数。
///								85:	16位BCD码。
///								86:	无符号32位二进制数。
///								87:	有符号32位二进制数。
///								88:	32位BCD码。
///								89:	32位浮点数。
///								100:	ASCII表示的浮点数。	
///				nBlockLen		设备中数据通常底位在前,高位在后,这是块长度,1表示1个字符即4个位。
///				nStrLen			要产生的字符串的长度。
///	备	  注:	此函数用于提供通用服务,建议不修改。此函数功能和上一个函数相反。
///	
CString CDevServer::SvrDouble2Str(double dData,
								  int nDataType,
								  int nBlockLen,
								  int nStrLen)
{
	if (nDataType >= 80 && nDataType < 89)
	{
		nStrLen = (int)pow(2, (nDataType - 80)/3 + 1);
	}
	else if (nDataType == 89)
	{
		///	如果是标准浮点数,那么这个字符串的长度必定是8(4个字节)。
		nStrLen = 8;
	}
	else if (nDataType == 100)
	{
		;
	}
	else
	{
		ASSERT(FALSE);
	}
	CString strFormat = _T("");
	strFormat.Format(_T("%%.%d"), nStrLen);	

	CString strValue = _T("");
	if (nDataType >= 80 && nDataType < 89)
	{
		DWORD dwValue = 0;
		switch (nDataType)
		{
		case 80:
			{
				dwValue =(DWORD)((unsigned char)(dData));
				strFormat += _T("X");
			}break;
		case 81:
			{
				dwValue =(DWORD)((signed char)(dData));
				strFormat += _T("X");
			}break;
		case 82:
			{
				dwValue =(DWORD)((unsigned char)(dData));
				strFormat += _T("d");
			}break;
		case 83:
			{
				dwValue =(DWORD)((unsigned short)(dData));
				strFormat += _T("X");
			}break;
		case 84:
			{
				dwValue =(DWORD)((signed short)(dData));
				strFormat += _T("X");
			}break;
		case 85:
			{	
				dwValue =(DWORD)((unsigned short)(dData));
				strFormat += _T("d");
			}break;
		case 86:
			{	
				dwValue =(DWORD)(dData);
				strFormat += _T("X");
			}break;
		case 87:
			{	
				dwValue =(DWORD)((int)(dData));
				strFormat += _T("X");
			}break;
		case 88:
			{	
				dwValue =(DWORD)(dData);
				strFormat += _T("d");
			}break;		
		}
		strValue.Format(strFormat, dwValue);	
	}
	else if (nDataType == 89)
	{
		///	如果是标准浮点数,那么这个字符串的长度必定是8(4个字节)。
		float f = float(dData);
		unsigned char cf[4];	
		CopyMemory(cf, &f, 4);	
		CString strTemp = _T("");
		for (int i = 0; i < 4; i ++)
		{	
			strTemp.Format(_T("%.2x"), cf[i]);
			strValue += strTemp;
		}	
	}
	else if (nDataType == 100)
	{
		strFormat.Format(_T("%%%d.%df"), nStrLen, nBlockLen);	
		strValue.Format(strFormat, dData);
	}

	strValue = strValue.Right(nStrLen);

	CString strProtocol = _T("");
	
	if (nBlockLen > 0 && nDataType != 100)
	{
		
		for (int i = 0; i < nStrLen; i += nBlockLen)
		{		
			strProtocol += strValue.Mid(nStrLen - nBlockLen- i, nBlockLen);
		}
	}
	else
	{
		strProtocol = strValue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -