A Digital Clock


Once having discussed timers, perhaps a clock is the most natural application of such knowledge. Two clocks are discussed in this chapter - one with a digital (or textual) display and the other emulates the old fashioned analog display (with three hands).

Popup windows

The digital clock positions itself in the upper-right corner of the screen and has a dialog frame. A snapshot of the digital clock running is shown below.

Until now, all the windows have been created with the compound style StyleStandard. The enumerator style::Standard is defined in the i++ header as:

Standard= window        |
          caption       |
          system_menu    |
          ThickFrame    |
          minimizeBox   |
          maximizeBox

this style is also referred to as "WS_OVERLAPPEDWINDOW" in Win32 (as distinct from win+). Rather than use the standard style, the style for the digital clock is defined when creating the window, as shown below.

handle window_handle = create_window((const character*)nameAtom,title,
                                   style::Popup | style::DialogFrame | style::system_menu | style::caption);
....

This combination of style bits creates a window of style known as "popup" - with a dialog frame, a title bar and a system menu. This style is most commonly used for dialog frames. Notice that the window cannot be resized (that is, it does not possess sizing borders). Moreover, the system menu has the sizing options disabled; however, the window may still be moved.

Positioning the window

The digital clock positions itself at the top right corner of the screen and ensures that it can accommodate the required text. The portion of the window procedure that performs the required calculations is shown below.

case message::create:
  {
   handle device_context = create_informational_device_context("DISPLAY",(const character*)null,(const character*)null,(const device_mode*)null);
 
   windows::string DateTimeString = FormatDateTime();

   dimensions Extent;
   get_text_extent(device_context,DateTimeString,DateTimeString.Length(),&Extent);

   delete_device_context(device_context);
   Extent = (Extent * 110) / 100;

   int Width  = Extent(0) + 2*get_system_metrics(system_metric::FixedFrameWidth);

   int height = Extent(1) + get_system_metrics(system_metric::Captionheight)
                              + 2*get_system_metrics(system_metric::FixedFrameheight);

   int X = get_system_metrics(system_metric::ScreenWidth) - Width;

   set_window_position(window_handle,0,X,0,
                     Width, height,place::NoZorder | place::NoRedraw);
  }
  break;

By way of querying information, an informational device context is created via the function create_informational_device_context. An informational device context may be used for querying attributes - but is unable to be used to render drawing. A normal device context may also have been used. Note that code within the message message::create is executed prior to the window being made visible. The text extent of the present time is calculated and expanded by 10%. The width and height of the frames as well of the height of the caption is then factored into the size calculation and the size of the window is set.

International date and Time Functions

The rest of the digital clock code is quite straight forward. When a timer message is received, the screen is invalidated and the paint routine does the rest. The paint routine merely formats the text to be centered in the client rectangle (horizontally and vertically). It calls the function FormatDateTime() to acquire the appropriate text to draw. The function FormatDateTime() is shown below.

string FormatDateTime()
{
 character date[30];
 character Time[30];

 get_date_format(locale_user_default,0,null,"dddd MMMM d  ",date,sizeof(date));
 get_time_format(locale_user_default,0,null,null,Time,sizeof(Time));

 return string(date) + string(Time);
}

windows has builtin functions to perform formatting of dates and times. An application should use these functions to deal with dates and times so as to remain internationally compliant. after querying the requisite quantities, strings are concatenated and returned to the drawing routine.