简单的LED时钟控件

来源:互联网 发布:如何查看mysql表结构 编辑:程序博客网 时间:2024/04/20 00:06

偶然的一次机会看到了这个小小的控件,想必大家都知道该如何利用它了吧。o(∩_∩)o...

///////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __MFC_EXT_DIGITCLOCK_H__
#define __MFC_EXT_DIGITCLOCK_H__
// EDClock.h : header file
//
#define IntegerCount  3
#define DecimalCount  5//4
/////////////////////////////////////////////////////////////////////////////
// CDigitDisplayer window

class CDigitDisplayer : public CStatic
{
// Construction
public:
 CDigitDisplayer();
 
virtual ~CDigitDisplayer();

// Attributes
public:
 
 
static COLORREF origin;

// Operations
public:
 
 COLORREF GetColor() 
const return m_color;}
 COLORREF SetColor(COLORREF color);
 
double m_number;
    
void DisplayDigit(double number);
 
void GetDigit(double number);
// Overrides
 
// ClassWizard generated virtual function overrides
 
//{{AFX_VIRTUAL(CDigitDisplayer)
 protected:
 
virtual void PreSubclassWindow();
 
//}}AFX_VIRTUAL

// Implementation
public:

 
// Generated message map functions
protected:
 
//{{AFX_MSG(CDigitDisplayer)
 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
 afx_msg 
void OnPaint();
 afx_msg 
void OnSize(UINT nType, int cx, int cy);
 
//}}AFX_MSG
private:

 COLORREF    m_color;
 UINT  m_w;
 UINT  m_h;
 BITMAP  m_bm;
 HBITMAP  m_hBitmap[
13];
 UINT  m_nTimer;
 
int         m_digit[10];
 
void  Output(UINT digit, UINT pos);

 DECLARE_MESSAGE_MAP()
}
;

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // __MFC_EXT_DIGITCLOCK_H__
//
// Author: Xie Jingwei, Chinese Spell: 谢敬伟
// Email to me, jw_xie@usa.net
// A digital clock control, :-)
//
// Usage: See the header, just simple 
// Please Note: Make sure ADD the 12 bitmaps to your project, and 
// sort the ID to correct order. I used IDB_BITMAP1 to IDB_BITMAP12 
// side by side. See following:
//
// Digit:     ID    VALUE
//   0        IDB_BITMAP1   100
//   1        IDB_BITMAP2   101 
//   2        IDB_BITMAP3   102 
//   3        IDB_BITMAP4   103 
//   4        IDB_BITMAP5   104
//   5        IDB_BITMAP6   105 
//   6        IDB_BITMAP7   106 
//   7        IDB_BITMAP8   107
//   8        IDB_BITMAP9   108
//   9        IDB_BITMAP10   109 
//   :        IDB_BITMAP11   110
//            IDB_BITMAP12   111 
//

// There are three properties.
// face color <-----> SetColor();
// style <-----> SetStyle();
// alarm mode <----> SetAlarm();

//////////////////////////////////////////////////////////////////////////////
// EDClock.cpp : implementation file
//数码管显示

#include 
"stdafx.h"

#include 
"resource.h"
#include 
"DigitDisplayer.h"
#include 
"math.h"

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

// The resource bitmap face color 
//static COLORREF origin; 
COLORREF CDigitDisplayer::origin = RGB(25500); 

/////////////////////////////////////////////////////////////////////////////
// CDigitDisplayer

CDigitDisplayer::CDigitDisplayer()
{
  
 m_color 
= origin;
 
for(int i = 0; i< 13; i++{//创建数码显示的位图
  HBITMAP temp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i+IDB_BITMAP1, 0, NULL, 0);//创建合适的位图
  m_hBitmap[i] = (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 00, LR_COPYRETURNORG | LR_COPYDELETEORG);//将位图存入缓存以备显示
  
 }

 
for(i=0;i<8;i++) m_digit[i]=0;
 m_number
=0;
}


CDigitDisplayer::
~CDigitDisplayer()
{
 
for(int i = 0; i< 12; i++{
  
if(m_hBitmap[i])
   ::DeleteObject(m_hBitmap[i]);
//清空缓存
 }

}


BEGIN_MESSAGE_MAP(CDigitDisplayer, CStatic)
 
//{{AFX_MSG_MAP(CDigitDisplayer)
 ON_WM_ERASEBKGND()
 ON_WM_PAINT()
 ON_WM_SIZE()
 
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDigitDisplayer message handlers

void CDigitDisplayer::PreSubclassWindow() 
{
 ::GetObject(m_hBitmap[
0], sizeof BITMAP, &m_bm);
 
 CStatic::PreSubclassWindow();
}


void CDigitDisplayer::OnPaint() //设置数码宽度和高度
{
 CPaintDC dc(
this); // device context for painting
 CRect rectClient;
 GetClientRect(
&rectClient);
 m_h 
= rectClient.Height();
 m_w 
= rectClient.Width()/(IntegerCount+DecimalCount+2);
 DisplayDigit(m_number);
 
}


BOOL CDigitDisplayer::OnEraseBkgnd(CDC
* pDC) //给数码显示准备无效区域
{
 
// TODO: Add your message handler code here and/or call default
 CBrush brush;
 brush.CreateSolidBrush(::GetSysColor(COLOR_WINDOWTEXT) ); 
 CBrush
* pOldBrush = pDC->SelectObject(&brush);

 CRect rectClient;
 GetClientRect(
&rectClient);
 pDC
->PatBlt(00, rectClient.Width(), rectClient.Height(), PATCOPY);
 pDC
->SelectObject(pOldBrush);
 
 
return CStatic::OnEraseBkgnd(pDC);
}


void CDigitDisplayer::Output(UINT digit, UINT pos)//数字输出
{
    
// draw the bitmap
 
 CClientDC dc(
this);
 CDC dcMem;
 dcMem.CreateCompatibleDC(
&dc);
 CBitmap
* pBitmap = CBitmap::FromHandle( m_hBitmap[digit] );
 CBitmap
* pOldBitmap = dcMem.SelectObject(pBitmap);
    dc.StretchBlt(m_w
*pos, 0, m_w, m_h,
   
&dcMem, 00, m_bm.bmWidth, m_bm.bmHeight, SRCCOPY);
  dcMem.SelectObject(pOldBitmap);
 dcMem.DeleteDC();
}




COLORREF CDigitDisplayer::SetColor(COLORREF color)
//显示数字的颜色设置,若是红色,则改为显示时的绿色。
{
 
 
if(m_color == color)
  
return color;
 COLORREF temp 
= m_color;
 m_color 
= color;
 
for(int i = 0; i< 13; i++{
  
if(m_hBitmap[i])
   ::DeleteObject(m_hBitmap[i]);
  COLORMAP mapColor;
  mapColor.from 
= origin;
  mapColor.to  
= color;
  HBITMAP temp 
= (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i+IDB_BITMAP1, 0&mapColor, 1);
  m_hBitmap[i] 
= (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 00, LR_COPYRETURNORG | LR_COPYDELETEORG);
 }

 
return temp;
}


void CDigitDisplayer::GetDigit(double number)//获取每一位数字
{
   
//最多显示4位整数,4位小数,1个小数点,1个符号
   m_digit[0]=number/1000;         //第一位整数
   m_digit[1]=(number-m_digit[0]*1000)/100//第二位整数
   m_digit[2]=(number-m_digit[0]*1000-m_digit[1]*100)/10//第三位整数
   m_digit[3]=number-m_digit[0]*1000-m_digit[1]*100-m_digit[2]*10;  //第四位整数
   m_digit[4]=(number-m_digit[0]*1000-m_digit[1]*100-m_digit[2]*10-m_digit[3])*10//第一位小数
   m_digit[5]=(number-m_digit[0]*1000-m_digit[1]*100-m_digit[2]*10-m_digit[3])*100-m_digit[4]*10//第二位小数
   m_digit[6]=(number-m_digit[0]*1000-m_digit[1]*100-m_digit[2]*10-m_digit[3])*1000-m_digit[4]*100-m_digit[5]*10//第三位小数
   m_digit[7]=(number-m_digit[0]*1000-m_digit[1]*100-m_digit[2]*10-m_digit[3])*10000-m_digit[4]*1000-m_digit[5]*100-m_digit[6]*10//第四位小数
   m_digit[8]=(number-m_digit[0]*1000-m_digit[1]*100-m_digit[2]*10-m_digit[3])*100000-m_digit[4]*10000-m_digit[5]*1000-m_digit[6]*100-m_digit[7]*10//第五位小数
}


void CDigitDisplayer::DisplayDigit(double number)
{
 
/*CRect rectClient;
 GetClientRect(&rectClient);
 m_h = rectClient.Height();
 m_w = rectClient.Width()/(IntegerCount+DecimalCount+2);
    
*/

 
 
//得到各个数码位
 GetDigit(fabs(number));

 
//显示符号
 if(number>0) Output(120);  //空位图
 else            Output(11,0);  //负号

 
//显示小数点前的各数码位
 
 
int firstpositive;
 firstpositive
=3;
 
for(int i=4-IntegerCount;i<4;i++)
 
{
  
if(m_digit[i]>0
  
{
   firstpositive
=i;
   
break;
  }

 }

 
for(i=4-IntegerCount;i<4;i++)
 
{
     
if(i>=firstpositive)
    Output(m_digit[i],i
-3+IntegerCount);
  
else
    Output(
12, i-3+IntegerCount);
 }


 
//显示小数点
 Output(10,IntegerCount+1);
 
 
//显示小数点后的各数码位
 for(i=IntegerCount+1;i<IntegerCount+1+DecimalCount;i++
 
{
  Output(m_digit[i],i
+1);
  
 }

}


void CDigitDisplayer::OnSize(UINT nType, int cx, int cy) //保存当前窗口宽和高,以便后面能用GetWindowHeight和GetWindowWidth得到
{
 CStatic::OnSize(nType, cx, cy);
 
 CRect rectClient;
 GetClientRect(
&rectClient);
 m_h 
= rectClient.Height();
 m_w 
= rectClient.Width()/(IntegerCount+DecimalCount+2);
 
}

在BITMAP中加入数码管资源即可实现