C++制作电压表电流表仪表盘(vs2008)

Meter类

Meter.h

#if !defined(AFX_METER_H__D5802279_6502_4453_BE21_58604877AD39__INCLUDED_)
#define AFX_METER_H__D5802279_6502_4453_BE21_58604877AD39__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Meter.h : header file
//

#ifndef ROUND
#define ROUND(x) (int)((x) + 0.5 - (double)((x) < 0))
#endif

#define BOUNDARY_POINTS 200
#define TABNUM 6
/
// CMeter window

class CMeter : public CStatic
{
// Construction
public:
    CMeter();

// Attributes
public:

// Operations
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMeter)
    protected:
    //}}AFX_VIRTUAL

// Implementation
public:
    void SetAngleRange(int nStartAngleDeg, int nEndAngleDeg);
    int m_nTabNum;
    void SetSubTicks(int nSubTicks);
    void SetTicks(int nTicks);
    void DrawValue(CDC *pDC);
    void SetColorTick(BOOL bColorTick = FALSE);
    BOOL m_bColorTick;
    void DrawNode(CDC *pDC);
    COLORREF m_colorTable[6];
    void SetValueDecimals(int nDecimals);
    void SetUnits(CString &strUnits);
    CString m_strUnits;
    int m_nValueDecimals;
    void SetScaleDecimals(int nDecimals);
    void SetRange(double dMin, double dMax);
    void SetNeedleColor (COLORREF colorNeedle);
    void UpdateNeedle(double dValue);
    COLORREF m_colorNeedle;
    int m_nScaleDecimals;
    
    double m_dCurrentValue;
    double m_dMaxValue;
    double m_dMinValue;

    void DrawNeedle(CDC *pDC);
    void ReconstructControl();
    void DrawMeterBackground(CDC *pDC, CRect &rect);
    int m_nStartAngleDeg;    // 仪表盘圆弧起始角度
    int m_nEndAngleDeg;        // 仪表盘圆弧终止角度
    int m_nTicks;            // 刻度数
    int m_nSubTicks;        // 分刻度数
    virtual ~CMeter();

    // Generated message map functions
protected:
    double m_dLeftAngleRad;
    double m_dRightAngleRad;
    int m_nCenterRadius;
    
    CRect m_rectCtrl;            // 控件区域
    CRect m_rectValue;            // 显示数值区域
    CRgn m_rgnBoundary;

    CBitmap *m_pBitmapOldBackground ;
    CBitmap m_bitmapBackground ;
    CDC m_dcBackground;

    CPoint m_ptMeterCenter;        // 仪表中心
    CPoint m_pointBoundary[BOUNDARY_POINTS]; // 边界点,用于绘制刻度

    CFont m_font;            // 显示文字字体

    COLORREF m_colorWindow;        // 背景色
    COLORREF m_colorHighlight;    
    COLORREF m_colorShadow;
    COLORREF m_colorButton;
    COLORREF m_colorText;        // 显示文本颜色

    int m_nRadiusFrame;            // 仪表盘边框半径
    //{{AFX_MSG(CMeter)
    afx_msg void OnPaint();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_METER_H__D5802279_6502_4453_BE21_58604877AD39__INCLUDED_)

 

Meter.cpp

// Meter.cpp : implementation file
//

#include "stdafx.h" 
#include "Meter.h"
#include "math.h"
#include "MemDCEx.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define PT_NUM 50
/
// CMeter

CMeter::CMeter()
{
    m_nStartAngleDeg = 225;
    m_nEndAngleDeg = 315;
    m_nTicks = 10;
    m_nSubTicks = 5;
    m_dMaxValue = 100.0;
    m_dMinValue = 0.0;
    m_dCurrentValue = 00.0;
    m_nScaleDecimals = 0;
    m_nValueDecimals = 1;
    m_colorNeedle = RGB(255, 0, 0);
    m_strUnits = _T("(KV)");
    m_bColorTick = FALSE;
    
    // 颜色表格
    m_colorTable[0] = RGB(177,255,99);
    m_colorTable[1] = RGB(0, 255,0);
    m_colorTable[2] = RGB(0,123,0);
    m_colorTable[3] = RGB(230,248, 38);
    m_colorTable[4] = RGB(253, 138, 29);
    m_colorTable[5] = RGB(255, 0, 0);
}

CMeter::~CMeter()
{
}


BEGIN_MESSAGE_MAP(CMeter, CStatic)
    //{{AFX_MSG_MAP(CMeter)
    ON_WM_PAINT()
    ON_WM_SIZE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMeter message handlers

void CMeter::OnPaint() 
{
    CPaintDC dc(this); // device context for painting

    // 获得控件区域
    GetClientRect (&m_rectCtrl);

    CMemDCEx memDC(&dc, &m_rectCtrl);

    // 选取圆盘边框半径
    m_nRadiusFrame = max(m_rectCtrl.Height(), m_rectCtrl.Width())*9/21;

    // 获得仪表盘中心点
    m_ptMeterCenter = m_rectCtrl.CenterPoint();
    m_ptMeterCenter.y += m_nRadiusFrame/10;
    
    //绘制仪表盘
    if(m_dcBackground.GetSafeHdc()== NULL|| (m_bitmapBackground.m_hObject == NULL))
    {
        m_dcBackground.CreateCompatibleDC(&dc);
        m_bitmapBackground.CreateCompatibleBitmap(&dc, m_rectCtrl.Width(),                                                                                     m_rectCtrl.Height()) ;
        m_pBitmapOldBackground = m_dcBackground.SelectObject(&m_bitmapBackground) ;
        DrawMeterBackground(&m_dcBackground, m_rectCtrl);

    }
    memDC.BitBlt(0, 0, m_rectCtrl.Width(), m_rectCtrl.Height(), 
                       &m_dcBackground, 0, 0, SRCCOPY) ;

    // 绘制指针
    DrawNeedle(&memDC);

    DrawNode(&memDC);

    DrawValue(&memDC);
    // Do not call CStatic::OnPaint() for painting messages
}

void CMeter::DrawMeterBackground(CDC *pDC, CRect &rect)
{
    int nInnerRadius = m_nRadiusFrame*8/10;    // 内圆弧半径

    m_nCenterRadius = m_nRadiusFrame/20;    // 中心园半径大小

    int nFrame = m_nRadiusFrame/18;            // 边框厚度

    double dstepTickDeg = (360.0+m_nStartAngleDeg-m_nEndAngleDeg)/(m_nTicks*m_nSubTicks);    // 刻度步进角度

    int nSubTickR = nInnerRadius+(m_nRadiusFrame-2*nFrame-nInnerRadius)/2;

    double dDeg = (m_nStartAngleDeg+360.0-m_nEndAngleDeg)/(TABNUM*PT_NUM);
     

    CRect rectPanel,rectInnerPanel;
    CPen penDraw, *pPenOld;
    CFont *pFontOld;
    CBrush brushFill, *pBrushOld;
    POINT ptStart, ptEnd, ptInnerStart, ptInnerEnd;    
    CPoint pointInner[BOUNDARY_POINTS], ptGroup1[PT_NUM*TABNUM+1], ptGroup2[PT_NUM*TABNUM+1];
    CPoint ptRgn[PT_NUM*2+2];
    CPoint pttemp;
    CString strtemp;
    double dRadPerDeg;
    double dTickAngleRad;
    double dTemp;
    int nRef = 0;
    int nTickAngle;    
    int nHeight;    // 字体大小
    double dtempangle;
    
    // 计算起始角终止角弧度
    dRadPerDeg = 4.0*atan(1.0)/180.0;
    m_dLeftAngleRad = (m_nStartAngleDeg-180.0)*dRadPerDeg;
    m_dRightAngleRad = (m_nEndAngleDeg-360.0)*dRadPerDeg;
    
    // 计算圆弧起始终止点及区域
    ptStart.x = m_ptMeterCenter.x-(int)(m_nRadiusFrame*cos(m_dLeftAngleRad));
    ptStart.y = m_ptMeterCenter.y+(int)(m_nRadiusFrame*sin(m_dLeftAngleRad));
    ptEnd.x = m_ptMeterCenter.x+(int)(m_nRadiusFrame*cos(-m_dRightAngleRad));
    ptEnd.y = m_ptMeterCenter.y+(int)(m_nRadiusFrame*sin(-m_dRightAngleRad));
    
    rectPanel.SetRect(m_ptMeterCenter.x-m_nRadiusFrame, m_ptMeterCenter.y-m_nRadiusFrame,
                        m_ptMeterCenter.x+m_nRadiusFrame, m_ptMeterCenter.y+m_nRadiusFrame);
    // 获取点的位置
    for(int i=0; i<=PT_NUM*TABNUM; i++)
    {
        ptGroup1[i].x = m_ptMeterCenter.x + (int)((m_nRadiusFrame-nFrame)*cos((m_nStartAngleDeg-i*dDeg)*dRadPerDeg));
        ptGroup1[i].y = m_ptMeterCenter.y - (int)((m_nRadiusFrame-nFrame)*sin((m_nStartAngleDeg-i*dDeg)*dRadPerDeg));
        ptGroup2[i].x = m_ptMeterCenter.x + (int)(m_nRadiusFrame*8*cos((m_nStartAngleDeg-i*dDeg)*dRadPerDeg)/10);
        ptGroup2[i].y = m_ptMeterCenter.y - (int)(m_nRadiusFrame*8*sin((m_nStartAngleDeg-i*dDeg)*dRadPerDeg)/10);
    }

    // 获取系统颜色;
    m_colorWindow    = GetSysColor(COLOR_WINDOW);
    m_colorButton    = GetSysColor(COLOR_BTNFACE);
    m_colorShadow    = GetSysColor(COLOR_BTNSHADOW);
    m_colorHighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
    m_colorText        = GetSysColor(COLOR_BTNTEXT);
    // 临时使用的颜色
    COLORREF colorCaption, cEdge, cMiddle;
    cMiddle = RGB(255, 255, 255);
    cEdge = RGB(96, 96, 255);

    // 用按钮色绘制背景
    brushFill.DeleteObject();
    brushFill.CreateSolidBrush(m_colorButton);
    pBrushOld = pDC->SelectObject(&brushFill);
    pDC->Rectangle(rect);
    pDC->SelectObject(pBrushOld);

    // 绘制圆盘边框

    for(int iOnBand=nFrame; iOnBand>0; iOnBand--)
    {
        penDraw.DeleteObject();
        colorCaption = RGB((GetRValue(cEdge)-GetRValue(cMiddle))*((float)iOnBand)/nFrame+GetRValue(cMiddle),
            (GetGValue(cEdge)-GetGValue(cMiddle))*((float)iOnBand)/nFrame+GetGValue(cMiddle),
            (GetBValue(cEdge)-GetBValue(cMiddle))*((float)iOnBand)/nFrame+GetBValue(cMiddle));
        penDraw.CreatePen(PS_SOLID, iOnBand*2, colorCaption);
        pPenOld = pDC->SelectObject(&penDraw);
        pDC->Arc(&rectPanel, ptEnd, ptStart);
        pDC->SelectObject(pPenOld);    
    }
    // 绘制内圈
    ptInnerStart.x = m_ptMeterCenter.x-(int)(nInnerRadius*cos(m_dLeftAngleRad));
    ptInnerStart.y = m_ptMeterCenter.y+(int)(nInnerRadius*sin(m_dLeftAngleRad));
    ptInnerEnd.x = m_ptMeterCenter.x+(int)(nInnerRadius*cos(-m_dRightAngleRad));
    ptInnerEnd.y = m_ptMeterCenter.y+(int)(nInnerRadius*sin(-m_dRightAngleRad));
    
    rectInnerPanel.SetRect(m_ptMeterCenter.x-nInnerRadius, m_ptMeterCenter.y-nInnerRadius,
                        m_ptMeterCenter.x+nInnerRadius ,m_ptMeterCenter.y+nInnerRadius);

    penDraw.DeleteObject();
    penDraw.CreatePen(PS_SOLID, 1, RGB(255,255,0));
    pPenOld = pDC->SelectObject(&penDraw);
    pDC->Arc(&rectInnerPanel, ptInnerEnd, ptInnerStart);
    pDC->SelectObject(pPenOld);    
    
    if(m_bColorTick)
    {
        
        // 绘制色彩刻度
        for(int i=0; i<TABNUM; i++)
        {
            //确定区域
            for(int j=0; j<=PT_NUM; j++)
            {
                ptRgn[j] = ptGroup1[i*PT_NUM+j];
                ptRgn[2*PT_NUM+1-j] = ptGroup2[i*PT_NUM+j];
            }
            brushFill.DeleteObject();
            brushFill.CreateSolidBrush(m_colorTable[i]);
            pBrushOld = pDC->SelectObject(&brushFill);
            penDraw.DeleteObject();
            penDraw.CreatePen(PS_SOLID, 1, m_colorTable[i]);
            pPenOld = pDC->SelectObject(&penDraw);
            pDC->Polygon(ptRgn, 2*PT_NUM+2);
            pDC->SelectObject(pBrushOld);
            pDC->SelectObject(pPenOld);
        }
        
    }

    // 计算刻度点,避免不能整除引起较大误差*100
    for(nTickAngle=m_nStartAngleDeg*100; nTickAngle>=(m_nEndAngleDeg-360)*100; nTickAngle-=(int)(dstepTickDeg*100))
    {
        // 转换成弧度
        dTickAngleRad = (double)nTickAngle/100*dRadPerDeg;    
        // 确定外圈坐标
        // 确定x坐标
        dTemp = m_ptMeterCenter.x + (m_nRadiusFrame-2*nFrame)*cos(dTickAngleRad);
        m_pointBoundary[nRef].x = ROUND(dTemp);
        // 确定y坐标
        dTemp = m_ptMeterCenter.y - (m_nRadiusFrame-2*nFrame)*sin(dTickAngleRad);
        m_pointBoundary[nRef].y = ROUND(dTemp);
        
        // 确定刻度点(主刻度和子刻度)
        //主刻度及文本标注点
        if(nRef%m_nSubTicks == 0)
        {
            dTemp = m_ptMeterCenter.x + nInnerRadius*cos(dTickAngleRad);
            pointInner[nRef].x = ROUND(dTemp);
            dTemp = m_ptMeterCenter.y - nInnerRadius*sin(dTickAngleRad);
            pointInner[nRef].y = ROUND(dTemp);
        }
        // 子刻度
        else
        {
            dTemp = m_ptMeterCenter.x + nSubTickR*cos(dTickAngleRad);
            pointInner[nRef].x = ROUND(dTemp);
            dTemp = m_ptMeterCenter.y - nSubTickR*sin(dTickAngleRad);
            pointInner[nRef].y = ROUND(dTemp);
        }
        nRef++ ;
    }
    // 多边形区域
    m_rgnBoundary.DeleteObject() ;
    m_rgnBoundary.CreatePolygonRgn(m_pointBoundary, nRef, ALTERNATE);
    
    m_rectValue.top = m_ptMeterCenter.y + m_nRadiusFrame/5;
    m_rectValue.bottom = m_ptMeterCenter.y + m_nRadiusFrame/2;
    m_rectValue.left = m_ptMeterCenter.x - m_nRadiusFrame/2;
    m_rectValue.right = m_ptMeterCenter.x + m_nRadiusFrame/2;

    // 绘制刻度
    penDraw.DeleteObject();
    penDraw.CreatePen(PS_SOLID, 1, RGB(0,0,0));
    pPenOld = pDC->SelectObject(&penDraw);
    for(int i=0; i<nRef; i++)
    {
        pDC->MoveTo(m_pointBoundary[i]);
        pDC->LineTo(pointInner[i]);
    }
    pDC->SelectObject(pPenOld);    

    // 刻度标号

    nHeight = m_nRadiusFrame/8;  //字体大小
    m_font.CreateFont(nHeight, 0, 0, 0, 550, 
                            FALSE, FALSE, 0, ANSI_CHARSET,
                            OUT_DEFAULT_PRECIS, 
                            CLIP_DEFAULT_PRECIS,
                            DEFAULT_QUALITY, 
                            DEFAULT_PITCH|FF_SWISS, "Arial");

    pFontOld = pDC->SelectObject(&m_font);
    pDC->SetBkMode(TRANSPARENT);
    for(int i=0; i<=m_nTicks; i++)
    {    
        dtempangle = m_nStartAngleDeg-i*m_nSubTicks*dstepTickDeg;
        strtemp.Format("%.*lf", m_nScaleDecimals, (m_dMinValue+(m_dMaxValue-m_dMinValue)*i/m_nTicks));

        if(dtempangle>190)
        {
            pDC->SetTextAlign(TA_BOTTOM|TA_LEFT);
            pDC->TextOut(pointInner[m_nSubTicks*i].x, pointInner[m_nSubTicks*i].y+nHeight/2, strtemp);
        }
        
        else if(dtempangle>170)
        {
            pDC->SetTextAlign(TA_BASELINE|TA_LEFT);
            pDC->TextOut(pointInner[m_nSubTicks*i].x, pointInner[m_nSubTicks*i].y+nHeight/3, strtemp);
        }
        else if(dtempangle>135)
        {
            pDC->SetTextAlign(TA_BASELINE|TA_LEFT);
            pDC->TextOut(pointInner[m_nSubTicks*i].x, pointInner[m_nSubTicks*i].y+nHeight/2, strtemp);
        }
        else if(dtempangle>100)
        {
            pDC->SetTextAlign(TA_TOP|TA_LEFT);
            pDC->TextOut(pointInner[m_nSubTicks*i].x-nHeight/4, pointInner[m_nSubTicks*i].y-nHeight/8, strtemp);
        }

        else if(dtempangle>80)
        {
            pDC->SetTextAlign(TA_TOP|TA_CENTER);
            pDC->TextOut(pointInner[m_nSubTicks*i].x, pointInner[m_nSubTicks*i].y, strtemp);
        }
        else if(dtempangle>45)
        {
            pDC->SetTextAlign(TA_BOTTOM|TA_RIGHT);
            pDC->TextOut(pointInner[m_nSubTicks*i].x+nHeight/3, pointInner[m_nSubTicks*i].y+nHeight, strtemp);
        }
        else if(dtempangle>10)
        {
            pDC->SetTextAlign(TA_RIGHT|TA_BASELINE);
            pDC->TextOut(pointInner[m_nSubTicks*i].x, pointInner[m_nSubTicks*i].y+nHeight/2, strtemp);
        }
        else if(dtempangle>-10)
        {
            pDC->SetTextAlign(TA_RIGHT|TA_BASELINE);
            pDC->TextOut(pointInner[m_nSubTicks*i].x, pointInner[m_nSubTicks*i].y+nHeight/3, strtemp);
        }
        else 
        {
            pDC->SetTextAlign(TA_RIGHT|TA_BOTTOM);
            pDC->TextOut(pointInner[m_nSubTicks*i].x, pointInner[m_nSubTicks*i].y+nHeight/2, strtemp);
        }
    }
    pDC->SelectObject(pFontOld);

}

void CMeter::ReconstructControl()
{
    if ((m_pBitmapOldBackground) && 
          (m_bitmapBackground.GetSafeHandle()) && 
            (m_dcBackground.GetSafeHdc()))
    {
            m_dcBackground.SelectObject(m_pBitmapOldBackground);
            m_dcBackground.DeleteDC() ;
            m_bitmapBackground.DeleteObject();
    }

    Invalidate ();
}

void CMeter::OnSize(UINT nType, int cx, int cy) 
{
    CStatic::OnSize(nType, cx, cy);
    
    // TODO: Add your message handler code here
    ReconstructControl() ;
}

void CMeter::DrawNeedle(CDC *pDC)
{
    int nResult;
    double dRadPerDeg = 4.0*atan(1.0)/180.0;
    double dAngleDeg;
    double dAngleRad ;
    double dTemp ;
    CBrush brushFill, *pBrushOld ;
    CPen penDraw, *pPenOld ;
    CPoint pointNeedle[4] ;    // 指针由四边形组成


    // 计算角度并限定指针走的角度
    dAngleDeg = m_nStartAngleDeg-(360.0+m_nStartAngleDeg-m_nEndAngleDeg)
        *(m_dCurrentValue-m_dMinValue)/(m_dMaxValue-m_dMinValue);
    dAngleDeg = min(dAngleDeg, m_nStartAngleDeg);
    dAngleDeg = max(dAngleDeg, m_nEndAngleDeg-360.0);
    dAngleRad = dAngleDeg*dRadPerDeg;

    // 计算三角形底边两个点
    pointNeedle[0].x = m_ptMeterCenter.x - (int)(m_nCenterRadius*10*sin(dAngleRad)/8);
    pointNeedle[0].y = m_ptMeterCenter.y - (int)(m_nCenterRadius*10*cos(dAngleRad)/8);
    pointNeedle[2].x = m_ptMeterCenter.x + (int)(m_nCenterRadius*10*sin(dAngleRad)/8);
    pointNeedle[2].y = m_ptMeterCenter.y + (int)(m_nCenterRadius*10*cos(dAngleRad)/8);
    
    // 计算指针顶部坐标
    dTemp = m_ptMeterCenter.x + m_nRadiusFrame*cos(dAngleRad)*95/100;
    pointNeedle[1].x = ROUND(dTemp);
    dTemp = m_ptMeterCenter.y - m_nRadiusFrame*sin(dAngleRad)*95/100;
    pointNeedle[1].y = ROUND(dTemp);
    // 计算指针尾部坐标
    dTemp = m_ptMeterCenter.x - m_nRadiusFrame*cos(dAngleRad)/6;
    pointNeedle[3].x = ROUND(dTemp);
    dTemp = m_ptMeterCenter.y + m_nRadiusFrame*sin(dAngleRad)/6;
    pointNeedle[3].y = ROUND(dTemp);

    pDC->SelectClipRgn(&m_rgnBoundary);

    brushFill.CreateSolidBrush(m_colorNeedle);
    penDraw.CreatePen(PS_SOLID, 1, m_colorNeedle);

    pPenOld = pDC->SelectObject(&penDraw) ;
    pBrushOld = pDC->SelectObject(&brushFill) ;

    // 绘制指针
    pDC->Polygon(pointNeedle, 4);

    nResult = pDC->SelectClipRgn(NULL);

    pDC->SelectObject(pPenOld);
    pDC->SelectObject(pBrushOld);

    // 立体感处理
    if(dAngleDeg>90)
    {
        penDraw.DeleteObject();
        penDraw.CreatePen(PS_SOLID, 2, m_colorShadow);
        pPenOld = pDC->SelectObject(&penDraw);
        pDC->MoveTo(pointNeedle[1]);
        pDC->LineTo(pointNeedle[0]);
        pDC->LineTo(pointNeedle[3]);
        pDC->SelectObject(pPenOld);
        
        penDraw.DeleteObject();
        penDraw.CreatePen(PS_SOLID, 1, m_colorHighlight);
        pPenOld = pDC->SelectObject(&penDraw);
        pDC->MoveTo(pointNeedle[1]);
        pDC->LineTo(pointNeedle[2]);
        pDC->LineTo(pointNeedle[3]);
        pDC->SelectObject(pPenOld);
    }
    else
    {
        penDraw.DeleteObject();
        penDraw.CreatePen(PS_SOLID, 2, m_colorShadow);
        pPenOld = pDC->SelectObject(&penDraw);
        pDC->MoveTo(pointNeedle[1]);
        pDC->LineTo(pointNeedle[2]);
        pDC->LineTo(pointNeedle[3]);
        pDC->SelectObject(pPenOld);
        
        penDraw.DeleteObject();
        penDraw.CreatePen(PS_SOLID, 1, m_colorHighlight);
        pPenOld = pDC->SelectObject(&penDraw);
        pDC->MoveTo(pointNeedle[1]);
        pDC->LineTo(pointNeedle[0]);
        pDC->LineTo(pointNeedle[3]);
        pDC->SelectObject(pPenOld);
    }
}

void CMeter::UpdateNeedle(double dValue)
{
    m_dCurrentValue = dValue;
    Invalidate();
}

void CMeter::SetNeedleColor(COLORREF colorNeedle)
{
    m_colorNeedle = colorNeedle ;
    ReconstructControl() ;
}


void CMeter::SetRange(double dMin, double dMax)
{
    m_dMaxValue = dMax ;
    m_dMinValue = dMin ;
    ReconstructControl() ;
}


void CMeter::SetScaleDecimals(int nDecimals)
{
    m_nScaleDecimals = nDecimals ;
    ReconstructControl() ;
}

void CMeter::SetUnits(CString &strUnits)
{
    m_strUnits = strUnits ;
    ReconstructControl() ;
}

void CMeter::SetValueDecimals(int nDecimals)
{
    m_nValueDecimals = nDecimals ;
    ReconstructControl() ;
}

void CMeter::DrawNode(CDC *pDC)
{
    CPen penDraw, *pPenOld;
    COLORREF cEdge, cMiddle, cNode;
    cMiddle = RGB(255, 255, 255);
    cEdge = RGB(0, 0, 0);
    for(int i=m_nCenterRadius*3/4; i>=0; i--)
    {
        cNode = RGB((GetRValue(cEdge)-GetRValue(cMiddle))*((float)i)*4/(3*m_nCenterRadius)+GetRValue(cMiddle),
            (GetGValue(cEdge)-GetGValue(cMiddle))*((float)i)*4/(3*m_nCenterRadius)+GetGValue(cMiddle),
            (GetBValue(cEdge)-GetBValue(cMiddle))*((float)i)*4/(3*m_nCenterRadius)+GetBValue(cMiddle));
    
        penDraw.DeleteObject();
        penDraw.CreatePen(PS_SOLID, 1, cNode);
        pPenOld = pDC->SelectObject(&penDraw);
        pDC->Arc(m_ptMeterCenter.x-i, m_ptMeterCenter.y-i,m_ptMeterCenter.x+i,m_ptMeterCenter.y+i,
            m_ptMeterCenter.x-i,m_ptMeterCenter.y,m_ptMeterCenter.x-i,m_ptMeterCenter.y);
        pDC->SelectObject(pPenOld);
    }
}

void CMeter::SetColorTick(BOOL bColorTick)
{
    m_bColorTick = bColorTick;
    ReconstructControl();
}

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

    //  数值显示
    nHeight = m_nRadiusFrame/4;
    pttemp = m_rectValue.CenterPoint();
    strtemp.Format("%.*lf", m_nValueDecimals, m_dCurrentValue); 
    m_font.DeleteObject() ;
    m_font.CreateFont (nHeight, 0, 0, 0, 550,
                        FALSE, FALSE, 0, ANSI_CHARSET,
                        OUT_DEFAULT_PRECIS, 
                        CLIP_DEFAULT_PRECIS,
                        DEFAULT_QUALITY, 
                        DEFAULT_PITCH|FF_SWISS, "Arial") ;
    pFontOld = pDC->SelectObject(&m_font);
    pDC->SetBkColor(m_colorButton);
    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);
    pDC->SetBkColor(m_colorWindow);
}

void CMeter::SetTicks(int nTicks)
{
    m_nTicks = nTicks;
    ReconstructControl();
}

void CMeter::SetSubTicks(int nSubTicks)
{
    m_nSubTicks = nSubTicks;
    ReconstructControl();
}

void CMeter::SetAngleRange(int nStartAngleDeg, int nEndAngleDeg)
{
    m_nStartAngleDeg = nStartAngleDeg;
    m_nEndAngleDeg = nEndAngleDeg;
    ReconstructControl();
}

 

 

 完整工程下载:https://download.csdn.net/download/qq_23565865/10715458

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值