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); }