Click here to Skip to main content
16,016,744 members
Articles / Desktop Programming / MFC

Digital Analog Clock

Rate me:
Please Sign up or sign in to vote.
3.68/5 (12 votes)
17 Aug 20024 min read 115.9K   2K   27   7
Digital analog clock

Sample Image - LEDChars.gif

Sample Image - MultiClocks.gif

What's New

This article is now a combination of two projects, under the new parent project Clocks, the source code has been modified to a large extent, to eliminate the direct reference of the classes through the Document class, some old source files have been deleted and new ones added in order to use the new sub-classes CAnalog and CDigital.

The following new sub-classes have been added to original LEDChars project:

  • CAnalog (Analog.cpp / Analog.h)
  • CDigital (Digital.cpp / Digital.h)
  • CAnanlogView (AnalogView.cpp / AnalogView.h)
  • CDigitalView (DigitalView.cpp / DigitalView.h)

The newly added project is named MultipleClocks and uses the sub-class CAnalog, used in the above project (LEDChars). When you open the project Clocks, the currently active project will be shown in bold in the projects pane at the left (VC6, no idea about .NET). When you select Build->Build (??) or Build->Rebuild All from the menu the currently active project will be built.

To make a different project active, from the menu select Project->Set Active Project and select the project you want OR left-click on the project you want to make active in the projects-pane at the left and select Set Active project from the pop-up menu.

To build both the projects simultaneously, from the menu, select Build->Batch Build and on the displayed form, click either Build or Rebuild All as per your requirement.

To use the sub-classes CAnalog and CDigital in some project of your own, either individually or together, refer to the How To section below.

Introduction

This article shows you how to create two different types of clocks, one digital (where the time is displayed as characters) and analog (where the time is shown like a watch with hand for hours, minutes and seconds), similar to what is available on hand watches.

Features

The clock displays time of some countries (may not be accurate) in both digital and analog form, the number of countries / states / cities has been kept to the bare minimum to allow others to modify the project and convert the clock to display time of all countries of the world and make it a World Clock.

LEDChars Project

Displays a treeview in the left-pane with some countries or time-zones and to the right an analog clock above and a digital clock below.

MultipleClocks Project

Displays more than one view of the analog clock. At the start, all views display the Greenwich-Mean time. To set the time of any of these views for a different time-zone, right-click on the view and select the time-zone to set from the pop-up menu that will be displayed.

How To

To Use sub-class CAnalog

  • Copy or Drag and Drop the source files Analog.cpp and Analog.h into your project folder.

On a Dialog-based Project

  • Add Windows message handler WM_DESTROY (OnDestroy).
  • Add Windows message handler WM_TIMER (OnTimer).
  • Add the line #Include "Analog.h".
  • Create a variable CAnalog m_Analog.
  • In the OnInitDialog() member function, add the following lines:
    C++
    int C?????::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
      if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;
    
      m_Analog.Create("", WS_VISIBLE|WS_CHILD, CRect(0,0,450,300), this , 0);
      SetTimer(0, 1000, NULL);
      //Change the values 0, 450 and 300 as per you requirements
      // Add the following line in the OnDestroy function created above
    
      return 0;
    }
    
    void C?????::OnDestroy() 
    {
      CTreeView::OnDestroy();
      // TODO: Add your message handler code here
      // The KillTimer function is very essential without 
      //which you system can crash 
      KillTimer(1);  
    }
    
    //In the OnTimer Function, add the following lines
    
    void C???????::OnTimer(UINT nIDEvent) 
    {
      // TODO: Add your message handler code here and/or call default
      struct tm *oTime;
      time_t t;
      time(&t);
      oTime = gmtime(&t);
      m_Analog.m_Country = "GMT" 
      // the name of the Time-Zone
      m_Analog.SetTime(oTime);
      CTreeView::OnTimer(nIDEvent);
    }
    //
    // Note : To use the sub-class without the Timer function
    // Do not create the Windows message handlers 
    // OnDestroy and OnTimer 
    // Comment the line SetTimer(0, 1000, Null)
    // Before the line m_Analog.Create( .....) type the following
    // m_Analog.m_bStandalone = TRUE;
    //

On a CView view-class, follow the same instructions as above, except that m_Analog.Create(....) should be in OnCreate() or OnInitialUpdate() functions.

To Use sub-class CDigital

  • Copy or drag and drop source files Digital.cpp and Digital.h into your project folder.
  • Same procedure as for CAnalog sub-class except that the class name.

Note: m_bStandAlone is presently not applicable here.

How It Works

The SetTimer() function sets up the system timer and the framework repeatedly calls the OnTimer() function every 1/1000th of a second to update the clocks, in the CAnanlog sub-class the Invalidate(FALSE) function calls up the OnPaint() function which paints the clock, in the same manner CDigital clock get painted in the OnPaint() function.

In the digital clock, each character is composed of vertical and horizontal lines. E.g. Number 1 is composed of two vertical lines, number 0 (zero) is composed of seven lines, one horizontal line at the top and one at the bottom, four vertical lines, two at the left and two at the right. Similarly, number 8 is composed of the same lines pattern as number 1 with an additional at the center and so on, depending on the character passed to it, the function DrawCharacter paints the character as below:

C++
void CDigital::DrawCharacter(CDC *pDC, CString sChar, int nLeft, 
      int nTop, COLORREF clr)
{

  if(sChar == "A")
  {
    pDC->FillSolidRect(nLeft+5  ,nTop+15,   15  ,5, clr); 
    // Top Line
    pDC->FillSolidRect(nLeft    ,nTop+20,  5  ,30, clr); 
    // Left Top
    pDC->FillSolidRect(nLeft+20 ,nTop+20, 5  ,30, clr ); 
    // Right Top
    pDC->FillSolidRect(nLeft+5  ,nTop+32,   15  ,5, clr );  
    // Central Line
    return;
  }

  if(sChar == "P")
  {
    pDC->FillSolidRect(nLeft+5  ,nTop+15,   15  ,5, clr); 
    // Top Line
    pDC->FillSolidRect(nLeft    ,nTop+20,  5  ,30, clr); 
    // Left Top
    pDC->FillSolidRect(nLeft+20 ,nTop+20, 5  ,12, clr ); 
    // Right Top
    pDC->FillSolidRect(nLeft+5  ,nTop+32,   15  ,5, clr );  
    // Central Line
    return;
  }

  if(sChar == "M")
  {
    pDC->FillSolidRect(nLeft    ,nTop+15,  15 ,5, clr); 
    // Top Line
    pDC->FillSolidRect(nLeft-5  ,nTop+20,  5  ,30, clr); 
    // Left Top
    pDC->FillSolidRect(nLeft+15 ,nTop+20,  5  ,30, clr ); 
    // Right Top
    pDC->FillSolidRect(nLeft+5  ,nTop+15,  5  ,15, clr ); 
    // Small Line
    return;
  }

  if(sChar == ":")
  {
    pDC->FillSolidRect(nLeft+12 , nTop + 12 , 7, 7,clr);
    pDC->FillSolidRect(nLeft+12 , nTop + 40 ,7, 7,clr);
    return;
  }

  if((sChar == "0") ||
     (sChar == "2") ||
     (sChar == "3") ||
     (sChar == "5") ||
     (sChar == "6") ||
     (sChar == "7") ||
     (sChar == "8") ||
     (sChar == "9"))
     pDC->FillSolidRect(nLeft,nTop,25,5, clr); 
     // Top Line

  if((sChar == "0") ||
       (sChar == "4") ||
     (sChar == "5") ||
     (sChar == "6") ||
     (sChar == "8") ||
     (sChar == "9"))
     pDC->FillSolidRect(nLeft-5,nTop+5,5,20, clr); 
     // Left Top

  if((sChar == "0") ||
     (sChar == "1") ||
     (sChar == "2") ||
     (sChar == "3") ||
     (sChar == "4") ||
     (sChar == "7") ||
     (sChar == "8") ||
     (sChar == "9"))
     pDC->FillSolidRect(nLeft+25,nTop+5,5,20, clr ); 
     // Right Top
  
  if((sChar == "2") ||
     (sChar == "3") ||
     (sChar == "4") ||
     (sChar == "5") ||
     (sChar == "6") ||
     (sChar == "8") ||
     (sChar == "9"))
     pDC->FillSolidRect(nLeft,nTop+25,25,5, clr );  
     // Central Line
  
  if((sChar == "0") ||
     (sChar == "2") ||
     (sChar == "3") ||
     (sChar == "5") ||
     (sChar == "6") ||
     (sChar == "8") ||
     (sChar == "9"))
     pDC->FillSolidRect(nLeft,nTop+50,25,5, clr );  
     // Bottom Line

  if((sChar == "0") ||
     (sChar == "2") ||
     (sChar == "6") ||
     (sChar == "8"))
     pDC->FillSolidRect(nLeft-5,nTop+30,5,20, clr ); 
     // Bottom Left

  if((sChar == "0") ||
     (sChar == "1") ||
     (sChar == "3") ||
     (sChar == "4") ||
     (sChar == "5") ||
     (sChar == "6") ||
     (sChar == "7") ||
     (sChar == "8") ||
     (sChar == "9"))
     pDC->FillSolidRect(nLeft+25,nTop+30,5,20, clr); 
     // Bottom Right
}

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
India India
Nothing to boast about

Comments and Discussions

 
Questionprob Pin
bipana14-Sep-10 17:33
bipana14-Sep-10 17:33 
GeneralGreat job... Pin
Girish Nurani Sankaranarayanan26-Nov-04 0:46
Girish Nurani Sankaranarayanan26-Nov-04 0:46 
Generalwell Pin
surgeproof6-Nov-04 1:48
surgeproof6-Nov-04 1:48 
GeneralPoor design Pin
Vagif Abilov8-Aug-02 4:35
professionalVagif Abilov8-Aug-02 4:35 
Generalbad implementation Pin
Michel Wassink4-Aug-02 20:00
Michel Wassink4-Aug-02 20:00 
GeneralOk... Pin
Shog94-Aug-02 7:40
sitebuilderShog94-Aug-02 7:40 
GeneralRe: Ok... Pin
alex.barylski4-Aug-02 16:55
alex.barylski4-Aug-02 16:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.