gusucode.com > 电子八段管的仿真控件C#源码程序 > 电子八段管的仿真控件/epanesrc/EPane/NumPane.cpp

    

#include "stdafx.h"
#include "EPane.h"
#include "NumPane.h"
#include "MemDC.h"

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

/////////////////////////////////////////////////////////////////////////////
// CNumPane
//#define HEIGHT(ht)  min(100,ht)
//#define WEIGHT(wt)  min(50,wt)

CNumPane::CNumPane(BOOL bIsShow)
{
	bIsShowBackGround	=	bIsShow;
	m_backgroundcolor	=	RGB(0,0,0);			//一般的数字八段管显示盘背景色都是黑色的
	m_borderColor		=	RGB(52,255,34);		//随便设置一个颜色
	m_numColor			=	RGB(52,255,34);		//随便设置一个颜色
	m_numBackColor		=   RGB(1,135,31);		
	m_perHeight			=	0.6f;			
	m_perWeight			=	0.9f;
	m_showNum			=	"21.234";
	m_oldNum			=	"A";
	m_penWidth			=	3;
	m_htow				=	2;
	m_maxHeight			=   50;	
	pItem				=	NULL;
}

CNumPane::~CNumPane()
{
	if(pItem != NULL)
		delete [] pItem;
}


BEGIN_MESSAGE_MAP(CNumPane, CStatic)
	//{{AFX_MSG_MAP(CNumPane)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNumPane message handlers

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

	GetClientRect(&m_controlRect);		//获得控件客户区矩形大小
	MakeAdjust();						//调整参数

	CMemDC	m_MemDC(&dc,&m_controlRect);
	
	MakeCoordinate();					//每次画的时候都计算一下数字对应的坐标

	m_MemDC.BitBlt(0,0,m_controlRect.Width(),m_controlRect.Height(),\
		&dc,0,0,SRCCOPY);
		
	//绘制背景颜色边框颜色
		CPen	m_temppen;		//用来画边框的笔,颜色(m_borderColor)
		CBrush	m_tempbrush;	//用来画背景的刷子,颜色(m_backgroundcolor)
		m_temppen.CreatePen(PS_SOLID,3,m_borderColor);
		m_tempbrush.CreateSolidBrush(m_backgroundcolor);
		CPen * pOldPen		=	m_MemDC.SelectObject(&m_temppen);
		CBrush * pOldBrush	=	m_MemDC.SelectObject(&m_tempbrush);
		m_MemDC.Rectangle(&m_controlRect);//绘制控件背景
		m_MemDC.SelectObject(pOldPen);
		m_MemDC.SelectObject(pOldBrush);
		m_temppen.DeleteObject();
		m_tempbrush.DeleteObject();
		

		int len	=	GetNumberLength();
		for(int i=0 ; i<len ; i++)
		{
			pItem[i].pDC	=	&m_MemDC; 
		}

		if(bIsShowBackGround) //如果画背景数字
		{
			DrawBackGround(&m_MemDC);
		}

		DrawNumber(&m_MemDC);//绘制数字
		
}

void CNumPane::DrawBackGround( CDC * pDC )
{

	CPen m_drawNumPen;
	m_drawNumPen.CreatePen(PS_SOLID,m_penWidth,m_numBackColor);
	CPen * poldPen = (CPen *)pDC->SelectObject(&m_drawNumPen);
	int len	=	GetNumberLength();
	for(int i=0 ; i<len ; i++)
	{
		pItem[i].Draw8();	//画背景数字,也就是绘制8
	}
	pDC->SelectObject(poldPen);
	m_drawNumPen.DeleteObject();
}

int CNumPane::GetNumberLength()
{
	return max(4,m_showNum.GetLength()-1); //获得数字的长度(.不计算在内),最小长度也要是4
}



void CNumPane::DrawNumber(CDC *pDC)
{
	CPen m_drawNumPen;
	m_drawNumPen.CreatePen(PS_SOLID,m_penWidth,m_numColor);
	CPen * poldPen = (CPen *)pDC->SelectObject(&m_drawNumPen);
	int len	=	GetNumberLength();
	int index = -1;
	for(int i=0 ; i<len+1 ; i++)
	{
		// 绘制len个8段管,分别把他们“点亮”
		index ++;
		char gchar	=	m_showNum.GetAt(i);
		switch(gchar)
		{
		case '0':
			pItem[index].Draw0();
			break;
		case '1':
			pItem[index].Draw1();
			break;
		case '2':
			pItem[index].Draw2();
			break;
		case '3':
			pItem[index].Draw3();
			break;
		case '4':
			pItem[index].Draw4();
			break;
		case '5':
			pItem[index].Draw5();
			break;
		case '6':
			pItem[index].Draw6();
			break;
		case '7':
			pItem[index].Draw7();
			break;
		case '8':
			pItem[index].Draw8();
			break;
		case '9':
			pItem[index].Draw9();
			break;
		case '-':
			pItem[index].DrawMinus();
			break;
		case '.':
			index--;
			pItem[index].DrawDot();			
			break;
	
		}
	}
	pDC->SelectObject(poldPen);
	m_drawNumPen.DeleteObject();
}

int CNumPane::GetDotPos()
{
	int pos = m_showNum.Find('.');
	return (pos);
}

void CNumPane::MakeCoordinate()
{
	
	int len			=	GetNumberLength();//生成的8段管数目
	if(m_showNum.Compare(m_oldNum)!=0)  //若是长度没有改变
	{
		//  如何得到每个8段管的坐标	
		pItem			=	new Pane8[len];	
	}
	
	
	int ctrlheight	=	m_controlRect.Height();
	int	middle		=	ctrlheight/2;
	int	up			=	(int)(middle - min(ctrlheight*m_perHeight*0.5,m_maxHeight));
	int	bottom		=	(int)(middle + min(ctrlheight*m_perHeight*0.5,m_maxHeight));
	
	int ctrlweight	=	m_controlRect.Width();
	float perval	=	0.2f;	//每个数字之间间隔和数字宽度之间的比例
	int	  temp		=	(int)(ctrlweight*m_perWeight/(len));
	temp			=	(int)min(temp,(ctrlheight*m_perHeight)*(1+perval)/m_htow);
	int val			=	int(temp*perval);
	int numwidth	=	int(temp*(1-perval));
	int leftbegin	=	(ctrlweight - temp*len)/2;//最左边的横坐标
	//填充数组
	for(int i=0 ; i<len ; i++)
	{
		pItem[i].m_leftup.x		=	leftbegin;
		pItem[i].m_leftup.y		=	up;
		pItem[i].m_leftmid.x	=	leftbegin;
		pItem[i].m_leftmid.y	=	middle;
		pItem[i].m_leftbottom.x	=	leftbegin;
		pItem[i].m_leftbottom.y	=	bottom;
		leftbegin				=	leftbegin + numwidth;
		pItem[i].m_rightup.x	=	leftbegin;
		pItem[i].m_rightup.y	=	up;
		pItem[i].m_rightmid.x	=	leftbegin;
		pItem[i].m_rightmid.y	=	middle;
		pItem[i].m_rightbottom.x=	leftbegin;
		pItem[i].m_rightbottom.y=	bottom;
		leftbegin				=	leftbegin + val;
		if(i == GetDotPos()-1)
		{
			leftbegin += 5;  //为画'.'留出多一些的间隔
		}
	}
	
}

void CNumPane::SetShowNumber(float f)
{
	//首先把float型转化成CString型
	CString str;
	str.Format("%.5f",f);
	
	if(str.Find('.')==-1)
	{
		str=str+".00";	//默认精度是小数点后两位
	}
	if(str.GetLength()<5)
	{
		for(int i=0;i<(5-str.GetLength());i++)
		{
			str="0"+str; //如果位数长度太短,则用0补齐
		}
	}
	m_oldNum  = m_showNum;
	m_showNum = str;
	if(m_showNum.Compare(m_oldNum)!=0)  //若是长度没有改变
	{
		if(pItem != NULL)
		{
		   delete [] pItem;
		}
	}
	Invalidate ();
}

void CNumPane::SetShowNumber(CString str)
{

	if(str.Find('.')==-1)
	{
		str=str+".00";
	}
	if(str.GetLength()<5)
	{
		for(int i=0;i<(5-str.GetLength());i++)
		{
			str="0"+str;
		}
	}

	m_oldNum  = m_showNum;
	m_showNum = str;
	if(m_showNum.Compare(m_oldNum)!=0)
	{
		delete [] pItem;
	}
	Invalidate ();
}

void CNumPane::SetBackGroundColor(COLORREF ref)
{	
	m_backgroundcolor	=	ref;
	Invalidate ();
}

void CNumPane::SetBorderColor(COLORREF ref)
{
	m_borderColor		=	ref;
	Invalidate ();
}

void CNumPane::SetNumColor(COLORREF ref)
{
	m_numColor			=	ref;
	Invalidate();
}

void CNumPane::SetBackNumColor(COLORREF ref)
{
	m_numBackColor		=	ref;
	Invalidate();
}

void CNumPane::MakeAdjust()
{
	float i = float(m_controlRect.Width()/100);
	if( i < 1.5 )
		m_penWidth	=	1;
	else if( 1.5 < i && i < 2.5 )
		m_penWidth	=	2;
	else
		m_penWidth	=	3;

	i = float(m_controlRect.Height());
	if(i < 100)
		m_perHeight	= 0.8f;
	else
		m_perHeight	= 0.5f;
}

void CNumPane::Restore()
{

	m_backgroundcolor	=	RGB(0,0,0);			
	m_borderColor		=	RGB(52,255,34);		
	m_numColor			=	RGB(52,255,34);	
	m_numBackColor		=   RGB(1,135,31);		
	m_perHeight			=	0.6f;			
	m_perWeight			=	0.9f;
	bIsShowBackGround	=	false;
	
}