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

📄 realtime.cpp

📁 读取串口数据并画实时曲线的VC源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
//#include <windows.h>
//#include <stdio.h>
#include "RealTime.h"

CALine::CALine()
{ 
	m_nColor		= RGB(0, 0, 0);		
	m_nLineStyle	= PS_SOLID;	
	m_nLineWidth	= 0;	
	m_pValues		= NULL;		
	m_sName			= "";		
	m_sDescription	= "";	
	m_sUnit			= "";		
	m_dMin			= 0;			
	m_dMax			= 0;			
	m_dScaleLow		= 0;	
	m_dScaleHigh	= 0;	
	m_nSize			= 0; 
}

bool CALine::Reset(DWORD size)
{
	assert(size > 0);
	if (m_pValues) free(m_pValues);
	m_pValues  = (CValue*)calloc((size_t)(size + 1), sizeof(CValue));
	if(!m_pValues) 
		return false;

	m_nSize = size;
	return true;
}

void CALine::AddValue(double& value, DWORD begin, DWORD end)
{
	if (m_pValues == NULL) return;
	if (end == m_nSize)
	{
		m_pValues[begin].bFlag	= 1;
		m_pValues[begin].YValue = value;
	}
	else
	{
		m_pValues[end].bFlag	= 1;
		m_pValues[end].YValue	= value;
	}
}

CRealTime::CRealTime()
{
	m_bSetingFailed	= true;
	m_nMaxPages		= 1;
	m_nTimeStart	= 0;
	m_nBegin		= 0;
	m_nEnd			= 0;
	m_nTimes		= 0;
	m_nCounter		= 1;
	m_nTick			= 0;
	m_sHigh			= 17;
	m_nPage			= 0;
	m_nMaxTime		= 0;
	m_nCursorTime	= 0;
	m_pValueTime	= NULL;
	m_pLineArray	= NULL;
	m_pCurLine		= NULL;
	m_wdTickLine	= 2;
	m_crTickLine	= RGB(255, 0, 0);

	m_SpeedLevel[0] = 10000;// 10 seconds	(0.1 cycle per second)
	m_SpeedLevel[1] = 5000;	// 5 seconds	(0.2 cycle per second)	
	m_SpeedLevel[2] = 2500;	// 2.5 seconds	(0.4 cycle per second)
	m_SpeedLevel[3] = 2000;	// 2 seconds	(0.5 cycle per second)
	m_SpeedLevel[4] = 1000;	// 1 seconds	(1 cycle per second)
	m_SpeedLevel[5] = 500;	// 0.5 seconds	(2 cycle per second)
	m_SpeedLevel[6] = 250;	// 0.4 seconds	(4 cycle per second)
	m_SpeedLevel[7] = 200;	// 0.2 seconds	(5 cycle per second)
	m_SpeedLevel[8] = 125;	// 0.125 seconds(8 cycle per second)
	m_SpeedLevel[9] = 100;  // 0.1 second	(10 cycle per second)
}

CRealTime::~CRealTime()
{
	if (m_pLineArray)
		free(m_pLineArray);

	if (m_pValueTime)
		free(m_pValueTime);

	int n = m_LineArray.GetSize();
	for(int i = n-1; i >= 0; i --)
		m_LineArray.RemoveAt(i);
}

RECT CRealTime::TickBarSize()
{
	m_SRect		   = m_PlotRect;
	m_SRect.top	   = m_SRect.top - m_sHigh;
	m_SRect.bottom = m_SRect.top  + m_sHigh - 1;
	m_SRect.left   = m_SRect.left - 7;
	m_SRect.right  = m_SRect.right + 7;

	return m_SRect;
}

bool CRealTime::SetRange(double xmin, double ymin, double xmax, double ymax)
{
	if (ymax <= ymin)
		return false; 

	m_Scale.xmin	= xmin;
    m_Scale.ymin	= ymin;
    m_Scale.xmax	= xmax;
    m_Scale.ymax	= ymax;
	return true; 
}

bool CRealTime::InitialSetting(double CycsPerSec, DWORD StartTime, DWORD TimeSpan,
							   DWORD MaxSeconds, int XTick, bool IsForward)
{
	if (!IsForward && 1000 * TimeSpan > StartTime)
	{
		int ret = MessageBox(NULL, "<1000 * TimeSpan - StartTime> must be positive value\nin initial backward drawing."
							 " Changed to foreward drawing?", 
							 "From InitialSetting() ...", MB_YESNO);
		if (ret == IDYES)
			IsForward = true;
		else
			return false;
	}

	assert(StartTime >= 0);
	assert(TimeSpan >= 30);
	assert(TimeSpan >= (DWORD)XTick);
	assert(MaxSeconds >= TimeSpan);
	MaxSeconds = TimeSpan * (MaxSeconds / TimeSpan);
	assert(CycsPerSec >= 0.09999 && CycsPerSec <= 10.00001f);

	if (MaxSeconds == TimeSpan ) MaxSeconds ++;
	m_nDataPerLine	= (DWORD)(0.5 + MaxSeconds * CycsPerSec + 1);

	m_pValueTime	= (DWORD*)calloc(m_nDataPerLine, sizeof(DWORD));
	if (!m_pValueTime)	return false;

	m_nMaxPages			= MaxSeconds / TimeSpan;
	m_nTimeSpan			= TimeSpan;
	m_nXTicks			= XTick;
	m_nCyclesPerSec		= CycsPerSec;
	m_nCounter			= (int)CycsPerSec;
	m_bIsForwardDrawing	= IsForward;
	m_nSTicks			= (int)(0.5 + TimeSpan * CycsPerSec);

	if (IsForward)
	{
		m_Scale.xmin = StartTime;
		m_Scale.xmax = StartTime + 1000. * TimeSpan;
	}
	else
	{
		m_Scale.xmin = StartTime - 1000. * TimeSpan;
		m_Scale.xmax = StartTime;
	}

	assert(m_Scale.xmin >= 0);
	assert(m_Scale.xmax >= 0);
	assert(m_Scale.xmax - m_Scale.xmin > 0);
	m_TimeToDraw = (DWORD)(0.5 + (m_Scale.xmax - m_Scale.xmin) / 1000 * m_nCyclesPerSec + 1);

	m_pLineArray = (POINT*)calloc(m_TimeToDraw, sizeof(POINT));
	if (!m_pLineArray)	
	{
		free(m_pValueTime);
		return false;
	}

	m_nMin = (DWORD)m_Scale.xmin;
	m_nMax = (DWORD)m_Scale.xmax;
	SetTimeRange(m_nMin, m_nMax);
	m_bAutoScrollX = true;

	EnableLegend(false);
	m_bLegendShadow = false;

	return	true;
}

void CRealTime::SetTimeRange(DWORD FromTime, DWORD ToTime)
{
	assert(ToTime - FromTime > 0);
	m_Scale.xmin = FromTime;
	m_Scale.xmax = ToTime;
	m_Scale.dx   = (m_Scale.xmax - m_Scale.xmin) / PX;
}

void CRealTime::Reset()
{
	if (m_bAutoScrollX)
		SetTimeRange(m_nMin, m_nMax);
	else
	{
		if (m_nEnd == m_nDataPerLine)
			m_nFrom = m_nBegin + m_nPage * (m_TimeToDraw - 1);
		else
			m_nFrom = m_nBegin + m_nPage * (m_TimeToDraw - 1); // -1 ;
		m_nFrom %= m_nDataPerLine;
		m_nTo    = m_nFrom + m_TimeToDraw - 1;
		m_nTo   %= m_nDataPerLine;
		SetTimeRange(m_pValueTime[m_nFrom], m_pValueTime[m_nTo]);
	}
}

bool CRealTime::AddALine(COLORREF color, double low, double high, 
						 const char* name, const char* desc, const char* unit, 
						 double min, double max, int style, int width)
{
	m_LineArray.Add(m_line);
	int n = m_LineArray.GetSize() - 1;

	// support only three styles : PS_SOLID, PS_DASH, PS_DOT
	if (style < PS_SOLID) style = PS_SOLID;
	if (style > PS_DOT) style	= PS_DOT;

	m_LineArray[n].m_nColor			= color;
	m_LineArray[n].m_dScaleLow		= low;			
	m_LineArray[n].m_dScaleHigh		= high;
	m_LineArray[n].m_sName			= name;
	m_LineArray[n].m_sDescription	= desc;	
	m_LineArray[n].m_sUnit			= unit;		
	m_LineArray[n].m_dMin			= min;			
	m_LineArray[n].m_dMax			= max;			
	m_LineArray[n].m_nLineStyle		= style;
	m_LineArray[n].m_nLineWidth		= width;

	if (!m_LineArray[n].Reset(m_nDataPerLine))
	{
		m_LineArray.RemoveAt(n);
		return false;
	}

	return true;
}

bool CRealTime::InsertALine(int index, COLORREF color, double low, double high, 
						 const char* name, const char* desc, const char* unit, 
						 double min, double max, int style, int width)
{
	int n = m_LineArray.GetSize();
	if (index < 0 || index > n)
		return false;

	m_LineArray.InsertAt(index, m_line);

	if (style < PS_SOLID) style = PS_SOLID;
	if (style > PS_DOT) style	= PS_DOT;

	m_LineArray[index].m_nColor			= color;
	m_LineArray[index].m_dScaleLow		= low;			
	m_LineArray[index].m_dScaleHigh		= high;
	m_LineArray[index].m_sName			= name;
	m_LineArray[index].m_sDescription	= desc;	
	m_LineArray[index].m_sUnit			= unit;		
	m_LineArray[index].m_dMin			= min;			
	m_LineArray[index].m_dMax			= max;			
	m_LineArray[index].m_nLineStyle		= style;
	m_LineArray[index].m_nLineWidth		= width;

	if (!m_LineArray[index].Reset(m_nDataPerLine))
	{
		m_LineArray.RemoveAt(index);
		return false;
	}

	return true;
}

bool CRealTime::RemoveALine(int Index)
{
	int n = m_LineArray.GetSize();
	if (n <= 0 || n <= Index)
		return false;

	m_LineArray.RemoveAt(Index);
	return true;
}

void CRealTime::DrawXAxisTimeTicks(int x, int y, DWORD& ticks)
{
	sprintf(m_sTempStr, "%d:%d:%d", ticks/3600, (ticks/60)%60, ticks%60);
	PrintString(x, y, 0, m_sTempStr);	
}

void CRealTime::XAxis()
{
	m_nStep = (m_TimeToDraw > m_nEnd) ? m_nEnd : m_TimeToDraw;
	for(int i = 0; i < m_nStep; i ++) 
	{
		DWORD sec = (DWORD)(m_Scale.xmin + i * 1000 / m_nCyclesPerSec + 0.5);
		xb = xe = (int)(GL + (sec - m_Scale.xmin) / m_Scale.dx);
		if ((sec % 1000) == 0 && ((sec / 1000) % (m_nTimeSpan / m_nXTicks)) == 0)
		{
			if (i == 0)
				SetStringAlign(LEFT, TOP);
			else if (i >= m_nStep - (int)m_nCyclesPerSec - 1 && m_TimeToDraw <= m_nEnd)
				SetStringAlign(RIGHT, TOP);
			else
				SetStringAlign(CENTER, TOP);

			ye = GB + m_bM / 7;
			DWORD ticks = sec / 1000;
			DrawXAxisTimeTicks(xb, GB + m_bM / 5, ticks);
		}
		else 
			ye = GB + m_bM / 14;

		yb=GB;
		if (!(sec % 1000) && i > 0 && i < m_nStep - 1)
			DrawLine(xb, yb, xe, ye);
	}

	PrintTime();
}

void CRealTime::Grid()
{
	HPEN hPen	= ::CreatePen(PS_DOT, 0, m_nGridColor);
	HPEN hOldPen = (HPEN)::SelectObject(m_hDC, hPen);

	m_nStep = (m_TimeToDraw > m_nEnd) ? m_nEnd : m_TimeToDraw;
	for(int i = 0; i < m_nStep; i ++) 
	{
		DWORD sec = (DWORD)(m_Scale.xmin + i * 1000 / m_nCyclesPerSec + 0.5);
		xb = xe = (int)(GL + (sec - m_Scale.xmin) / m_Scale.dx);
		if (xb == GL)

⌨️ 快捷键说明

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