www.gusucode.com > 虚拟仪表-风向表盘C++源码程序 > 虚拟仪表-风向表盘/wind/wind/WindPicture.cpp

    /***********************************************************************
* Copyright (c) 2010* All rights reserved.* 
* ATTRIBUTE:        一个仪表控件类,用来仿真工业控制现场仪表数据显示等
* FILE NAME:		WindPicture.cpp
* ABSTRACT:			可用于工业控制仿真仪表数据显示等
* CURRENT VERSION:	V1.0
* AUTHOR:			李保成
* CONTECT:			chengbaolee@gmail.com	
* BUILD DATA:		26/11/2010
* COMPLETION DATE:	26/11/2010
* PRE-COMPLETION DATE:	
* NOTE:	            如果您要作为商业用途,请联系作者
***********************************************************************/
#include "stdafx.h"
#include "WindPicture.h"
#include <math.h>
#include "MemDC.h"
#include "Resource.h"
CWindPicture::CWindPicture()
{
    m_angle=0.0;
	m_Point[0].x=0;
    m_Point[0].y=0;
	m_Point[1].x=0;
    m_Point[1].y=0;
	m_Point[2].x=0;
    m_Point[2].y=0;
	m_Point[3].x=0;
    m_Point[3].y=0;
	m_NeedleColor = RGB( 255, 0, 0);
	memset(m_strUnits, 0, sizeof(m_strUnits));
	::strcpy(m_strUnits,"风向");
	m_angle=0;

}
CWindPicture::~CWindPicture()
{
	m_bitmapBackground.DeleteObject();
}

BEGIN_MESSAGE_MAP(CWindPicture, CStatic)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

void CWindPicture::OnPaint()
{
	CPaintDC dc(this); // device context for painting
    GetClientRect(&m_rectCtrl);
    CMemDC memDC(&dc, &m_rectCtrl);

	// 选取圆盘边框半径
	//m_nRadiusFrame = max(m_rectCtrl.Height(), m_rectCtrl.Width())*9/21;
	m_nRadiusFrame=min(m_rectCtrl.Height(),m_rectCtrl.Width());
	// 获得仪表盘中心点
	m_ptMeterCenter = m_rectCtrl.CenterPoint();

    if(m_dcground.GetSafeHdc()== NULL|| (m_bitmapBackground.m_hObject == NULL))
	{
		m_dcground.CreateCompatibleDC(&dc);
		m_bitmapBackground.CreateCompatibleBitmap(&dc, m_rectCtrl.Width(),m_rectCtrl.Height());
		m_pBitmapOldBackground = m_dcground.SelectObject(&m_bitmapBackground);
		DrawMeterBackground(&m_dcground, m_rectCtrl);
	}
	    memDC.BitBlt(0, 0, m_rectCtrl.Width(), m_rectCtrl.Height(), 
		&m_dcground, 0, 0, SRCCOPY) ;

        DrawValue(&memDC);
	 	DrawNeedle(&memDC, m_rectCtrl);

	// 不为绘图消息调用 CStatic::OnPaint()
}
void CWindPicture::DrawMeterBackground(CDC *pDC, CRect &rect)
{
	int nFrame=m_nRadiusFrame/10;
	CPen   PenOut, pPenInner, *pOldPen;
	CBrush m_brushBack, pBackBrush, *pOldBrush;

	m_BackColor=GetSysColor(COLOR_WINDOW);
	m_brushBack.CreateSolidBrush(m_BackColor);
	pOldBrush = (CBrush *)pDC->SelectObject(&m_brushBack);	
	pDC->FillRect(rect, &m_brushBack);   //绘制背景
	//pDC->Rectangle(rect);                //绘制一个边框
	pDC->SelectObject(pOldBrush);
	m_brushBack.DeleteObject();
	m_brushBack.CreateSolidBrush(RGB(255, 255, 255));//圆盘色
	pOldBrush = (CBrush *)pDC->SelectObject(&m_brushBack);	
	PenOut.CreatePen(PS_SOLID, 10, RGB( 0, 0, 255));//外圆色
    pOldPen = (CPen *)pDC->SelectObject(&PenOut);
	CRect rectRound(m_ptMeterCenter.x - m_nRadiusFrame / 2+nFrame, 
		m_ptMeterCenter.y - m_nRadiusFrame / 2+nFrame,
		m_ptMeterCenter.x + m_nRadiusFrame / 2-nFrame, 
		m_ptMeterCenter.y + m_nRadiusFrame / 2-nFrame);
	pDC->Ellipse(rectRound);  
	pDC->SelectObject(pOldPen);
	PenOut.DeleteObject();//外圆
	pPenInner.CreatePen(PS_DOT, 1, RGB( 0, 0, 255));//内圆
	pOldPen = (CPen *)pDC->SelectObject(&pPenInner);
	CRect rectInside(m_ptMeterCenter.x - m_nRadiusFrame / 2+2*nFrame, 
		m_ptMeterCenter.y - m_nRadiusFrame / 2+2*nFrame,
		m_ptMeterCenter.x + m_nRadiusFrame / 2-2*nFrame, 
		m_ptMeterCenter.y + m_nRadiusFrame / 2-2*nFrame);
	pDC->Ellipse(rectInside);  
	pDC->SelectObject(pOldPen);
	PenOut.DeleteObject();
	//画方向标志符
	pDC->SetTextAlign(TA_BOTTOM|TA_LEFT);//north
	pDC->TextOut(m_ptMeterCenter.x-2, m_ptMeterCenter.y-m_nRadiusFrame/2.3, "N");

	pDC->SetTextAlign(TA_BOTTOM|TA_LEFT);//south
	pDC->TextOut(m_ptMeterCenter.x, m_ptMeterCenter.y+m_nRadiusFrame/2.0, "S");

	pDC->SetTextAlign(TA_BOTTOM|TA_RIGHT);//east
	pDC->TextOut(m_ptMeterCenter.x+m_nRadiusFrame/2.0, m_ptMeterCenter.y, "E");

	pDC->SetTextAlign(TA_BOTTOM|TA_LEFT);//west
	pDC->TextOut(m_ptMeterCenter.x-m_nRadiusFrame/2.0, m_ptMeterCenter.y, "W");

}
void CWindPicture::DrawValue(CDC *pDC)
{
	int nHeight;
	CPoint pttemp;
	CString strtemp;
	CFont *pFontOld;

	//  数值显示
	nHeight = m_nRadiusFrame/8;
	m_rectValue.SetRect(m_ptMeterCenter.x-nHeight,m_ptMeterCenter.y+nHeight,m_ptMeterCenter.x+nHeight,m_ptMeterCenter.y-nHeight);
	pttemp = m_rectValue.CenterPoint();
	strtemp.Format("%.*lf",2, m_angle); //2表示两位小数
	m_font.DeleteObject() ;
	m_font.CreateFont (nHeight, 0, 0, 0, 400,
		FALSE, FALSE, 0, ANSI_CHARSET,
		OUT_DEFAULT_PRECIS, 
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, 
		DEFAULT_PITCH|FF_SWISS, "楷体") ;
	pFontOld = pDC->SelectObject(&m_font);
	pDC->SetBkColor(RGB(255,255,255));//GetSysColor(COLOR_BTNFACE)
	pDC->SetTextAlign(TA_TOP|TA_CENTER);
	pDC->TextOut(pttemp.x, pttemp.y, m_strUnits);
	pDC->TextOut(pttemp.x, pttemp.y+nHeight, strtemp);
	// 恢复字体和背景色
	pDC->SelectObject(pFontOld);


}
void CWindPicture::DrawNeedle(CDC *pDC, CRect &rect)
{

	/*m_rgn.DeleteObject ();
    m_rgn.CreatePolygonRgn(m_Point,4,ALTERNATE);*/


	CBrush pNeedleBrush, *pOldBrush;
	CPen penDraw,*pPenOld ;
	pNeedleBrush.CreateSolidBrush(m_NeedleColor);
	pOldBrush = (CBrush *)pDC->SelectObject(&pNeedleBrush);

	CPoint ptRgn[4];
	double radius=m_nRadiusFrame/2.0-m_nRadiusFrame/9.0;//外圆半径
	ptRgn[0].x=m_ptMeterCenter.x-(int)(sin((m_angle+15)/180*3.1415927)*(radius-m_nRadiusFrame/7));
	ptRgn[0].y=m_ptMeterCenter.y-(int)(cos((m_angle+15)/180*3.1415927)*(radius-m_nRadiusFrame/7));
	ptRgn[1].x=m_ptMeterCenter.x-(int)(sin(m_angle/180*3.1415927)*radius);
	ptRgn[1].y=m_ptMeterCenter.y-(int)(cos(m_angle/180*3.1415927)*radius);
	ptRgn[2].x=m_ptMeterCenter.x-(int)(sin((m_angle-15)/180*3.1415927)*(radius-m_nRadiusFrame/7));
	ptRgn[2].y=m_ptMeterCenter.y-(int)(cos((m_angle-15)/180*3.1415927)*(radius-m_nRadiusFrame/7));
	ptRgn[3].x=m_ptMeterCenter.x-(int)(sin(m_angle/180*3.1415927)*(radius-m_nRadiusFrame/13));
	ptRgn[3].y=m_ptMeterCenter.y-(int)(cos(m_angle/180*3.1415927)*(radius-m_nRadiusFrame/13));

    pDC->SetPolyFillMode(/*WINDING*/ALTERNATE);
	pDC->Polygon(ptRgn, 4);
	pDC->SelectObject(pOldBrush);
	pNeedleBrush.DeleteObject();


	//CString strtemp;
	//double radius=m_nRadiusFrame/2.0-m_nRadiusFrame/9.0;
	//for (int i=0;i<8;i++)
	//{
	//		strtemp.Format("%.*lf", 2,i*45);
	//		pDC->SetTextAlign(TA_BOTTOM|TA_LEFT);
	//		pDC->TextOut(m_ptMeterCenter.x-radius*sin((i*45)* PI / 180), m_ptMeterCenter.y+radius*cos((i*45)* PI / 180),strtemp);
	//}

}
void CWindPicture::setAngle(double angle)
{

	m_angle=angle;
    ReconstructControl();
}
void CWindPicture::ReconstructControl()
{
	if ((m_pBitmapOldBackground) && 
		(m_bitmapBackground.GetSafeHandle()) && 
		(m_dcground.GetSafeHdc()))
	{
		m_dcground.SelectObject(m_pBitmapOldBackground);
		m_dcground.DeleteDC() ;
		m_bitmapBackground.DeleteObject();
	}

	Invalidate ();
}

BOOL CWindPicture::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
    return CStatic::OnEraseBkgnd(pDC);
}