Countdown to...
- Posted: Nov 22, 2006 at 9:07 PM
- 794 Views
- 4 Comments
Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
| This application starts with a fairly simple premise—counting down to a date—then starts adding interesting features. | |
|
Difficulty: Intermediate
Time Required:
Less than 1 hour
Cost: Free
Software: Visual Basic or Visual C# Express Editions,
Hardware:
Download:
|
|
Well, the year's winding down to an end, and the holiday season is upon us. Whether you are looking forward to Christmas (December 25), Hanukkah (December 26-January 1), Winter Solstice (December 21), or my birthday (December 29), you are probably counting down the days. Perhaps even the hours, minutes, and seconds until that great event (better get my presents sent a few days early so they arrive in time!). Looking at a calendar each day isn't really good enough. What you really need is a real-time countdown timer so you never lose your focus. What better way to do this than with a countdown utility application built using the .NET Framework! In this In the Box (Holiday Guide) installment, I decided to create a System Tray utility to display a countdown as a tooltip, and optionally as an overlay on the screen.
Code for the sample is available as a download at the top of the page, and is offered in both C# and Visual Basic. You will need either the C# or Visual Basic version (or both) of Visual Studio 2005 Express Edition. These have just been released out of beta, and are available for free for one year! Take advantage of this while you can. What better way to get started writing great .NET code?
In writing this application, I wanted to display a countdown, but also glitz it up a bit. Just showing a battleship-grey dialog with a standard title, minimize/close buttons and borders didn't sound very appealing. Instead, I decided to explore some methods of creating non-traditional windows. Though the effect is still somewhat simplistic, it was a great introduction to "windows without borders" (sounds like a political organization!). As with typical System Tray applications, hovering over the icon displays the application name. Of course it also displays the countdown itself. Right-clicking the icon displays a context menu, and you have the option of changing the settings, or exiting (but why would you do that?).
The fun part started with customizing the window. You can get rid of the Minimize/Maximize/Close button in the upper right by setting the form's
ControlBox property to false. Eliminating the title bar entirely is accomplished by setting the form's
Text property to an empty string. The borders go away when you set FormBorderStyle to
None. Once you've done that, you are left with a grey rectangle floating on the screen. Two problems emerge. First of all, you can't close it, and second, you can't move it. You can alleviate the first issue by setting the form's visibility
using a context menu attached to the icon in the System Tray. The second problem is more challenging.
It turns out that moving a form isn't especially difficult, but if you need to do it yourself, it does take a little work. It requires the capture of two events: MouseDown and MouseMove. The basic gist of it is, upon the MouseDown event, you need to capture the coordinates of the mouse. Then, for each MouseMove event, invoke the form's Move method taking into account the delta movement of the mouse. In other words, if the mouse click was detected at coordinates (0, 0), then a move event was triggered at coordinates (10,10), move the form from its original position, +10 on the x-axis, and +10 on the y-axis. It's clearer looking at some code:
Visual C#
// Class-level declaration private Point mouseOffset; ... private void countdownLabel_MouseDown(object sender, MouseEventArgs e) { mouseOffset = new Point(-e.X, -e.Y); } private void countdownLabel_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { Point mousePos = Control.MousePosition; if (constrainToRight) { this.Top = Control.MousePosition.Y + mouseOffset.Y; } else { mousePos.Offset(mouseOffset.X, mouseOffset.Y); this.Location = mousePos; } } }
Visual Basic
'Class-level declaration Dim mouseOffset As PointPrivate Sub countdownLabel_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) _ Handles countdownLabel.MouseDown mouseOffset = New Point((e.X * -1), (e.Y * -1)) End Sub Private Sub countdownLabel_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) _ Handles countdownLabel.MouseMove If (e.Button = Windows.Forms.MouseButtons.Left) Then Dim mousePos As Point = Control.MousePosition If constrainToRight Then Me.Top = (Control.MousePosition.Y + mouseOffset.Y) Else mousePos.Offset(mouseOffset.X, mouseOffset.Y) Me.Location = mousePos End If End If End Sub
You can monitor these mouse events from the form itself, or from any control. In this case, the form will contain one visual control: a label. It's the label that will display the current countdown string. In order to get rid of the plain rectangular window shape surrounding it, you can actually turn it invisible. Set the form's TransparencyKey property to Control, and any grey regions will disappear. It's a great effect, it's easy, and it can lead to some interesting effects. Imagine if you used a bitmap as the background of the form. It would be easy to add rounded edges, or other irregular effects this way.

Figure 1. The Settings Dialog
Once it was possible to move the frame, I decided to add a feature to constrain the countdown to the right side of the screen. This involves a slight change to the code in the
MouseMove event handler. Using the width of the screen and the width of the countdown label, you can calculate how far the form's coordinates should be. The label control's
AutoSize propery was set to true, so it makes it very easy to determine the width of the text. Once you've done all of this, just use the length information to calculate the left edge of the form and force it to that value, regardless of
the mouse movement. Of course, you could constrain to the left side even easier—just force the X coordinate to always be zero.
Two more visual effects are to allow you to set the countdown as the topmost form, and to alter the overall transparency. Setting the
TopMost property to true keeps the form on top of all other non-topmost windows. As it turns out, this is especially useful when trying to click on the form to move it! Because of the way opacity works, getting rid of the form background
makes it necessary to click exactly on black pixels (in the countdown itself) to actually move anything. This is harder than it seems. Changing the transparency allows you see other forms behind the countdown. As this information isn't something you need to
fully focus on at all times, this is a nice feature. Just set the Opacity
property to a value from 0 to 100.

Figure 2. Specifying a low Opacity value
Finally, the countdown itself: a timer ticks each second. On the Tick event, the current date is compared to the configured date. If the date has been reached, an alert is displayed in the countdown form and as a System Tray tooltip. Otherwise, a string is built up to display the number of days, hours, minutes, and seconds until the event. This is pretty easy string composition using the Append method of a StringBuilder object. The StringBuilder class is a more efficient way of concatenating strings than the "plus" operation. This is because of the way memory is allocated when the string value changes.
The application works as-is, but can certainly stand some enhancements. For one thing, playing a sound or a song when the event is reached would be fun! A festive holiday tune, birthday song, or maybe a voice recording would make sense. Using a nice bitmap for the background of the form could provide an easier place to click for dragging it, and would be visually appealing. See what else you can come up with.
This application starts with a fairly simple premise—counting down to a date—then starts adding interesting features. See what you can do to spice up your applications. Go to the Visual Studio Express Web site at http://msdn.microsoft.com/vstudio/express/default.aspx. Remember that all editions are now free for one year, and you can download as many versions as you'd like. Download one or more today, and get started writing great applications!
Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation,
please create a new thread in our Forums,
or
Contact Us and let us know.
Follow the Discussion
Oops, something didn't work.
What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in. You need to be signed in to Channel 9 to use this feature.What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in and view them all on your notifications page.sign up for email notifications?
Am I missing something? The article says that the code for the app is available as a download at the top of the page. When I download it, it comes as a .msi file which tries to install the program on my computer, not give me that code. Am I such a newbie that I'm missing something totally obvious?
Thanks!
@Don
If you did a default install, should be something like:
C:\Users\crutkas\Documents\MSDN\Holiday Countdown - CS\
This is with my user account and running Vista, XP's path may be different.
Then open up the Countdown.sln file. The solution will require a conversion if you have Visual Studio 2008. Just click through the conversion wizard.
The code is no longer available for download. Can you point me to where to get it or put it back in place, please? Thanks.
@Shane, I just tried both links and they work.
Remove this comment
Remove this thread
close