Click here to Skip to main content
15,861,168 members
Articles / Programming Languages / C++
Article

World Time

Rate me:
Please Sign up or sign in to vote.
4.90/5 (28 votes)
14 Mar 2004CPOL6 min read 89.3K   5K   37   17
Displays current time in various timezones. Also demonstrates some Win32 API programming tricks.

Sample Image - WorldTime.jpg

Introduction

This application runs as an icon in the system tray and displays the current time in different parts of the world. A tooltip also shows the current time in the place which is set as the default.

The idea of making this application came to me when I started work here in Japan. I come from India and everytime I needed to contact somebody back home, maybe by telephone or by chat, I had to first find out what time it was there. I found it to be annoying to always subtract 3.5 hours from the current Japan time (And I always got it wrong). When I first created this application, it showed only the current time in India. I called the program 'India Time' then. That's when I thought of changing it to 'World Time'.

Since this application didn't require any window to be displayed, I decided on a windows application (Not using MFC). I didn't want it to include classes like CMainFrame or any CView derivatives which I'm not going to use. A registry class in included, which uses the stl vector class for enumeration.

For most of us, the code of a windows application is a real chaos, where functions span thousands of lines with big switch statements. With the help of the code in this article I would also like to share some tips that most people programming using Win32 APIs do not do. Following these rules should get you out of the nightmare of programming using only the Win32 API.

Something about the demo program

The program creates an overlapped window which is never displayed (I call this a hidden window) and a tray icon. The popup menu to be displayed when the tray icon is right clicked is created dynamically. Initially, when the popup menu is created, some items like 'Exit', 'Add Timezone' and a couple of separators are inserted into the menu. Many timezone information are stored in the registry. This information is read, loaded and sorted into a vector at startup. When the user right clicks the tray icon to display the popup menu, the timezone information is taken from the vector and the corresponding time is calculated with respect to the current system time. These times are then added to the popup menu before it is displayed.

There is an option in the popup menu called 'Add Timezone'. Using this the user can add a new timezone. I have currently not given any options for deleting or modifying a timezone. But that can be easily done by extending the 'Add Timezone' dialog. The dialog box accepts the name of the place and the difference in time from the Greenwich Mean Time (GMT). On Clicking the 'Set' button, this information is added to the registry and the menu.

Add Timezone Dialog

One of the timezones in the menu can be set as the default timezone by clicking on it. What this means is that it will be shown as a tooltip of the tray icon.

Using the code

Here a brief description of the projects files and their contents

Stdafx.hIncludes the windows and C runtime header files.
Registry.hClass declaration of the CRegistry class.
Registry.cppImplementaion of the CRegistry class.
WorldTime.hContains a few #define values and function prototypes.
WorldTime.cppMain code of the application which contains the WinMain function.
WndFunc.hFunction prototypes dealing with the main hidden window and the tray icon.
WndFunc.cppFunction definitions of the above mentioned functions.
DlgFunc.hFunction prototypes dealing with the 'Add Timezone' dialog box.
DlgFunc.cppFunction definitions of the above mentioned functions.

Most programmers would write this propram without using the WndFunc and DlgFunc files. The whole program will usually be written in the WorldTime.cpp file, which will eventually not be an easy ride to maintain. What I have done here is to logically group functionality dealing with the tray icon and the dialog box into separate files. Using this technique, the switch statements in the main file becomes very simple.

Here is the switch statement of the procedure dealing with the dialog box messages.

LRESULT CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) 
    {
    case WM_INITDIALOG:
        DlgFunc::OnInitDialog(hDlg, message, wParam, lParam);
        break;

    case WM_COMMAND:
        DlgFunc::OnCommand(hDlg, message, wParam, lParam);
        break;

    case WM_NOTIFY:
        DlgFunc::OnNotify(hDlg, message, wParam, lParam);
        break;
    }

    return 0;
}

Here each message received is delegated to a function, thereby giving it an MFC feel. You will also notice the use of namespaces (DlgFunc::), which makes it possible to have functions with the same name in different files. The DlgFunc.h and Wndfunc.h files have the function prototypes declared within a namespace. In this code, both the WndFunc and DlgFunc namespaces have the same OnCommand function. Another thing to notice here is that each delegate function in the switch statement has the same signature. This way it would be possible to completely eliminate the switch statement by using function pointers or pointer-to-member operators (.* and ->*).

Something more about the code

Now lets look at some things worth mentioning in the code.

The Registry.h file has a VALUES structure used while enumerating registry values. The structure contains a union of a character array and a dword, because a registry value can only either be a string or a dword or a binary value. The class currently does not support binary values.

The VALUES structure has an overloaded < (less than) operator defined. This is used by the STL sort algorithm to sort the contents of the vector.

To change the registry path for storing timezones, change the REG_KEY #define constant in the WorldTime.h file.

The ShowPopupMenu function in the WndFunc.cpp file is called whenever the user right clicks on the tray icon. This function first deletes all place entries from the menu and then adds them back after calculating the current time.

The GetZoneTime function in the WndFunc.cpp file returns the formatted time based on the passed in bias information stored in the registry. The actual time calculation is done using the SystemTimeToTzSpecificLocalTime API which takes the timezone information and the Greenwich Mean Time as input parameters and returns the specific local time. The GetSystemTime API gives the GMT based on the system time.

The OnTimer function in the WndFunc.cpp file is called by a timer to change the tooltip of the tray icon. When the application is started or when the user changes the default timezone, a timer of 10 milliseconds interval is set. This timer event is deleted within the OnTimer function and a new timer of 1 minute interval is set.

I guess there is nothing worth mentioning in the DlgFunc.cpp file, but the controls accepting timezone information are list boxes whose values are changed depending on the notification sent by the updown control (spin button). And also the items in the list boxes are selected when they get focus and deselected when they loose focus.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
Santosh works as a Technical Architect in God's own Country, Kerala, India. He has been involved with C/C++ since 1996. Started with a few game clones and then went on to commercial software. He started his stint with software training and then went on to professional software development, design and architecture. Unix and C were his favorite in his early days but later grew very fond of Windows especially with the release of Windows NT 4.0 and Visual C++ 6.0. Technologies like COM and .Net fascinate him. He still lurks around Unix once in a while.

Music and the guitar are his second favorites and he manages to impress his friends with these skills when there are nobody better than him around. He is a patient and fun loving character who does not think too much about the future. He hates wasting time and so is working hard (in his dreams) to perfect instant transportation and time travel.

Oh! Yes. He loves Superman. Always did and always will. He would love to become a Superman and rid the world of all evil.

He used to be a Microsoft Visual C++ MVP (October 2009 - September 2013)

Comments and Discussions

 
QuestionWhat about ,Net 2.0 Support? Pin
StotleD14-Jul-07 12:22
StotleD14-Jul-07 12:22 
Generalnice Pin
anujshail17-Feb-07 3:23
anujshail17-Feb-07 3:23 
GeneralNice! Pin
Ravi Bhavnani15-Mar-04 3:26
professionalRavi Bhavnani15-Mar-04 3:26 
GeneralRe: Nice! Pin
«_Superman_»15-Mar-04 13:09
professional«_Superman_»15-Mar-04 13:09 
GeneralRe: Nice! Pin
«_Superman_»15-Mar-04 13:12
professional«_Superman_»15-Mar-04 13:12 
GeneralRe: Nice! Pin
Joey Bloggs20-Mar-04 14:01
Joey Bloggs20-Mar-04 14:01 
GeneralRe: Nice! Pin
ThatsAlok10-May-05 23:41
ThatsAlok10-May-05 23:41 
GeneralRanking Pin
«_Superman_»14-Mar-04 22:17
professional«_Superman_»14-Mar-04 22:17 
GeneralAt least you may try... Pin
Kochise14-Mar-04 22:25
Kochise14-Mar-04 22:25 
GeneralRe: At least you may try... Pin
«_Superman_»14-Mar-04 22:28
professional«_Superman_»14-Mar-04 22:28 
General&quot;It's beyon logic&quot; Spock Pin
Kochise15-Mar-04 3:08
Kochise15-Mar-04 3:08 
GeneralRe: &quot;It's beyon logic&quot; Spock Pin
«_Superman_»15-Mar-04 13:00
professional«_Superman_»15-Mar-04 13:00 
GeneralRe: &quot;It's beyon logic&quot; Spock Pin
Malali15-Mar-04 13:20
Malali15-Mar-04 13:20 
GeneralRe: &quot;It's beyon logic&quot; Spock Pin
«_Superman_»15-Mar-04 13:32
professional«_Superman_»15-Mar-04 13:32 
GeneralAt least, you cannot vote... Pin
Kochise15-Mar-04 20:01
Kochise15-Mar-04 20:01 
GeneralRe: At least you may try... Pin
«_Superman_»14-Mar-04 22:32
professional«_Superman_»14-Mar-04 22:32 
GeneralRe: Ranking Pin
TomKat15-Mar-04 4:02
TomKat15-Mar-04 4:02 

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.