绘制动态波形图必要代码

1 头文件

#pragma once
#include "afxtempl.h"
#include "afxwin.h"
#ifdef  UNICODE
#define	COPYSTRING	wcscpy_s
#else 
#define	COPYSTRING	strcpy_s
#endif

#define		STR_CLASS_NAME		_T("CGraphView")

typedef		CArray<double>		DataBuff;
// CGraphView

class CGraphView : public CWnd
{
	DECLARE_DYNAMIC(CGraphView)

	CFont		m_fontView;
	COLORREF	m_clrCoordBkg,
				m_clrFrame,
				m_clrWave;
	int			m_nMarginLeft,
				m_nMarginTop,
				m_nMarginRight,
				m_nMarginBottom;
	double		m_dbStartX, m_dbEndX,
				m_dbStartY, m_dbEndY;
	double		m_dbResolutionX,
				m_dbResolutionY;
	int			m_nDivisionX,
				m_nDivisionY;
	DataBuff	m_dataGraph;

public:
	CGraphView();
	virtual ~CGraphView();

	void	RegisterCtrlClass();
	void	SetViewFont(const CString& strFont, int nPointSize, int nWeight, BOOL bIsRedraw=TRUE);
	void	SetMargin(int nLeft, int nTop, int nRight, int nBottom, BOOL bIsRedraw=TRUE);
	bool	SetGraphyView(double dbStartX, double dbEndX, double dbStartY, double dbEndY, int nDivisionX = 10, int nDivisionY = 10, BOOL bIsRedraw=TRUE);
	void	SetResolution(double dbResolutionX, double dbResolutionY, BOOL bIsRedraw=TRUE);
	void	LoadGraphyData(DataBuff& dataShow);

	void	DrawCoordinate(CDC* pDC, CRect rectCoord);
	void	DrawGraphy(CDC* pDC, CRect rectCoord);

protected:
	virtual void PreSubclassWindow();

public:
	afx_msg void OnPaint();

	DECLARE_MESSAGE_MAP()
};

2 函数实现

// GraphView.cpp : 实现文件
//

#include "stdafx.h"
#include "GxSingleCamMono.h"
#include "MyGraphView.h"


// CGraphView

IMPLEMENT_DYNAMIC(CGraphView, CWnd)

CGraphView::CGraphView()
{
	//注册控件类
	RegisterCtrlClass();

	m_nMarginLeft			= 50;
	m_nMarginTop			= 14;
	m_nMarginRight			= 25;
	m_nMarginBottom			= 15;

	m_dbResolutionX			= 1;
	m_dbResolutionY			= 1;
	m_nDivisionX			= 10;
	m_nDivisionY			= 10;

	m_dbStartX				= m_dbStartY	= 0;
	m_dbEndX				= m_dbEndY		= 100;

	//颜色表
	m_clrCoordBkg			= RGB(255, 255, 255);
	m_clrFrame				= RGB(0, 0, 0);
	m_clrWave				= RGB(0, 0, 255);
}

CGraphView::~CGraphView()
{
}

void CGraphView::RegisterCtrlClass()
{
	HINSTANCE hInstance = AfxGetInstanceHandle();

	WNDCLASS	wndclsCtrl;
	ZeroMemory(&wndclsCtrl, sizeof(WNDCLASS));

	if(::GetClassInfo(hInstance, STR_CLASS_NAME, &wndclsCtrl))
		return;

	//设置控件类信息
	wndclsCtrl.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wndclsCtrl.lpfnWndProc		= ::DefWindowProc;
	wndclsCtrl.cbClsExtra		= 0;
	wndclsCtrl.cbWndExtra		= 0;
	wndclsCtrl.hInstance		= hInstance;
	wndclsCtrl.hIcon			= NULL;
	wndclsCtrl.hCursor			= AfxGetApp()->LoadStandardCursor(IDC_ARROW);
	wndclsCtrl.hbrBackground	= NULL;
	wndclsCtrl.lpszMenuName		= NULL;
	wndclsCtrl.lpszClassName	= STR_CLASS_NAME;

	//注册控件类
	AfxRegisterClass(&wndclsCtrl);
}

void CGraphView::SetViewFont(const CString& strFont, int nPointSize, int nWeight, BOOL bIsRedraw)
{
	int		nCount;
	LOGFONT	lf;
	memset(&lf, 0, sizeof(LOGFONT));

	//设置字体样式
	nCount	= sizeof(lf.lfFaceName)/sizeof(TCHAR);
	COPYSTRING(lf.lfFaceName, nCount, strFont);
	lf.lfHeight	 = nPointSize;
	lf.lfWeight  = nWeight;
	lf.lfCharSet = GB2312_CHARSET;

	//清楚已有样式
	if(m_fontView.GetSafeHandle())
		m_fontView.DeleteObject();

	//设置字体
	m_fontView.CreateFontIndirect(&lf);

	if(bIsRedraw)
		Invalidate();
}

void CGraphView::SetMargin(int nLeft, int nTop, int nRight, int nBottom, BOOL bIsRedraw)
{
	m_nMarginLeft	= nLeft;
	m_nMarginTop	= nTop;
	m_nMarginRight	= nRight;
	m_nMarginBottom	= nBottom;

	if(bIsRedraw)
		Invalidate();
}

bool CGraphView::SetGraphyView(double dbStartX, double dbEndX, double dbStartY, double dbEndY, int nDivisionX, int nDivisionY, BOOL bIsRedraw)
{
	if(nDivisionX<=1||nDivisionY<=1)
		return false;

	m_dbStartX		= dbStartX;
	m_dbEndX		= dbEndX;
	m_dbStartY		= dbStartY;
	m_dbEndY		= dbEndY;
	m_nDivisionX	= nDivisionX;
	m_nDivisionY	= nDivisionY;

	if(bIsRedraw)
		Invalidate();

	return	true;
}

void CGraphView::SetResolution(double dbResolutionX, double dbResolutionY, BOOL bIsRedraw)
{
	m_dbResolutionX	= dbResolutionX;
	m_dbResolutionY	= dbResolutionY;

	if(bIsRedraw)
		Invalidate();
}

void CGraphView::LoadGraphyData(DataBuff& dataShow)
{
	double	dbData;
	INT_PTR	nCount	= dataShow.GetCount();

	if(nCount==0)
		return;

	m_dataGraph.RemoveAll();
	m_dataGraph.SetSize(nCount);
	for(int i=0; i<nCount; i++)
	{
		dbData	= dataShow.ElementAt(i);

		m_dataGraph.SetAt(i, dbData);
	}
	Invalidate();
}

void CGraphView::DrawCoordinate(CDC* pDC, CRect rectCoord)
{
	CString	strCoord;
	CRect	rectTemp;
	int		i, nSection, nOffset;
	CSize	szText, szUnit;
	double	dbTemp, dbTempStartY, dbTempStartX,
			dbRangX	= m_dbEndX-m_dbStartX,
			dbRangY	= m_dbEndY-m_dbStartY;

	dbTempStartX	= m_dbStartX;
	dbTempStartY	= m_dbStartY;

	pDC->FillSolidRect(rectCoord, m_clrCoordBkg);
	nOffset	= 2;
	for(i=0; i<=m_nDivisionX; i++)
	{
		dbTemp	= dbTempStartX+dbRangX*i/m_nDivisionX;
		strCoord.Format(_T("%g"), dbTemp);

		nSection	= rectCoord.Width()*i/m_nDivisionX;
		szText		= pDC->GetTextExtent(strCoord, strCoord.GetLength());

		rectTemp.SetRect(rectCoord.left+nSection-szText.cx/2, rectCoord.bottom+nOffset, rectCoord.left+nSection+szText.cx/2, rectCoord.bottom+szText.cy+nOffset);
		pDC->MoveTo(rectCoord.left+nSection, rectCoord.top);
		pDC->LineTo(rectCoord.left+nSection, rectCoord.bottom);
		pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_CENTER);
	}

	nOffset	= 2;
	for(i=0; i<=m_nDivisionY; i++)
	{
		dbTemp	= dbTempStartY+dbRangY*i/m_nDivisionY;
		strCoord.Format(_T("%g"), dbTemp);

		nSection	= rectCoord.Height()*i/m_nDivisionY;
		szText		= pDC->GetTextExtent(strCoord, strCoord.GetLength());

		rectTemp.SetRect(rectCoord.left-szText.cx-nOffset, rectCoord.bottom-nSection-szText.cy*2/3, rectCoord.left-nOffset, rectCoord.bottom-nSection+szText.cy/3);
		pDC->MoveTo(rectCoord.left, rectCoord.top+nSection);
		pDC->LineTo(rectCoord.right+1, rectCoord.top+nSection);
		pDC->DrawText(strCoord, strCoord.GetLength(), rectTemp, DT_RIGHT);
	}

	nOffset	= 4;
	rectTemp.SetRect(rectCoord.left+nOffset, rectCoord.top+1, rectCoord.right, rectCoord.bottom-nOffset);
	pDC->FillSolidRect(rectTemp, m_clrCoordBkg);
}

void CGraphView::DrawGraphy(CDC *pDC, CRect rectCoord)
{
	CRect	rectView;
	CRgn	rgnTemp, rgnView;
	CPen	penLine, *pOldPen;
	INT_PTR	nCount	= m_dataGraph.GetCount();

	if(nCount==0)
		return;

	double	dbData;
	int		nOffsetX, nOffsetY;
	int		nRangX	= abs(int((m_dbEndX-m_dbStartX)*m_dbResolutionX)),
			nRangY	= abs(int((m_dbEndY-m_dbStartY)*m_dbResolutionY));
	int		nCoordWith		= rectCoord.Width(),
			nCoordHeight	= rectCoord.Height(),
			nOriginX		= rectCoord.left-int(m_dbStartX*nCoordWith/nRangX),
			nOriginY		= rectCoord.bottom+int(m_dbStartY*nCoordHeight/nRangY);


	rgnTemp.CreateRectRgnIndirect(rectCoord);
	pDC->SelectObject(rgnTemp);
	penLine.CreatePen(PS_SOLID, 1, m_clrWave);
	pOldPen		= pDC->SelectObject(&penLine);

	dbData		= m_dataGraph.ElementAt(0);
	nOffsetY	= int(nCoordHeight*dbData/nRangY);
	pDC->MoveTo(nOriginX, nOriginY-nOffsetY);

	for(int i=1; i<nCount; i++)
	{
		dbData		= m_dataGraph.ElementAt(i);
		nOffsetX	= int(nCoordWith*(i+1)/nRangX);
		nOffsetY	= int(nCoordHeight*dbData/nRangY);

		pDC->LineTo(nOriginX+nOffsetX, nOriginY-nOffsetY);
	}
	pDC->SelectObject(pOldPen);
	GetClientRect(rectView);
	rgnView.CreateRectRgnIndirect(rectView);
	pDC->SelectObject(rgnView);
}

BEGIN_MESSAGE_MAP(CGraphView, CWnd)
	ON_WM_PAINT()
END_MESSAGE_MAP()

// CGraphView 消息处理程序

void CGraphView::PreSubclassWindow()
{
	CWnd::PreSubclassWindow();

	SetViewFont(_T("宋体"), 12, FW_NORMAL);
}

void CGraphView::OnPaint()
{
	CPaintDC	dc(this);
	int			nMode;
	CRect		rectClient, rectCoord, rectInfo, rectTemp;
	CString		strCaption, strOutputInfo;
	CBitmap		bitmapTemp, *pOldBitmap;
	CFont*		pOldFont;
	CDC*		pMemDC		= new CDC;

	//获取控件信息
	GetClientRect(rectClient);
	GetWindowText(strCaption);

	//创建位图内存
	bitmapTemp.CreateCompatibleBitmap(&dc, rectClient.Width(), rectClient.Height());
	pMemDC->CreateCompatibleDC(&dc);
	pOldBitmap	= pMemDC->SelectObject(&bitmapTemp);
	pOldFont	= pMemDC->SelectObject(&m_fontView);
	nMode		= pMemDC->SetBkMode(TRANSPARENT);

	//填充客户区
	pMemDC->FillSolidRect(&rectClient, GetSysColor(COLOR_BTNFACE));
	//绘制视图标题
	pMemDC->DrawText(strCaption, strCaption.GetLength(), rectClient, DT_CENTER);
	//绘制坐标框
	rectCoord.SetRect(rectClient.left+m_nMarginLeft, rectClient.top+m_nMarginTop, rectClient.right-m_nMarginRight, rectClient.bottom-m_nMarginBottom);
	DrawCoordinate(pMemDC, rectCoord);
	//绘制波形
	DrawGraphy(pMemDC, rectCoord);

	dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), pMemDC, 0, 0, SRCCOPY);

	pMemDC->SetBkMode(nMode);
	pMemDC->SelectObject(pOldFont);
	pMemDC->SelectObject(pOldBitmap);
	ReleaseDC(pMemDC);
	delete	pMemDC;
}
注:这个代码是下载的,具体哪个地方我自己都搞忘了。侵权请联系。

猜你喜欢

转载自blog.csdn.net/qq_39524140/article/details/81053187