程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 七段數碼顯示的數字時鐘

七段數碼顯示的數字時鐘

編輯:關於VC++

摘要

絕大多數的電子產品都使用了七段數碼顯示,如果軟件也能模擬出這種效果該有多好?在本文之前,VC知識庫在線雜志曾有兩篇文章介紹過如何實現這種效果,有一篇的實現方法較為簡單,但繪出的數字不夠逼真,而另一篇實現的效果雖然逼真,但必須依賴位圖資源,並且無法設置前景色和背景色等。筆者經過仔細的研究與試驗,終於找到了較好的解決辦法。本文將詳細講述七段數碼顯示的數字時鐘的實現。

關鍵字 七段數碼顯示 數字時鐘

實現原理

我們知道,時鐘的顯示由時、分、秒及冒號組成,因此我們可以用以下函數來實現:DrawHour,DrawMinute,DrawSecond和Draw2Dot。由於時、分、秒都由兩個數字組成(小於10的前面加0),因此可以再把問題分解,用DrawSingleNunber來畫單個數字。單個數字又該怎麼畫呢?下面看七段數碼的組成,我們用1到7的標號來表示每一段。

由於每個數字都是由這七段拼湊而成,因此我們可以在DrawSingleNumber函數中用switch語句,根據不同的數字去畫不同的段,接下來的工作就是如何去畫這七段了,每一段都是一個具有顏色填充的多邊形。

void CDigitalClock::DrawSingleNumber(int nNum,int nLeft)
{
  switch (nNum)
  {
  case 0:
    DrawSection1(nLeft);
    DrawSection2(nLeft);
    DrawSection3(nLeft);
    DrawSection4(nLeft);
    DrawSection5(nLeft);
    DrawSection6(nLeft);
    break;
  case 1:
    DrawSection2(nLeft);
    DrawSection3(nLeft);
    break;
  case 2:
    DrawSection1(nLeft);
    DrawSection2(nLeft);
    DrawSection4(nLeft);
    DrawSection5(nLeft);
    DrawSection7(nLeft);
    break;
  case 3:
    DrawSection1(nLeft);
    DrawSection2(nLeft);
    DrawSection3(nLeft);
    DrawSection4(nLeft);
    DrawSection7(nLeft);
    break;
  case 4:
    DrawSection2(nLeft);
    DrawSection3(nLeft);
    DrawSection6(nLeft);
    DrawSection7(nLeft);
    break;
  case 5:
    DrawSection1(nLeft);
    DrawSection3(nLeft);
    DrawSection4(nLeft);
    DrawSection6(nLeft);
    DrawSection7(nLeft);
    break;
  case 6:
    DrawSection1(nLeft);
    DrawSection3(nLeft);
    DrawSection4(nLeft);
    DrawSection5(nLeft);
    DrawSection6(nLeft);
    DrawSection7(nLeft);
    break;
  case 7:
    DrawSection1(nLeft);
    DrawSection2(nLeft);
    DrawSection3(nLeft);
    break;
  case 8:
    DrawSection1(nLeft);
    DrawSection2(nLeft);
    DrawSection3(nLeft);
    DrawSection4(nLeft);
    DrawSection5(nLeft);
    DrawSection6(nLeft);
    DrawSection7(nLeft);
    break;
  case 9:
    DrawSection1(nLeft);
    DrawSection3(nLeft);
    DrawSection4(nLeft);
    DrawSection2(nLeft);
    DrawSection6(nLeft);
    DrawSection7(nLeft);
    break;
  default:
    ;
  }
}

要畫出逼真的效果來,必須精確或基本精確去計算出多邊形的每個頂點的坐標,然後用作圖函數MoveTo和LineTo去畫線條,畫線前,可以構造一個畫筆,用指定的顏色去畫。把幾個邊的線條畫好後,發現還需要進行填充,因此再去構造一個區域,使用畫刷進行填充。這樣一來,不僅畫出了立體效果,還可以設置不同的背景色和前景色。以下代碼展示了第一段的繪制過程

void CDigitalClock::DrawSection1(int nLeft)
{
  if (m_memDC.m_hDC!=NULL)
  {
    CPoint point[4];
    point[0].x=nLeft+(int)(0.1*m_nWidth);
    point[0].y=m_nYmargin;
    point[1].x=nLeft+(int)(0.9*m_nWidth);
    point[1].y=m_nYmargin;
    point[2].x=nLeft+(int)(0.7*m_nWidth);
    point[2].y=(int)(0.2*m_nWidth)+m_nYmargin;
    point[3].x=nLeft+(int)(0.3*m_nWidth);
    point[3].y=(int)(0.2*m_nWidth)+m_nYmargin;
    CBrush br(m_crText);
    CRgn rgn;
    rgn.CreatePolygonRgn(point,4,ALTERNATE);
    m_memDC.FillRgn(&rgn,&br);
    br.DeleteObject();
    rgn.DeleteObject();

    m_memDC.MoveTo(point[0]);
    m_memDC.LineTo(point[1]);

    m_memDC.MoveTo(point[1]);
    m_memDC.LineTo(point[2]);

    m_memDC.MoveTo(point[2]);
    m_memDC.LineTo(point[3]);

    m_memDC.MoveTo(point[3]);
    m_memDC.LineTo(point[0]);
  }
}

實現了這些基本元素“段”,就可以畫單個數字了,進而可以在不同的位置畫出時、分、秒。冒號由一個專門的函數Draw2Dot來實現。

void CDigitalClock::Draw2Dot(int nLeft)
{
  if (m_memDC.m_hDC!=NULL)
  {
    CBrush br(m_crText);
    CRect rect;
    rect.SetRect(nLeft+(int)(0.3*m_nWidth),(int)(0.4*m_nWidth)+m_nYmargin,
      nLeft+(int)(0.6*m_nWidth),(int)(0.7*m_nWidth)+m_nYmargin);
    m_memDC.Ellipse(rect);
    CRgn rgn1;
    rgn1.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom);
    m_memDC.FillRgn(&rgn1,&br);
    rect.OffsetRect(0,(int)(0.8*m_nWidth)+m_nYmargin);
    m_memDC.Ellipse(rect);
    CRgn rgn2;
    rgn2.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom);
    m_memDC.FillRgn(&rgn2,&br);
    br.DeleteObject();
    rgn1.DeleteObject();
    rgn2.DeleteObject();
  }
}

結語

要實現七段數碼顯示的效果,關鍵在於計算各個頂點的坐標,經過調試發現,將一個數字的寬度調整為高度的一半時可達到最好的顯示效果。最初設計這個類時,我是在OnPaint裡面調用自定義繪圖函數DrawHour、DrawMinute、DrawSecond以及Draw2Dot,結果發現繪出的時鐘有明顯閃爍,後來采用雙緩沖繪圖的辦法消除了這一現象。

本文實現的數字時鐘從CStatic派生,使用時,只需在界面上放置一個靜態文本控件,然後關聯一個CDigitalClock的控件變量即可。示例代碼在VC6.0+Windows XP下編譯通過。運行效果如下圖:

最後,衷心感謝《電子八段管的仿真控件》的作者kevin cheng和《電子式時鐘》的作者李宏亮以及網友redcheek等人。

QQ: 40475290

Email: [email protected]

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved