www.pudn.com > PressMonitor_q.zip > 3DMeterCtrl.cpp
// 3DMeterCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "math.h"
#include "3DMeterCtrl.h"
#include "MemDC.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// C3DMeterCtrl
C3DMeterCtrl::C3DMeterCtrl()
{
m_dCurrentValue = 0.0 ;
m_dMaxValue = 35.0 ;
m_dMinValue = 0.0 ;
m_nScaleHeight = 12;
m_nUnitHeight = 24;
m_nValueHeight = 14;
m_nScaleDecimals = 0 ;
m_nValueDecimals = 1 ;
m_nFrameWidth=2;
m_strUnits.Format("MPa") ;
m_crRuler = GetSysColor(COLOR_WINDOW) ;
m_crNeedle = RGB(255, 0, 0) ;
m_crSectorStart = RGB(0 ,0,255) ;
m_crSectorMiddle = RGB(0, 255,0) ;
m_crSectorEnd = RGB(255, 0, 0) ;
m_crSectorFrame = RGB(0 ,64,128) ;
m_crFrame = GetSysColor(COLOR_BTNFACE);
m_crUnits = RGB(0,0,0);
m_crValueBack = GetSysColor(COLOR_BTNTEXT);
m_crValue = RGB(255,255,0);//GetSysColor(COLOR_WINDOWTEXT);
m_crScale = GetSysColor(COLOR_WINDOW);
m_crMeterFace = RGB(64,128,128);//RGB(129,170,240);
m_crMeterBack = RGB(64,128,128) ;
// get the relevant system crs
m_crWindow = GetSysColor(COLOR_WINDOW) ;
m_crButton = GetSysColor(COLOR_BTNFACE) ;
m_crShadow = GetSysColor(COLOR_3DSHADOW) ;
m_crDkShadow = GetSysColor(COLOR_3DDKSHADOW);
m_crLight = GetSysColor(COLOR_3DLIGHT);
m_crHighlight = GetSysColor(COLOR_3DHIGHLIGHT) ;
m_crText = GetSysColor(COLOR_BTNTEXT) ;
}
C3DMeterCtrl::~C3DMeterCtrl()
{
if ((m_pBitmapOldBackground) &&
(m_bitmapBackground.GetSafeHandle()) &&
(m_dcBackground.GetSafeHdc()))
{
m_dcBackground.SelectObject(m_pBitmapOldBackground);
m_dcBackground.DeleteDC() ;
m_bitmapBackground.DeleteObject();
}
}
BEGIN_MESSAGE_MAP(C3DMeterCtrl, CStatic)
//{{AFX_MSG_MAP(C3DMeterCtrl)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// C3DMeterCtrl message handlers
class CRotPoint : public CPoint
{
public:
CRotPoint() : CPoint() {};
CRotPoint(int xPos, int yPos) : CPoint(xPos, yPos) {};
void Rotate(double Radians);
double Angle();
};
#define M_PI 3.1415926535897932384626433832795
#define ABS(a) ( ((a)>0)?(a):(-(a)) )
double CRotPoint::Angle()
{
if (x == 0)
return y >= 0 ? M_PI/2 : -M_PI/2;
double AngleRad = atan2((double)y, (double)x);
if (AngleRad < 0)
AngleRad += M_PI*2;
return AngleRad;
}
void CRotPoint::Rotate(double Radians)
{
double StartAngle, EndAngle, Length;
StartAngle = Angle();
EndAngle = StartAngle + Radians;
Length = sqrt((double)x*(double)x + (double)y*(double)y);
x = (long)(Length * cos(EndAngle) + 0.5);
y = (long)(Length * sin(EndAngle) + 0.5);
}
BOOL C3DMeterCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
}
void C3DMeterCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// Find out how big we are
GetClientRect (&m_rectCtrl) ;
/*
CDC memDC;
CBitmap Bitmap;
memDC.CreateCompatibleDC(&dc) ;
Bitmap.CreateCompatibleBitmap(&dc, m_rectCtrl.Width(), m_rectCtrl.Height()) ;
CBitmap *pOldBitmap=memDC.SelectObject(&Bitmap) ;
*/
// make a memory dc
CMemDC memDC(&dc, &m_rectCtrl);
// set up a memory dc for the background stuff
// if one isn't being used
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) ;
// Fill this bitmap with the background.
// Note: This requires some serious drawing and calculating,
// therefore it is drawn "once" to a bitmap and
// the bitmap is stored and blt'd when needed.
DrawFrame(&m_dcBackground);
DrawRuler(&m_dcBackground);
DrawColorCirque(&m_dcBackground);
DrawScale(&m_dcBackground);
DrawUnit(&m_dcBackground);
}
// drop in the background
memDC.BitBlt(0, 0, m_rectCtrl.Width(), m_rectCtrl.Height(),
&m_dcBackground, 0, 0, SRCCOPY) ;
/*
DrawFrame(&memDC);
DrawRuler(&memDC);
DrawColorCirque(&memDC);
DrawScale(&memDC);
DrawUnit(&memDC);
*/
// add the value to the background
DrawValue(&memDC) ;
// add the needle to the background
DrawNeedle(&memDC) ;
/*
dc.BitBlt(0, 0, m_rectCtrl.Width(), m_rectCtrl.Height(),
&memDC, 0, 0, SRCCOPY) ;
memDC.SelectObject(pOldBitmap) ;
*/
}
void C3DMeterCtrl::DrawValue(CDC *pDC)
{
CString strTemp ;
CFont fontUse,*pFontOld ;
fontUse.CreateFont (m_nValueHeight, 0, 0, 0, 300,
FALSE, FALSE, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_SWISS, "Times New Roman") ;
pFontOld = pDC->SelectObject(&fontUse) ;
int nMode=pDC->SetBkMode(TRANSPARENT);
// set the crs based on the system crs
pDC->SetTextColor(m_crValue) ;
// draw the text in the recessed rectangle
strTemp.Format("%.*f", m_nValueDecimals, m_dCurrentValue) ;
pDC->DrawText(strTemp,m_rectValue,DT_CENTER|DT_VCENTER|DT_SINGLELINE) ;
// restore the color and the font
pDC->SelectObject(pFontOld) ;
pDC->SetBkMode(nMode);
}
void C3DMeterCtrl::UpdateNeedle(double dValue)
{
m_dCurrentValue = dValue ;
Invalidate() ;
}
void C3DMeterCtrl::DrawNeedle(CDC *pDC)
{
// create a pen and brush based on the needle color
CPen penAxes,*pPenOld;
penAxes.CreatePen(PS_SOLID,1,m_crText);
CBrush brushShadow,brushNeedle;
brushShadow.CreateSolidBrush(RGB(255,0,0)) ;
brushNeedle.CreateSolidBrush(m_crNeedle) ;
double dAngleRad ;
CRect rectAxes(m_nMeterCX-3,m_nMeterCY-3,m_nMeterCX+3,m_nMeterCY+3);
static CRotPoint North[] =
{
CRotPoint(-8,1),
CRotPoint(-7,3),
CRotPoint(-5,5),
CRotPoint(-4,7),
CRotPoint(-2,7),
CRotPoint(-1,8),
CRotPoint(1,8),
CRotPoint(2,7),
CRotPoint(4,7),
CRotPoint(5,5),
CRotPoint(7,3),
CRotPoint(8,1),
CRotPoint(0,-m_nBottomRadius),
};
#define NORTH_LEN (sizeof(North)/sizeof(North[0]))
CRotPoint pointNeedle[NORTH_LEN];
// calculate the angle for the tip of the needle
dAngleRad = (m_dCurrentValue-m_dMinValue)*(m_dEndAngleRad-m_dStartAngleRad)/
(m_dMaxValue-m_dMinValue) ;
// if the angle is beyond the meter, draw the needle
// at the limit (as if it is "pegged")
if(m_dCurrentValuem_dMaxValue)
dAngleRad=m_dEndAngleRad-m_dStartAngleRad;
#define SHADOW_OFFSET 1
int i;
//
// Draw the shadow
//
for (i = 0; i < NORTH_LEN; i++)
{
pointNeedle[i] = North[i];
pointNeedle[i].Rotate(m_dEndAngleRad+dAngleRad);
pointNeedle[i].Offset(m_nMeterCX+SHADOW_OFFSET, m_nMeterCY+SHADOW_OFFSET);
}
{
CRgn NeedleRgn;
NeedleRgn.CreatePolygonRgn(pointNeedle, NORTH_LEN, ALTERNATE);
pDC->FillRgn(&NeedleRgn, &brushShadow);
}
// draw the needle
for (i = 0; i < NORTH_LEN; i++)
{
pointNeedle[i] = North[i];
pointNeedle[i].Rotate(m_dEndAngleRad+dAngleRad);
pointNeedle[i].Offset(m_nMeterCX-1, m_nMeterCY-1);
}
{
CRgn NeedleRgn;
NeedleRgn.CreatePolygonRgn(pointNeedle, NORTH_LEN, ALTERNATE);
pDC->FillRgn(&NeedleRgn, &brushNeedle);
}
pPenOld=pDC->SelectObject(&penAxes);
pDC->Ellipse(rectAxes);
pDC->SelectObject(pPenOld);
}
void C3DMeterCtrl::OnSize(UINT nType, int cx, int cy)
{
CStatic::OnSize(nType, cx, cy);
ReconstructControl() ;
}
void C3DMeterCtrl::ReconstructControl()
{
// if we've got a stored background - remove it!
if ((m_pBitmapOldBackground) &&
(m_bitmapBackground.GetSafeHandle()) &&
(m_dcBackground.GetSafeHdc()))
{
m_dcBackground.SelectObject(m_pBitmapOldBackground);
m_dcBackground.DeleteDC() ;
m_bitmapBackground.DeleteObject();
m_bitmapBackground.Detach();
}
Invalidate () ;
}
void C3DMeterCtrl::SetRange(double dMin, double dMax)
{
m_dMaxValue = dMax ;
m_dMinValue = dMin ;
ReconstructControl() ;
}
void C3DMeterCtrl::SetScaleDecimals(int nDecimals)
{
m_nScaleDecimals = nDecimals ;
ReconstructControl() ;
}
void C3DMeterCtrl::SetValueDecimals(int nDecimals)
{
m_nValueDecimals = nDecimals ;
ReconstructControl() ;
}
void C3DMeterCtrl::SetUnits(CString &strUnits)
{
m_strUnits = strUnits ;
ReconstructControl() ;
}
void C3DMeterCtrl::SetNeedleColor (COLORREF crNeedle)
{
m_crNeedle = crNeedle ;
ReconstructControl() ;
}
void C3DMeterCtrl::DrawFrame(CDC *pDC)
{
CPen penFrame,penHighlight,penDkShadow,*pPenOld;
penFrame.CreatePen(PS_SOLID, m_nFrameWidth*2,m_crFrame) ;
penHighlight.CreatePen(PS_SOLID, 1, m_crHighlight) ;
penDkShadow.CreatePen(PS_SOLID, 1, m_crDkShadow) ;
CBrush brushBack,*pBrushOld;
brushBack.CreateSolidBrush(m_crMeterBack) ;
// »Íâ±ß¿ò
pPenOld = pDC->SelectObject(&penFrame) ;
pBrushOld = pDC->SelectObject(&brushBack) ;
pDC->Rectangle(m_rectCtrl) ;
/*
// draw the left and top sides with the highlight
pDC->SelectObject(&penHighlight) ;
pDC->MoveTo(m_rectCtrl.left, m_rectCtrl.bottom) ;
pDC->LineTo(m_rectCtrl.left, m_rectCtrl.top) ;
pDC->LineTo(m_rectCtrl.right-1, m_rectCtrl.top) ;
// draw the right and bottom sides with the shadow
pDC->SelectObject(&penDkShadow) ;
pDC->LineTo(m_rectCtrl.right-1, m_rectCtrl.bottom-1) ;
pDC->LineTo(m_rectCtrl.left, m_rectCtrl.bottom-1) ;
*/
// draw the left and top sides with the shadow
pDC->SelectObject(&penDkShadow) ;
pDC->MoveTo(m_rectPane.left, m_rectPane.bottom) ;
pDC->LineTo(m_rectPane.left, m_rectPane.top) ;
pDC->LineTo(m_rectPane.right-1, m_rectPane.top) ;
// draw the right and bottom sides with the highlight
pDC->SelectObject(&penHighlight) ;
pDC->LineTo(m_rectPane.right-1, m_rectPane.bottom-1) ;
pDC->LineTo(m_rectPane.left, m_rectPane.bottom-1) ;
pDC->SelectObject(pPenOld);
pDC->SelectObject(pBrushOld);
}
void C3DMeterCtrl::DrawRuler(CDC *pDC)
{
CPen penRuler1,penRuler2,penRuler3,*pPenOld;
penRuler1.CreatePen(PS_SOLID, 4, m_crRuler) ;
penRuler2.CreatePen(PS_SOLID, 2, m_crRuler) ;
penRuler3.CreatePen(PS_SOLID, 1, m_crRuler) ;
CRect rectTemp;
double dX,dY,dX1,dY1;
int nAngleDeg;
double dAngleRad;
double dRadPerDeg = 4.0*atan(1.0)/180.0 ;
int nRadius=m_nBottomRadius-10;
////////////////////////////////////////////»ÄÚȦ
pPenOld=pDC->SelectObject(&penRuler1) ;
rectTemp.left=m_nMeterCX-nRadius;
rectTemp.right=m_nMeterCX+nRadius;
rectTemp.top=m_nMeterCY-nRadius;
rectTemp.bottom=m_nMeterCY+nRadius;
dX=m_nMeterCX+nRadius*cos(m_dStartAngleRad);
dY=m_nMeterCY-nRadius*sin(m_dStartAngleRad);
dX1=m_nMeterCX+nRadius*cos(m_dEndAngleRad);
dY1=m_nMeterCY-nRadius*sin(m_dEndAngleRad);
pDC->MoveTo(CPoint(ROUND(dX),ROUND(dY)));
pDC->Arc(rectTemp,CPoint(ROUND(dX),ROUND(dY)),CPoint(ROUND(dX1),ROUND(dY1) ));
//draw ruler
pDC->SelectObject(&penRuler2) ;
for (nAngleDeg=m_nStartAngleDeg; nAngleDeg<=m_nEndAngleDeg; nAngleDeg+=m_nTickAngleDeg)
{
// move to the top of the tick mark
dX = m_nMeterCX + nRadius*cos(nAngleDeg*dRadPerDeg) ;
dY = m_nMeterCY - nRadius*sin(nAngleDeg*dRadPerDeg) ;
pDC->MoveTo(ROUND(dX), ROUND(dY)) ;
// move to the bottom of the tick mark
dX = m_nMeterCX + (nRadius+10)*cos(nAngleDeg*dRadPerDeg) ;
dY = m_nMeterCY - (nRadius+10)*sin(nAngleDeg*dRadPerDeg) ;
pDC->LineTo(ROUND(dX), ROUND(dY)) ;
}
pDC->SelectObject(&penRuler3) ;
for (dAngleRad=m_dStartAngleRad; dAngleRad<=m_dEndAngleRad; dAngleRad+=m_dTickAngleRad/10)
{
// move to the top of the tick mark
dX = m_nMeterCX + (nRadius+4)*cos(dAngleRad) ;
dY = m_nMeterCY - (nRadius+4)*sin(dAngleRad) ;
pDC->MoveTo(ROUND(dX), ROUND(dY)) ;
// move to the bottom of the tick mark
dX = m_nMeterCX + (nRadius+8)*cos(dAngleRad) ;
dY = m_nMeterCY - (nRadius+8)*sin(dAngleRad) ;
pDC->LineTo(ROUND(dX), ROUND(dY)) ;
}
pDC->SelectObject(pPenOld);
}
void C3DMeterCtrl::DrawScale(CDC *pDC)
{
int nAngleDeg,i;
double dRadPerDeg = 4.0*atan(1.0)/180.0 ;
double dTemp;
double dX,dY;
CString strTemp;
int nRadius=m_nBottomRadius-30;
//draw scale
CFont fontUse,*pFontOld;
fontUse.CreateFont (m_nScaleHeight, 0, 0, 0, 600,
FALSE, FALSE, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_SWISS, "Times New Roman") ;
pFontOld=pDC->SelectObject(&fontUse) ;
int nMode=pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(m_crScale) ;
for (nAngleDeg=m_nStartAngleDeg; nAngleDeg<=m_nEndAngleDeg; nAngleDeg+=2*m_nTickAngleDeg)
{
dTemp=m_dMaxValue-(nAngleDeg-m_nStartAngleDeg)*(m_dMaxValue-m_dMinValue)/(m_nEndAngleDeg-m_nStartAngleDeg);
strTemp.Format("%.*f",m_nScaleDecimals,dTemp);
i=(nAngleDeg-m_nStartAngleDeg)/(2*m_nTickAngleDeg);
switch(i)
{
case 0:
dX = m_nMeterCX + (nRadius)*cos(nAngleDeg*dRadPerDeg) ;
dY = m_nMeterCY - (nRadius)*sin(nAngleDeg*dRadPerDeg) ;
break;
case 1:
dX = m_nMeterCX + (nRadius)*cos(nAngleDeg*dRadPerDeg) ;
dY = m_nMeterCY - (nRadius)*sin(nAngleDeg*dRadPerDeg)-m_nScaleHeight/2 ;
break;
case 2:
dX = m_nMeterCX + (nRadius)*cos(nAngleDeg*dRadPerDeg) ;
dY = m_nMeterCY - (nRadius)*sin(nAngleDeg*dRadPerDeg)-m_nScaleHeight ;
break;
case 3:
dX = m_nMeterCX + (nRadius)*cos(nAngleDeg*dRadPerDeg)-m_nScaleHeight ;
dY = m_nMeterCY - (nRadius)*sin(nAngleDeg*dRadPerDeg)-m_nScaleHeight ;
break;
case 4:
dX = m_nMeterCX + (nRadius)*cos(nAngleDeg*dRadPerDeg)-m_nScaleHeight ;
dY = m_nMeterCY - (nRadius)*sin(nAngleDeg*dRadPerDeg)-m_nScaleHeight/2;
break;
case 5:
dX = m_nMeterCX + (nRadius)*cos(nAngleDeg*dRadPerDeg)-m_nScaleHeight ;
dY = m_nMeterCY - (nRadius)*sin(nAngleDeg*dRadPerDeg) ;
break;
}
pDC->TextOut(ROUND(dX),ROUND(dY),strTemp) ;
}
pDC->SelectObject(pFontOld) ;
pDC->SetBkMode(nMode);
}
void C3DMeterCtrl::DrawUnit(CDC *pDC)
{
//draw unit//////////////////////////////////////
// determine the font size
CFont fontUse,*pFontOld;
fontUse.CreateFont (m_nUnitHeight, 0, 0, 0, 400,
FALSE, FALSE, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_SWISS, "Monotype Corsiva") ;
pFontOld=pDC->SelectObject(&fontUse) ;
int nMode=pDC->SetBkMode(TRANSPARENT);
// set the colors (based on system colors)
pDC->SetTextColor(m_crUnits) ;
// draw the units below the meter face
pDC->SetTextAlign(TA_CENTER|TA_BASELINE) ;
pDC->TextOut(m_nMeterCX, m_nMeterCY - m_nBottomRadius/4,m_strUnits) ;
pDC->SelectObject(pFontOld);
pDC->SetBkMode(nMode);
}
BOOL C3DMeterCtrl::ReCalculating()
{
double dRadPerDeg ;
GetClientRect(&m_rectCtrl);
// determine the centerpoint of the radii for
// the meter face.
m_nMeterCX = m_rectCtrl.left+m_rectCtrl.Width()/2 ;
m_nMeterCY = m_rectCtrl.top+m_rectCtrl.Height()*35/64 ;
// determine the radii for the top of the meter
// and the bottom of the meter
m_nTopRadius = m_rectCtrl.Width()*17/36 ;
m_nBottomRadius = m_nTopRadius*14/15 ;
// Radians per Degree
// This helps me lay things out in degrees
// which are more intuitive than radians.
dRadPerDeg = 4.0*atan(1.0)/180.0 ;
// set the left and right limits for the meter face
m_nStartAngleDeg = -45 ;
m_nEndAngleDeg = 225 ;
m_nTickAngleDeg = 27 ;
// this is the density of points along the arcs
// convert these to radians
// for computer (rather than human) use!
m_dStartAngleRad = m_nStartAngleDeg*dRadPerDeg ;
m_dEndAngleRad = m_nEndAngleDeg*dRadPerDeg ;
m_dTickAngleRad = m_nTickAngleDeg*dRadPerDeg ;
m_rectPane=m_rectCtrl;
m_rectPane.DeflateRect(m_nFrameWidth,m_nFrameWidth,m_nFrameWidth,m_nFrameWidth);
m_rectValue.left = m_nMeterCX - m_rectCtrl.Width()*10/64 ;
m_rectValue.right = m_nMeterCX + m_rectCtrl.Width()*10/64 ;
m_rectValue.top = m_nMeterCY + m_rectCtrl.Height()*1/8 ;
m_rectValue.bottom = m_nMeterCY + m_rectCtrl.Height()*2/8;
m_nScaleHeight=(int)(m_nBottomRadius*0.24) ;
m_nUnitHeight=(int)(m_nBottomRadius*0.35) ;
m_nValueHeight=(int)(m_rectValue.Height()) ;
return TRUE;
}
BOOL C3DMeterCtrl::Initialize()
{
CString strTemp;
SetRange(0,35);
strTemp.Format("MPa");
SetUnits(strTemp);
return ReCalculating();
}
void C3DMeterCtrl::DrawColorCirque(CDC *pDC)
{
int nRad;
nRad=(m_nTopRadius+m_nBottomRadius)/2;
PaintGradiantCirque(pDC,m_nTopRadius,nRad,m_crSectorStart,RGB(255,255,255),false);
PaintGradiantCirque(pDC,nRad,m_nBottomRadius,m_crSectorStart,RGB(255,255,255),true);
}
void C3DMeterCtrl::PaintGradiantCirque(CDC *pDC, int nRadTop, int nRadBottom, COLORREF clrFrom, COLORREF clrTo,BOOL ascend )
{
int x,y,x1,y1;
CRect rectTemp;
int nRadius;
int radCap = nRadTop - nRadBottom;
// Get the intensity values for the ending color
int r1 = GetRValue(clrTo); // red
int g1 = GetGValue(clrTo); // green
int b1 = GetBValue(clrTo); // blue
// Get the intensity values for the begining color
int r2 = GetRValue(clrFrom); // red
int g2 = GetGValue(clrFrom); // green
int b2 = GetBValue(clrFrom); // blue
int r, g, b;
int rad = radCap;
int w = radCap; // radius of area to shade
int radDelta= 1; // radius of one shade band
while (rad >= 0)
{
if (r1 > r2)
r = r1 - (r1-r2)*(w-rad)/w;
else
r = r1 + (r2-r1)*(w-rad)/w;
if (g1 > g2)
g = g1 - (g1-g2)*(w-rad)/w;
else
g = g1 + (g2-g1)*(w-rad)/w;
if (b1 > b2)
b = b1 - (b1-b2)*(w-rad)/w;
else
b = b1 + (b2-b1)*(w-rad)/w;
if(ascend) // Paint from left to right;
nRadius=nRadBottom+rad;
else // Paint from right to left;
nRadius=nRadTop-rad;
rectTemp.left=m_nMeterCX-nRadius;
rectTemp.right=m_nMeterCX+nRadius;
rectTemp.top=m_nMeterCY-nRadius;
rectTemp.bottom=m_nMeterCY+nRadius;
x=m_nMeterCX+(int)(nRadius*cos(m_dStartAngleRad));
y=m_nMeterCY-(int)(nRadius*sin(m_dStartAngleRad));
x1=m_nMeterCX+(int)(nRadius*cos(m_dEndAngleRad));
y1=m_nMeterCY-(int)(nRadius*sin(m_dEndAngleRad));
DrawArc(pDC,rectTemp,CPoint(x,y),CPoint(x1,y1),RGB(r,g,b));
rad -= radDelta;
}
}
void C3DMeterCtrl::DrawArc(CDC *pDC, CRect& rect, CPoint ptStart, CPoint ptEnd,COLORREF clr)
{
CPen penArc,*pPenOld;
penArc.CreatePen(PS_SOLID,1,clr);
pPenOld=pDC->SelectObject(&penArc);
pDC->MoveTo(ptStart.x,ptStart.y);
pDC->Arc(rect,ptStart,ptEnd);
pDC->SelectObject(pPenOld);
}