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; }