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;
}
注:这个代码是下载的,具体哪个地方我自己都搞忘了。侵权请联系。