?? roundmeter.cpp
字號:
/***********************************************************************
* Copyright (c) 2007* All rights reserved.*
* ATTRIBUTE: 一個儀表控件類,用來仿真工業控制現場儀表數據顯示等
* FILE NAME: RoundMeter.cpp
* FILE ID: SYSTEMCTRL-ROUNDMETER-CPP
* ABSTRACT: 可用于工業控制仿真儀表數據顯示等
* CURRENT VERSION: V1.0
* AUTHOR: 戚高
* CONTECT: successq_g@163.com
* BUILD DATA: 26/12/2007
* COMPLETION DATE: 26/12/2007
* PRE-VERSION: NONE
* PRE-AUTHOR: NONE
* PRE-COMPLETION DATE:
* NOTE: 未經授權請不要作為商業用途,或者如果您要作為商業
用途,請聯系作者
***********************************************************************/
#include "stdafx.h"
#include "RoundMeter.h"
#include <math.h>
#include "MemDC.h"
CRoundMeter::CRoundMeter()
{
m_bMouseDrag = false;
//顏色設置
// m_BackColor = RGB( 33, 177, 138); //背景方框顏色
m_BackColor = RGB( 0, 0, 0); //背景方框顏色
m_BackLineColor=RGB( 0, 0, 0); //背景方框線色
m_NeedleColor=RGB( 0, 0, 0); //指針顏色
m_NeedleLineColor=RGB( 0, 0, 0); //指針線色
m_WarnNeedleColor=RGB( 255, 0, 0); //報警指針顏色
m_WarnNeedleLineColor=RGB( 255, 0, 0); //報警指針線色
m_FirstColor=RGB(182, 182, 182); //第一圈顏色
m_FirstLineColor=RGB( 0, 0, 0); //第一圈線色
m_SecondColor=RGB(182, 182, 182); //第二圈顏色
m_SecondLineColor=RGB(0,0,0); //第二圈線色
m_ThirdColor=RGB(182, 182, 182); //第三圈顏色
m_ThirdLineColor=RGB(0,0,0); //第三圈線色
m_FourthColor=RGB(0,0,0); //第四圈顏色 指針圈1
m_FourthLineColor=RGB(0,0,0); //第四圈線色 指針圈1
m_FifthColor=RGB( 255, 128, 64); //第五圈顏色 指針圈2
m_FifthLineColor=RGB( 255, 128, 64); //第五圈線色 指針圈2
m_TextColor=RGB( 0, 0, 255); //普通字體顏色
m_TextBackColor=RGB(255,255,255); //普通字體底色
m_WarnTextColor=RGB(255,0,0); //報警字體顏色
m_WarnTextBackColor=RGB(255,255,255); //報警字體底色
m_TickColor=RGB(0,0,255); //大格刻度顏色
m_SubTickColor=RGB(0,0,0); //小格刻度顏色
m_dMinValue = 0.00f; //表量程初始值
m_dMaxValue = 1000.00f; //表量程終值
m_WarnMaxValue = 900.0f; //報警上限
m_WarnMinValue = 100.0f; //報警下限
m_nTicks = 5; //大格個數
m_nSubTicks = 5; //大格中小格個數
m_dCurrentValue = 600.00f;
m_nStartAngle = 0;
m_nEndAngle = m_nStartAngle; //兩個角度相等表示全圓表
m_ncnt=0; //遮蔽多邊形點數為零
m_bReset=TRUE; //第一次需要重繪
memset(m_strUnits, 0, sizeof(m_strUnits));
strcpy(m_strUnits, "溫度"); //表單位
// wcscpy(m_strUnits, _T("溫度"));
}
CRoundMeter::~CRoundMeter()
{
}
BEGIN_MESSAGE_MAP(CRoundMeter, CStatic)
//{{AFX_MSG_MAP(CRoundMeter)
ON_WM_PAINT()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CRoundMeter::OnPaint()
{
CPaintDC dc(this);
// 獲得控件區域
GetClientRect (&m_rectCtrl);
CMemDC memDC(&dc, &m_rectCtrl);
//繪制儀表盤
if (m_dcMeterPlate.GetSafeHdc() == NULL || (m_bitmapMeterPlate.m_hObject == NULL))
{
m_dcMeterPlate.CreateCompatibleDC(&dc);
m_bitmapMeterPlate.CreateCompatibleBitmap(&dc, m_rectCtrl.Width(), m_rectCtrl.Height()) ;
m_pbitmapOldMeterPlate = m_dcMeterPlate.SelectObject(&m_bitmapMeterPlate) ;
DrawMeterBackground(&m_dcMeterPlate, m_rectCtrl);
}
memDC.BitBlt(0, 0, m_rectCtrl.Width(), m_rectCtrl.Height(),
&m_dcMeterPlate, 0, 0, SRCCOPY);
DrawNeedle(&memDC, m_rectCtrl);
DrawValue(&memDC, m_rectCtrl);
}
void CRoundMeter::PreSubclassWindow()
{
ModifyStyle(0, BS_NOTIFY);
}
//繪制儀表背景
void CRoundMeter::DrawMeterBackground(CDC *pDC, CRect &rect)
{
CPen pPenThin, *pOldPen;
CBrush m_brushBack, *pOldBrush;
static POINT PtRgn[8];
pDC->SetBkColor(m_BackColor);
m_brushBack.CreateSolidBrush(m_BackColor);
pOldBrush = (CBrush *)pDC->SelectObject(&m_brushBack);
pPenThin.CreatePen(PS_SOLID, 1, m_BackLineColor);
pOldPen = (CPen *)pDC->SelectObject(&pPenThin);
pDC->FillRect(rect, &m_brushBack); //繪制背景
pDC->Rectangle(rect); //繪制一個邊框
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
m_brushBack.DeleteObject();
pPenThin.DeleteObject();
pDC->SetBkMode(TRANSPARENT);
m_ptMeterCenter = rect.CenterPoint(); //點中心坐標
int nRadius = 0;
if (rect.Width() <= rect.Height())
{
nRadius = rect.Width() - 5;
}
else
{
nRadius = rect.Height() - 5;
}
m_nRadiusFrame = nRadius;
//繪制儀表圓盤
m_brushBack.CreateSolidBrush(m_FirstColor); //繪制第一圈
pOldBrush = (CBrush *)pDC->SelectObject(&m_brushBack);
pPenThin.CreatePen(PS_SOLID, 1, m_FirstLineColor);
pOldPen = (CPen *)pDC->SelectObject(&pPenThin);
CRect rectRound(m_ptMeterCenter.x - nRadius / 2,
m_ptMeterCenter.y - nRadius / 2,
m_ptMeterCenter.x + nRadius / 2,
m_ptMeterCenter.y + nRadius / 2);
pDC->Ellipse(rectRound);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
m_brushBack.DeleteObject();
pPenThin.DeleteObject();
if(m_bReset)
{
//計算遮蔽區域
m_ncnt=CalVeilRgn(PtRgn,m_ptMeterCenter,nRadius / 2,m_nStartAngle,m_nEndAngle);
//計算刻度結構
CalAboutTicks(nRadius);
m_bReset=FALSE;
}
m_brushBack.CreateSolidBrush(m_SecondColor); //繪制第二圈
pOldBrush = (CBrush *)pDC->SelectObject(&m_brushBack);
pPenThin.CreatePen(PS_SOLID, 1, m_SecondLineColor);
pOldPen = (CPen *)pDC->SelectObject(&pPenThin);
rectRound.SetRect(m_ptMeterCenter.x - nRadius / 2 + nRadius / 50,
m_ptMeterCenter.y - nRadius / 2 + nRadius / 50,
m_ptMeterCenter.x + nRadius / 2 - nRadius / 50,
m_ptMeterCenter.y + nRadius / 2 - nRadius / 50);
pDC->Ellipse(rectRound);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
m_brushBack.DeleteObject();
pPenThin.DeleteObject();
m_brushBack.CreateSolidBrush(m_ThirdColor); //繪制第三圈
pOldBrush = (CBrush *)pDC->SelectObject(&m_brushBack);
pPenThin.CreatePen(PS_SOLID, 1, m_ThirdLineColor);
pOldPen = (CPen *)pDC->SelectObject(&pPenThin);
rectRound.SetRect(m_ptMeterCenter.x - nRadius / 2 + nRadius / 15,
m_ptMeterCenter.y - nRadius / 2 + nRadius / 15,
m_ptMeterCenter.x + nRadius / 2 - nRadius / 15,
m_ptMeterCenter.y + nRadius / 2 - nRadius / 15);
pDC->Ellipse(rectRound);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
m_brushBack.DeleteObject();
pPenThin.DeleteObject();
//繪制遮蔽區
DrawRgn(pDC,PtRgn,m_ncnt,m_BackColor);
//畫刻度
char strFigure[MAXNAMELENGTH + 1];
memset(strFigure, 0, sizeof(strFigure));
CFont fDrawFont;
fDrawFont.CreateFont(nRadius/15, nRadius/45, 0, 0, 0, FALSE, FALSE, ANSI_CHARSET,
CLIP_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_PITCH, FF_DONTCARE, _T("Arail"));
CFont *pOldFont = (CFont *)pDC->SelectObject(&fDrawFont);
pPenThin.CreatePen(PS_SOLID, nRadius / 50, m_TickColor); //母刻度
pOldPen = (CPen *)pDC->SelectObject(&pPenThin);
pDC->SetBkMode(TRANSPARENT);
CPoint pt;
for (int i=0; i<m_nTicks+1; i++) //刻度坐標
{
pt=m_TicksSPt.GetAt(i);pDC->MoveTo(pt);
pt=m_TicksEPt.GetAt(i);pDC->LineTo(pt);
//寫刻度
sprintf(strFigure, "%.0f", (m_dMaxValue - m_dMinValue) * i / m_nTicks);
// pDC->SetTextColor(m_TextBackColor);
// pDC->DrawText(strFigure, ,
// DT_SINGLELINE|DT_CENTER|DT_VCENTER);
pDC->SetTextColor(m_TextColor);
pDC->DrawText(strFigure,m_TicksTitle.GetAt(i),DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
pDC->SelectObject(pOldPen);
pPenThin.DeleteObject();
pPenThin.CreatePen(PS_SOLID, nRadius / 100, m_SubTickColor); //子刻度顏色
pOldPen = (CPen *)pDC->SelectObject(&pPenThin);
for (i=0; i<m_nTicks*(m_nSubTicks-1); i++)
{
pt=m_SubTicksSPt.GetAt(i);pDC->MoveTo(pt);
pt=m_SubTicksEPt.GetAt(i);pDC->LineTo(pt);
}
pDC->SelectObject(pOldPen);
pPenThin.DeleteObject();
pDC->SelectObject(pOldFont);
fDrawFont.DeleteObject();
//文本顯示的初始化
int nRadiusFrame = m_nRadiusFrame / 2;
CFont pUnitFont;
pUnitFont.CreateFont(nRadiusFrame/5, 0, 0, 0, 0, FALSE, FALSE, ANSI_CHARSET,
CLIP_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_PITCH, FF_DONTCARE, _T("Times New Roman"));
pOldFont = (CFont *)pDC->SelectObject(&pUnitFont);
// pDC->SetTextColor(m_TextBackColor);
// CRect rectUnits(int(m_ptMeterCenter.x - nRadiusFrame * 0.30f + 2),
// int(m_ptMeterCenter.y + nRadiusFrame * 0.10f + 2),
// int(m_ptMeterCenter.x + nRadiusFrame * 0.30f + 2),
// int(m_ptMeterCenter.y + nRadiusFrame * 0.50f + 2));
// pDC->DrawText(m_strUnits, &rectUnits, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
pDC->SetTextColor(m_TextColor);
pDC->DrawText(m_strUnits, &m_nrectUnits, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
pDC->SelectObject(pOldFont);
pUnitFont.DeleteObject();
}
void CRoundMeter::DrawNeedle(CDC *pDC, CRect &rect)
{
CRect rectRound;
CPen pPenThin, *pOldPen;
CBrush pNeedleBrush, *pOldBrush;
if(m_dCurrentValue>m_WarnMaxValue || m_dCurrentValue<m_WarnMinValue)
{
pNeedleBrush.CreateSolidBrush(m_WarnNeedleColor);
pPenThin.CreatePen(PS_SOLID, 1, m_WarnNeedleLineColor);
}
else
{
pNeedleBrush.CreateSolidBrush(m_NeedleColor);
pPenThin.CreatePen(PS_SOLID, 1, m_NeedleLineColor);
}
pOldBrush = (CBrush *)pDC->SelectObject(&pNeedleBrush);
pOldPen = (CPen *)pDC->SelectObject(&pPenThin);
double dRadius = fabs(m_nRadiusFrame / 2 - m_nRadiusFrame / 16) - fabs(m_nRadiusFrame / 15);
if (m_dCurrentValue < m_dMinValue)
{
m_dCurrentValue = m_dMinValue;
}
else if (m_dCurrentValue > m_dMaxValue)
{
m_dCurrentValue = m_dMaxValue;
}
/////////////////////////////////////////////////////
double dAngle;
if(m_nStartAngle==m_nEndAngle)
{
dAngle=360.0*(m_dCurrentValue-m_dMinValue)/(m_dMaxValue-m_dMinValue);
}
if(m_nStartAngle>m_nEndAngle)
{
dAngle=double((m_nStartAngle-m_nEndAngle))*(m_dCurrentValue-m_dMinValue)
/(m_dMaxValue-m_dMinValue);
}
if(m_nStartAngle<m_nEndAngle)
{
dAngle=double(m_nStartAngle+360-m_nEndAngle)*(m_dCurrentValue-m_dMinValue)
/(m_dMaxValue-m_dMinValue);
}
dAngle=m_nStartAngle-dAngle;
if(dAngle<0.0)
dAngle=dAngle+360.0;
// double dAngle = 300 * (m_dCurrentValue - m_dMinValue) / (m_dMaxValue - m_dMinValue);
CPoint ptRgn[5];
ptRgn[0].x = int(m_ptMeterCenter.x + (m_nRadiusFrame / 25) * cos(dAngle * PI / 180));
ptRgn[0].y = int(m_ptMeterCenter.y - (m_nRadiusFrame / 25) * sin(dAngle * PI / 180));
ptRgn[1].x = int(m_ptMeterCenter.x + (m_nRadiusFrame / 25) * cos(dAngle * PI / 180)
+ (m_nRadiusFrame / 20) * cos((dAngle-30) * PI / 180));
ptRgn[1].y = int(m_ptMeterCenter.y - (m_nRadiusFrame / 25) * sin(dAngle * PI / 180)
- (m_nRadiusFrame / 25) * sin((dAngle-30) * PI / 180));
ptRgn[2].x = int(m_ptMeterCenter.x + (dRadius - 10) * cos(dAngle * PI / 180));
ptRgn[2].y = int(m_ptMeterCenter.y - (dRadius - 10) * sin(dAngle * PI / 180));
ptRgn[3].x = int(m_ptMeterCenter.x + (m_nRadiusFrame / 25) * cos(dAngle * PI / 180)
+ (m_nRadiusFrame / 20) * cos((dAngle + 30) * PI / 180));
ptRgn[3].y = int(m_ptMeterCenter.y - (m_nRadiusFrame / 25) * sin(dAngle * PI / 180)
- (m_nRadiusFrame / 25) * sin((dAngle + 30) * PI / 180));
ptRgn[4].x = int(m_ptMeterCenter.x + (m_nRadiusFrame / 25) * cos(dAngle * PI / 180));
ptRgn[4].y = int(m_ptMeterCenter.y - (m_nRadiusFrame / 25) * sin(dAngle * PI / 180));
// pDC->SetPolyFillMode(WINDING);
pDC->Polygon(ptRgn, 5);
pNeedleBrush.DeleteObject();
pPenThin.DeleteObject();
//第四圈
pNeedleBrush.CreateSolidBrush(m_FourthColor);
pPenThin.CreatePen(PS_SOLID, 1, m_FourthLineColor);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -