Creating an Alarm Clock in the System Tray
- Posted: Oct 31, 2006 at 2:08 AM
- 12,194 Views
- 25 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
| In this article, we will create an alarm clock application | |
|
Difficulty: Easy
Time Required:
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware:
Download:
|
|
Ever since the earliest versions of Windows, it has always surprised me that there is no built-in alarm clock. For people with Outlook, reminders fill this void; however, you don't always want an event in your calendar. Others could use the system Task Scheduler, but it's really overkill for a simple alarm, not to mention difficult to use for this purpose! Ideally, the system clock should just have a tab for setting an alarm, but of course this isn't available.
For this column I decided to see what it would take to use Visual Studio 2005 to create a simple alarm clock that would hide to the system tray, display a notification, and optionally play a sound. Once an alarm is passed, it should roll over to the same time/next day, and have a checkbox for enabling and disabling the alarm. The user interface should be easy-to-grasp with as few controls as possible. I'm a firm believer in "less is more" in user interface design.
Creating the alarm clock enabled me to work with both new and improved features in Visual Studio 2005. The highlighted code samples use Visual Basic 2005 Express Edition; however, any of the Visual Studio Express Editions can be used to create a similar sample. Beta 2 of the Express editions can be downloaded from http://msdn.microsoft.com/express.
From a design point of view, I knew that I wanted an icon to appear in the system tray (the row of icons by the system clock). I knew that I wanted the alarm to show as a system notification, not as a message box. System notifications are a great feature in Windows XP which allow you to alert a user without stealing focus and without requiring immediate action. .NET 2.0 makes notifications a snap. I also wanted to play a sound when the alarm fired. This is trivial with Visual Basic, and only requires a few lines of code in C#. Altogether, the project went smoothly and I was able to implement exactly what I had imagined.
The first step is to create a Windows Forms project in Visual Studio. This creates a mostly empty project, containing a single blank form. This form will become the settings dialog, so start by highlighting the form in the Solution Explorer and pressing F2. This makes the filename editable. A good name is simply "AlarmSettingsForm". Drag two textbox controls for the sound filename and the alarm message respectively. Drag a checkbox to enable and disable the alarm, a DateTimePicker for the actual time entry, buttons for OK, Cancel, file browse, and corresponding labels.
Once the UI layout is complete, the next step is to add the system tray icon. This requires no Win32 calls, as all of the features are completely available in managed code. From the Toolbox, drag a NotifyIcon control to the design surface. Because it is essentially a non-visual control, it will actually snap to the surface beneath the form itself. Set the three BalloonTip properties for a message to appear when notification is triggered.
In order for the notify icon to always be displayed visually at runtime, you will need to create an icon file. From the Solution Explorer, add a new item of type Icon File. From here you are on your own! As you can see, I don't really consider myself an artist, but I can throw something together in a pinch (it's a bell in case you're wondering).
(click image to zoom)
You'll need to associate the icon file with the NotifyIcon control. You will also need to create a context menu. This is the menu to appear when you right-click the icon in the tray. If you right-click the system clock you see a menu for Toolbars, Adjust Date/Time, Customize Notifications, and more. To create a similar menu, drag a ContextMenuStrip from the Toolbox, and then select it to start editing. Add options for Settings, Enabled, and Exit.
In order to allow your application to sound an alarm, you need to know when the specified time has been reached. You can't directly be notified at a given time, but you can determine this yourself without incurring much overhead. Drag a Timer control to the design surface and set an interval of 1000. The timer interval is measured in milliseconds, so when enabled, the control will fire once each second. In the Tick event handler of the timer control add the following code:
Visual C#
if( DateTime.Now.CompareTo(alarmTime) >= 0 )
{
// Add a day to the alarm to reset it for the next day RolloverTime(); // Show the notification for up to a minute. // After that, no one must be paying attention! AlarmNotifyIcon.BalloonTipText = (alarmMessage.Length > 0?alarmMessage:"Attention!");
AlarmNotifyIcon.ShowBalloonTip(60000);
// Play the alarm sound if( alarmSound.Length > 0 )
{
player.PlayLooping();
}
}
Visual Basic
If DateTime.Now.CompareTo(alarmTime) >= 0 Then ' Add a day to the alarm to reset it for the next day RolloverTime() ' Show the notification for up to a minute. ' After that, no one must be paying attention! AlarmNotifyIcon.BalloonTipText = _ IIf(alarmMessage.Length > 0, alarmMessage, "Attention!")
AlarmNotifyIcon.ShowBalloonTip(60000)
' Play the alarm sound If alarmSound.Length > 0 Then My.Computer.Audio.Play(alarmSound, AudioPlayMode.BackgroundLoop) End If End If
Notice the first call is to the RolloverTime method. This has not been defined yet, but is very important for simulating a real-world alarm clock. If you set the alarm for 3:00 P.M., internally the DateTime object will reflect 3:00 P.M. of a certain day. Once the alarm time is reached, it must be changed to 3:00 P.M. of the next day. Using the constructor to create a new instance of DateTime rather than calling the AddDays method removes any worry about the current date portion when a new time is selected. Here is the code to accomplish that:
Visual C#
private void RolloverTime()
{
// If the user selects a time already passed, it must be for tomorrow if( DateTime.Now.TimeOfDay.CompareTo(alarmTime.TimeOfDay) > 0 )
{
alarmTime = new DateTime(DateTime.Now.Year,
DateTime.Now.Month, DateTime.Now.Day + 1,
alarmTime.Hour, alarmTime.Minute, alarmTime.Second);
}
// Otherwise, set it for today else { alarmTime = new DateTime(DateTime.Now.Year,
DateTime.Now.Month, DateTime.Now.Day,
alarmTime.Hour, alarmTime.Minute, alarmTime.Second);
}
}
Visual Basic
Private Sub RolloverTime()
' If the user selects a time already passed, it must be for tomorrow If DateTime.Now.TimeOfDay.CompareTo(alarmTime.TimeOfDay) > 0 Then alarmTime = New DateTime(DateTime.Now.Year, _
DateTime.Now.Month, DateTime.Now.Day + 1, _
alarmTime.Hour, alarmTime.Minute, alarmTime.Second)
' Otherwise, set it for today Else alarmTime = New DateTime(DateTime.Now.Year, _
DateTime.Now.Month, DateTime.Now.Day, _
alarmTime.Hour, alarmTime.Minute, alarmTime.Second)
End If End Sub
Visual Studio 2005 makes it easy to work with notifications, timers, tray icons, and sound. A next step might be to add "snooze" functionality. Perhaps clicking the notification elsewhere than the close button would delay the alarm for several minutes. Changing the tray icon based on the alarm being enabled, disabled, or ringing would also be a nice touch. If you haven't already, download Visual C# 2005 Express Edition and try this out. Get started at http://msdn.microsoft.com/express.
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?
@Hung: The VB link is on the top of the article for downloading.
Can I create this in Microsoft Visual Basic? (excel)
wav files won't play
we are using Visual Basic 2005
pls help
@Upheaval is it throwing exceptions? Did you attempt to do a small scale test?
I need a modification to use the application for our Toastmasters meetings as a countdown timer. Our speeches can last between x and y minutes. After x minutes are reached, the green light of the traffic light switches to yellow. When the maximum time y is reached, the red light is activated. Anyone?
I'd have two threads. One turns on your yellow light, the other the red light. Thread sleep them for the desired milliseconds.
Another way to do this is to start the program, Thread.Sleep(neededMilliseconds). then turn on the yellow light. Then subtract the Redlight time minus the yellow light time to figure out the needed milliseconds and sleep and turn on the red light.
Okay so I'm kinda new to C# and I've been doing a few projects to get into the swing of it.
This is an app I will seriously use, but I'm getting an error on SoundBrowserDialog & EnabledToolStripMenuItem saying they don't exist in the current content.
I'm sure its something right in front of me, but just to make sure I downloaded the source code and double, triple, quadruple checked my code and event handles.
Your version ran perfectly on my computer, but I keep getting these errors when I try to Debug my own. Any suggestions?
This is the Best solution that i can show my appliaction icon in system tray and can show ballon message.
Wish u best of luck and thnx
@smith yeah, moving foward all Coding4Fun projects will have a "Run It", "Build It" set up as more and more of the stuff we do actually has useful applications
This is a pretty old article actually, we'll rebuild it in the future I'm betting.
Wanted such an app today... too lazy to code my own but preferred code to a compiled freeware app. Downloaded, ran through the VS 2008 upgrade wiz, ran the exe and I for once I left the office on time for my son's school thing. Thanks Arian
. Oh, on a typical programmer's Vista 32-Biz without the Windows Media Plyer SDK installed it of course faulted out on an MP3 but was fine with a real wav.
@howBoutTheObvious well, doing that is possible but requires some extra work. You'll need a font that is crisp but very small like SilkScreen (http://www.kottke.org/plus/type/silkscreen/) and you'll have to create the graphic on the fly. I did the quick math and that font should work. 3 pixels for space, 1 for the colon, that gives you 12 pixels left and each SilkScreen number is 4 pixels in width.
This may not be a bad program to update and do something like that in the future.
Very cute. But come on, the darn clock's TIME (TEXT) should appear in the tray. How to do that?
@Dummy1912 social.msdn.microsoft.com/.../05dc2d35-1d45-4837-8e16-562ee919da85 looks like that should be able to do it. You still have the issue of if the physical speakers have their volume turned down.
How to get if your pc sound is on?
so you can hear the message.
@Tom doing a quick glance at the article, I'd do two things, create a new class called "alarm" with a DateTime(alarmTime) and bool(alarmEnabled) then in the app I'd have a list of alarms I'd follow the pattern Arian laid out since we now it works but anytime you see alarmTime or alarmEnabled, you'd have to alter the code to work with the new class.
One other item you'd have to do is made a new user interface as well.
I am new to vb and have written an alarm close to this but with some bells and whistles. Now I want to add the ability to store and run several alarms concurrently. I do not expect a full explanation but some useful pointers or if you have something close for me to look at it would help greatly. Does anyone know how to accomplish this?
I have remade the whole project, but I have no idea about creating the dll. Does anyone have an example of using the class as suggested? I cannot find related information that helps.
does anyone have a sample of using a class in this way? I tried looking up some examples but I did not understand it.
@Tom so once you have the project fully done, hit "f5" on your keyboard, Debug->Start Debugging from the menus, or there is a play icon in the toolbars
The physical files for the project will be where you saved the
app folder\bin\debug\
The debug may be release depending on what you set your compile to, i'm going to bet it is debug however.
Another quick way to get to the physical files is right click on your project or a folder in that project and go to "Open Folder in Explorer"
@ajp, This is a .NET example. You can write the app in c/c++ but would have to be done differently. You could write in in Managed C++ and the code would be, for the most part, the same.
Can we write this code in C?
@Stephen thanks for providing useful feedback!
Just in case you didnt know, you can also initiate a new DateTime object using DateTime.Add or DateTime.Subtract, each taking a TimeSpan argument, and you give the TimeSpan object a value of a day and it makes your code "read" better as to your intent
I am using visual 2008 and how Can I show Time as mention in Your appliction alarmtime,It only show the day ,month,year ,and current time ,how can I srt the alrmtime
@shashikant if you look in the tick event, you'll see how the alarm actually starts. The article above outlines this part too.
if( DateTime.Now.CompareTo(alarmTime) >= 0 ) is how the application actually checks if it is time to fire off the alarm.
Remove this comment
Remove this thread
close