www.pudn.com > hmmPlatform.rar > WaveDisplay.cpp


#include "StdAfx.h" 
#include ".\wavedisplay.h" 
 
////////////////////////////////////////////////////////////////////////// 
// class CWaveDisplay 
// 
// 功能:	实现数据的在GUI上的显示 
// 创建人:	陈文凯 (chwkai@gmail.com) 
// 创建日期:2005年5月19日 
// 修改人: 
// 修改日期: 
// 版本 
 
CWaveDisplay::CWaveDisplay(HWND hOwner) 
: m_nPrecision(0) 
{ 
	this->InitDefaultSetting(); 
 
	// 设定父控件 
	this->m_hOwner = hOwner; 
} 
 
CWaveDisplay::~CWaveDisplay(void) 
{ 
	this->Dispose(); 
} 
 
BEGIN_MESSAGE_MAP(CWaveDisplay, CStatic) 
	ON_WM_PAINT() 
	ON_WM_MOUSEWHEEL() 
END_MESSAGE_MAP() 
 
////////////////////////////////////////////////////////////////////////// 
// 调用默认设置函数,初始化显示区域 
void CWaveDisplay::InitDefaultSetting() 
{ 
	// 缓冲为空 
	this->m_pBuffer = NULL; 
 
	//// 设置显示参数 
	this->SetGridWidth(); 
	this->SetCoordinateWidth(); 
	this->SetCellSize(); 
	this->SetLineWidth(); 
	this->SetPrecision(); 
 
	this->SetLineColor(); 
	this->SetBkColor(); 
	this->SetGridColor(); 
	this->SetCoordinateColor(); 
 
	this->SetXMetrics(); 
	this->SetYMetrics(); 
	this->SetZoomStep(); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 进行显示区域初始化,画出背景和网格 
void CWaveDisplay::DrawTable(CPaintDC* pDc) 
{ 
	CSize size;								// 显示区域大小 
	int curVPos = 0;						// 绘制线条处的y 
	int curHPos = 0;						// 绘制线条处的x 
 
	CPen linePen(0, this->m_nGridWidth, this->m_refGridColor);				// 设置网格线条 
	CPen coPen(0, this->m_nCoordinateWidth, this->m_refCoordinateColor);	// 设置坐标轴线条 
	CBrush bkBrush(this->m_refBkColor);		// 用于设置背景色 
 
	// 获取显示区域大小,并设定区域原点位置 
	this->GetClientRect(&this->m_clientRect); 
	size = this->m_clientRect.Size(); 
	this->m_ptOrigin.y = (this->m_clientRect.bottom - this->m_clientRect.top) / 2; 
	this->m_ptOrigin.x = 0; 
	this->m_ptCurPos = this->m_ptOrigin; 
 
	// 填充背景 
	pDc->FillRect(&this->m_clientRect, &bkBrush); 
 
	// 绘制X轴 
	pDc->SelectObject(coPen); 
	pDc->MoveTo(this->m_ptOrigin.x, this->m_ptOrigin.y); 
	pDc->LineTo(this->m_clientRect.right - this->m_clientRect.left, this->m_ptOrigin.y); 
 
	// 绘制网格线 
	pDc->SelectObject(linePen); 
 
	// 先绘制纵向线条 
	curHPos = this->m_ptOrigin.x; 
	while (curHPos < size.cx) 
	{ 
		pDc->MoveTo(curHPos, 0); 
		pDc->LineTo(curHPos, size.cy); 
 
		curHPos += this->m_nCellSize; 
	} 
 
	// 再绘制横向线条,先绘制上半轴 
	curVPos = this->m_ptOrigin.y - this->m_nCellSize; 
 
	while (curVPos > 0) 
	{ 
		pDc->MoveTo(this->m_ptOrigin.x, curVPos); 
		pDc->LineTo(size.cx, curVPos); 
 
		curVPos -= this->m_nCellSize; 
	} 
 
	// 再绘制下半轴 
	curVPos = this->m_ptOrigin.y + this->m_nCellSize; 
 
	while (curVPos < this->m_clientRect.bottom) 
	{ 
		pDc->MoveTo(this->m_ptOrigin.x, curVPos); 
		pDc->LineTo(size.cx, curVPos); 
 
		curVPos += this->m_nCellSize; 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 按设定的显示精度,绘制数据 
void CWaveDisplay::DrawData(CPaintDC* pDc) 
{ 
	CPen linePen(0, this->m_nLineWidth, this->m_refLineColor); 
	UINT nCount = 0; 
 
	// 读取缓冲数据 
	if (this->m_pBuffer != NULL) 
	{ 
		pDc->SelectObject(linePen); 
		pDc->MoveTo(this->m_ptCurPos); 
 
		for (UINT nCount = 0;  
			nCount < this->m_pBuffer->nSize && this->m_ptCurPos.x < this->m_clientRect.right;  
			nCount += this->m_nPrecision) 
		{ 
			// 计算纵坐标 
			this->m_ptCurPos.y = this->m_pBuffer->lpData[nCount] * this->m_fYMetrics; 
			this->m_ptCurPos.y = this->m_ptOrigin.y - this->m_ptCurPos.y; 
 
			// 对数值进行截取 
			this->m_ptCurPos.y  =  
				(this->m_ptCurPos.y > this->m_clientRect.bottom ?  
				this->m_clientRect.bottom : this->m_ptCurPos.y); 
			this->m_ptCurPos.y  =  
				(this->m_ptCurPos.y < this->m_clientRect.top ?  
				this->m_clientRect.top : this->m_ptCurPos.y); 
 
			pDc->LineTo(this->m_ptCurPos); 
			//pDc->MoveTo(this->m_ptCurPos); 
 
			this->m_ptCurPos.x += this->m_fXMetrics; 
 
		} 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 释放所占用的资源 
void CWaveDisplay::Dispose() 
{ 
	PDisplayChunk lpTemp = NULL; 
 
	while (this->m_pBuffer != NULL) 
	{ 
		lpTemp = this->m_pBuffer; 
		this->m_pBuffer = this->m_pBuffer->lpNext; 
 
		if (lpTemp->lpData != NULL) 
		{ 
			delete[] lpTemp->lpData; 
		} 
 
		delete[] lpTemp; 
	} 
 
	this->m_pBuffer = NULL; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定显示数据 
void CWaveDisplay::LoadData(double* pData,  unsigned int nSize) 
{ 
	BOOL bRet = false;				// 设定样本是否成功 
	PDisplayChunk pChunk = NULL; 
 
	if (pData != NULL) 
	{ 
		// 拷贝显示数据 
		pChunk = new DisplayChunk; 
		pChunk->lpData = new double[nSize]; 
		pChunk->nDataReaded = 0; 
		pChunk->nSize = nSize; 
		pChunk->lpNext = NULL; 
 
		memcpy(pChunk->lpData, pData, sizeof(double) * nSize); 
	} 
	 
	this->m_pBuffer = pChunk; 
 
	// 画出新数据 
	this->Invalidate(); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 加入新的显示缓冲块,维护缓冲块链表 
//void CWaveDisplay::AppendBuffer(PDisplayChunk pChunk) 
//{ 
//	PDisplayChunk lpTemp = NULL; 
// 
//	if (pChunk != NULL && pChunk->lpData != NULL) 
//	{ 
//		// 若显示缓冲为空 
//		if (this->m_pBuffer == NULL) 
//		{ 
//			this->m_pBuffer = pChunk; 
//		} 
//		// 把缓冲添加到链表最后 
//		else 
//		{ 
//			lpTemp = this->m_pBuffer; 
// 
//			while (lpTemp->lpNext != NULL) 
//			{ 
//				lpTemp = lpTemp->lpNext; 
//			} 
// 
//			lpTemp->lpNext = pChunk;			 
//		} 
// 
//		pChunk->lpNext = NULL; 
//	} 
//} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定波形颜色 
void CWaveDisplay::SetLineColor( int nRed /* = 0 */, int nGreen /* = 128 */, int nBlack /* = 64 */) 
{ 
	this->m_refLineColor = RGB(nRed, nGreen, nBlack); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定背景颜色 
void CWaveDisplay::SetBkColor( int nRed /* = 0 */, int nGreen /* = 0 */, int nBlack /* = 0 */) 
{ 
	this->m_refBkColor = RGB(nRed, nGreen, nBlack); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定坐标轴颜色 
void CWaveDisplay::SetCoordinateColor( int nRed /* = 255 */, int nGreen /* = 255 */, int nBlack /* = 0 */) 
{ 
	this->m_refCoordinateColor = RGB(nRed, nGreen, nBlack); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定网格颜色 
void CWaveDisplay::SetGridColor( int nRed /* = 0 */, int nGreen /* = 128 */, int nBlack /* = 64s */) 
{ 
	this->m_refGridColor = RGB(nRed, nGreen, nBlack); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定X轴逻辑单元宽度 
void CWaveDisplay::SetXMetrics(float fValue /* = 1 */) 
{ 
	if (fValue > 0) 
	{ 
		this->m_fXMetrics = fValue; 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定Y轴逻辑单元宽度 
void CWaveDisplay::SetYMetrics(float fValue /* = 1 */) 
{ 
	if (fValue > 0) 
	{ 
		this->m_fYMetrics = fValue; 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定显示单元格的宽(高)度,以象素为单位 
void CWaveDisplay::SetCellSize(UINT nSize /* = 10 */) 
{ 
	this->m_nCellSize = nSize; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定数据线条宽度 
void CWaveDisplay::SetLineWidth(UINT nWidth /* = 1 */) 
{ 
	this->m_nLineWidth = nWidth; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定坐标轴宽度 
void CWaveDisplay::SetCoordinateWidth(UINT nWidth /* = 1 */) 
{ 
	this->m_nCoordinateWidth = nWidth; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定网格线宽度 
void CWaveDisplay::SetGridWidth(UINT nWidth /* = 1 */) 
{ 
	this->m_nGridWidth = nWidth; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 重载CWnd::OnPaint,绘制波形数据 
void CWaveDisplay::OnPaint() 
{ 
	CPaintDC dc(this); 
 
	this->DrawTable(&dc); 
	this->DrawData(&dc); 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 设定显示精度 
void CWaveDisplay::SetPrecision(UINT nPrecision) 
{ 
	this->m_nPrecision = nPrecision; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 用鼠标中键滚动,进行显示微调时的放大倍数 
void CWaveDisplay::SetZoomStep(UINT nStep) 
{ 
	this->m_nZoomStep = nStep; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 在鼠标中间滚动时,进行显示微调 
BOOL CWaveDisplay::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{ 
	// TODO: 在此添加消息处理程序代码和/或调用默认值 
	// 放大 
	if (zDelta > 0) 
	{ 
		this->m_fYMetrics *= this->m_nZoomStep; 
	} 
	else 
	{ 
		this->m_fYMetrics /= this->m_nZoomStep; 
	} 
 
	// 重绘数据 
	this->Invalidate(); 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 获取显示微调放大倍数 
UINT CWaveDisplay::GetZoomSetp() const 
{ 
	return this->m_nZoomStep; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 获取Y放大倍数 
float CWaveDisplay::GetYMetrics() const 
{ 
	return this->m_fYMetrics; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 获取X放大倍数 
float CWaveDisplay::GetXMetrics() const 
{ 
	return this->m_fXMetrics; 
} 
 
////////////////////////////////////////////////////////////////////////// 
// 获取显示精度 
UINT CWaveDisplay::GetPrecision() const 
{ 
	return this->m_nPrecision; 
}