⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thermometer.cpp

📁 工控软件图形界面-控件实现(温度计控件) 可用于工业控制系统开发使用的控件
💻 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 + -