📄 thermometer.cpp
字号:
#include "stdafx.h"
#include "ThermoMeter.h"
#include "MemDC.h"
CScaleUnit::CScaleUnit()
{
m_BackColor = RGB( 33, 177, 138);
}
CScaleUnit::~CScaleUnit()
{
}
void CScaleUnit::Draw(CDC *pDC)
{
CPoint ptRgn[3];
ptRgn[0].x = m_rectClient.left;
ptRgn[0].y = m_rectClient.top;
ptRgn[1].x = m_rectClient.left;
ptRgn[1].y = m_rectClient.bottom;
ptRgn[2].x = m_rectClient.right;
ptRgn[2].y = m_rectClient.top + (m_rectClient.bottom - m_rectClient.top) / 2;
CBrush pBackBrush, *pOldBrush;
pBackBrush.CreateSolidBrush(m_BackColor);
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
pDC->SetPolyFillMode(WINDING);
pDC->Polygon(ptRgn, 3);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
//---------------------------------------------------------
CThermoMeter::CThermoMeter()
{
m_BackColor = RGB( 192, 192, 192);
m_dMinValue = 0;
m_dMaxValue = 100;
m_dCurrentValue = 0.00f;
m_nTicks = 5; //大格个数
m_nSubTicks = 5; //大格中小格个数
memset(m_strUnits, 0, sizeof(m_strUnits));
strcpy(m_strUnits, "温度"); //表单位
}
CThermoMeter::~CThermoMeter()
{
}
BEGIN_MESSAGE_MAP(CThermoMeter, CStatic)
//{{AFX_MSG_MAP(CThermoMeter)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CThermoMeter::PreSubclassWindow()
{
CStatic::PreSubclassWindow();
}
void CThermoMeter::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);
DrawScale(&memDC);
m_ctrlUnit.Draw(&memDC);
}
//绘制仪表背景
void CThermoMeter::DrawMeterBackground(CDC *pDC, CRect &rect)
{
CString strScale;
CFont fScaleFont, *pOldFont;
CPen penThick, penThin, penShadow, penScale, *pOldPen;
CBrush m_brushBack, pBackBrush, *pOldBrush;
pDC->SetBkColor(m_BackColor);
m_brushBack.CreateSolidBrush(m_BackColor);
pOldBrush = (CBrush *)pDC->SelectObject(&m_brushBack);
pDC->FillRect(rect, &m_brushBack); //绘制背景
pDC->SelectObject(pOldBrush);
m_brushBack.DeleteObject();
//绘制边框的立体效果
penThick.CreatePen(PS_SOLID, 1, RGB(172, 168, 153));
penThin.CreatePen(PS_SOLID, 1, RGB(113, 111, 110));
penShadow.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
pOldPen = (CPen *)pDC->SelectObject(&penShadow);
pDC->MoveTo(rect.left, rect.top);
pDC->LineTo(rect.right - 1, rect.top);
pDC->MoveTo(rect.left + 1, rect.top + 1);
pDC->LineTo(rect.right - 2, rect.top + 1);
pDC->MoveTo(rect.left, rect.top);
pDC->LineTo(rect.left, rect.bottom - 1);
pDC->MoveTo(rect.left + 1, rect.top + 1);
pDC->LineTo(rect.left + 1, rect.bottom - 2);
pDC->SelectObject(&penThick);
pDC->MoveTo(rect.left + 1, rect.bottom - 1);
pDC->LineTo(rect.right - 1, rect.bottom - 1);
pDC->LineTo(rect.right - 1, rect.top + 1);
pDC->SelectObject(&penThin);
pDC->MoveTo(rect.left, rect.bottom);
pDC->LineTo(rect.right, rect.bottom);
pDC->LineTo(rect.right, rect.top);
pDC->SelectObject(pOldPen);
//绘制指针显示区域
CRect rectScale;
rectScale.SetRect(rect.left + rect.Width() / 4,
rect.top + rect.Height() / 12,
rect.left + rect.Width() / 4 + rect.Width() / 10,
rect.bottom - rect.Height() / 12);
pBackBrush.CreateSolidBrush(RGB(128, 0, 0));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
pDC->FillRect(&rectScale, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
//绘制指针区域立体效果
pDC->SelectObject(&penThick);
pDC->MoveTo(rectScale.left, rectScale.bottom);
pDC->LineTo(rectScale.left, rectScale.top);
pDC->LineTo(rectScale.right, rectScale.top);
pDC->SelectObject(&penThin);
pDC->MoveTo(rectScale.left + 1, rectScale.bottom);
pDC->LineTo(rectScale.left + 1, rectScale.top + 1);
pDC->LineTo(rectScale.right, rectScale.top + 1);
pDC->SelectObject(&penShadow);
pDC->MoveTo(rectScale.right - 1, rectScale.top + 1);
pDC->LineTo(rectScale.right - 1, rectScale.bottom - 1);
pDC->LineTo(rectScale.left + 1, rectScale.bottom - 1);
pDC->MoveTo(rectScale.right, rectScale.top);
pDC->LineTo(rectScale.right, rectScale.bottom);
pDC->LineTo(rectScale.left, rectScale.bottom);
m_rectScale = rectScale;
m_rectScale.DeflateRect(2, 2, 2, 2);
//绘制刻度
fScaleFont.CreateFont(rect.Height() / 8, 0,
0,
0,
FW_NORMAL,
FALSE,
FALSE,
FALSE,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE,
"System");
pOldFont = (CFont *)pDC->SelectObject(&fScaleFont);
penScale.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
for (int i=0; i<m_nTicks+1; i++)
{
CPoint ptStartTick, ptEndTick;
int nTickDisc = rect.Height() * 5 * i / (6 * m_nTicks);
ptStartTick.x = rect.left + rect.Width() * 3 / 7;
ptStartTick.y = rect.bottom - rect.Height() / 12 - nTickDisc;
ptEndTick.x = rect.left + rect.Width() * 3 / 5;
ptEndTick.y = rect.bottom - rect.Height() / 12 - nTickDisc;
pDC->SelectObject(penScale);
pDC->MoveTo(ptStartTick);
pDC->LineTo(ptEndTick);
//绘制立体感觉
CPoint ptShadowStartTick, ptShadowEndTick;
ptShadowStartTick = ptStartTick;
ptShadowEndTick = ptEndTick;
ptShadowStartTick.y--;
ptShadowEndTick.y--;
pDC->SelectObject(penShadow);
pDC->MoveTo(ptShadowStartTick);
pDC->LineTo(ptShadowEndTick);
//绘制子刻度
for (int j=0; j<m_nSubTicks+1; j++)
{
if (i < m_nTicks)
{
CPoint ptSubStartTick, ptSubEndTick;
int nSubTickDisc = (rect.Height() * 5 / (6 * m_nTicks)) * j / m_nSubTicks;
ptSubStartTick.x = ptStartTick.x;
ptSubStartTick.y = ptStartTick.y - nSubTickDisc;
ptSubEndTick.x = ptSubStartTick.x + (ptEndTick.x - ptSubStartTick.x) / 2;
ptSubEndTick.y = ptSubStartTick.y;
pDC->SelectObject(penScale);
pDC->MoveTo(ptSubStartTick);
pDC->LineTo(ptSubEndTick);
CPoint ptShadowSubStartTick, ptShadowSubEndTick;
ptShadowSubStartTick = ptSubStartTick;
ptShadowSubEndTick = ptSubEndTick;
ptShadowSubStartTick.y--;
ptShadowSubEndTick.y--;
pDC->SelectObject(penShadow);
pDC->MoveTo(ptShadowSubStartTick);
pDC->LineTo(ptShadowSubEndTick);
}
}
//绘制刻度
CRect ptScale;
pDC->SetBkMode(TRANSPARENT);
strScale.Format("%.0f", (m_dMaxValue - m_dMinValue) * i / m_nTicks);
CSize size = pDC->GetTextExtent(strScale);
pDC->SetTextColor(RGB(255, 255, 255));
ptScale.SetRect(rect.left + rect.Width() * 2 / 3,
ptStartTick.y - size.cy / 2,
rect.right,
ptStartTick.y + size.cy / 2);
pDC->DrawText(strScale, ptScale, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
pDC->SetTextColor(RGB(0, 0, 0));
ptScale.DeflateRect(-1, -1, 1, 1);
pDC->DrawText(strScale, ptScale, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
}
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldFont);
penThick.DeleteObject();
penThin.DeleteObject();
penShadow.DeleteObject();
m_brushBack.DeleteObject();
pBackBrush.DeleteObject();
fScaleFont.DeleteObject();
penScale.DeleteObject();
}
void CThermoMeter::DrawScale(CDC *pDC)
{
if (m_dCurrentValue > m_dMaxValue)
{
m_dCurrentValue = m_dMaxValue;
}
else if (m_dCurrentValue < m_dMinValue)
{
m_dCurrentValue = m_dMinValue;
}
CRect rectScale;
double yScale = (m_dCurrentValue - m_dMinValue) / (m_dMaxValue - m_dMinValue);
rectScale.SetRect(m_rectScale.left,
m_rectScale.bottom - int(yScale * (m_rectScale.Height())),
m_rectScale.right,
m_rectScale.bottom);
CBrush pBackBrush, *pOldBrush;
pBackBrush.CreateSolidBrush(RGB(255, 0, 0));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
pDC->FillRect(&rectScale, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
m_ctrlUnit.SetRect(GetUnitRect());
}
CRect CThermoMeter::GetUnitRect()
{
CRect rcClient;
double yScale = (m_dCurrentValue - m_dMinValue) / (m_dMaxValue - m_dMinValue);
int yPos = m_rectScale.bottom - int(yScale * (m_rectScale.Height()));
rcClient.left = m_rectCtrl.left + m_rectCtrl.Width() / 12;
rcClient.right = rcClient.left + m_rectCtrl.Width() / 8;
rcClient.top = yPos - m_rectCtrl.Width() / 16;
rcClient.bottom = yPos + m_rectCtrl.Width() / 16;
return rcClient;
}
void CThermoMeter::SetCurrentValue(const double dCurrentValue)
{
m_dCurrentValue = dCurrentValue;
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -