Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Creating an Alarm Clock in the System Tray

  In this article, we will create an alarm clock application
Arian Kulp's Blog

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 here for larger image

(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

Conclusion

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.

Tags:

Follow the Discussion

  • Clint RutkasClint I'm a "developer"

    @Hung:  The VB link is on the top of the article for downloading.

  • HungHung

    Can I create this in Microsoft Visual Basic? (excel)

  • UpheavalUpheaval

    wav files won't play

    we are using Visual Basic 2005

    pls help

  • Clint RutkasClint I'm a "developer"

    @Upheaval is it throwing exceptions?  Did you attempt to do a small scale test?

  • SabineSabine

    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?

  • Clint RutkasClint I'm a "developer"

    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.

  • JanieJanie

    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?

  • JavedJaved

    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

  • Clint RutkasClint I'm a "developer"

    @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 Smiley

    This is a pretty old article actually, we'll rebuild it in the future I'm betting.

  • smithsmith

    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 Smiley.  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.

  • Clint RutkasClint I'm a "developer"

    @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.

  • howBoutTheObvioushowBoutThe​Obvious

    Very cute.  But come on, the darn clock's TIME (TEXT) should appear in the tray.  How to do that?

  • Clint RutkasClint I'm a "developer"

    @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.

  • Dummy1912Dummy1912

    How to get if your pc sound is on?

    so you can hear the message.

  • Clint RutkasClint I'm a "developer"

    @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.

  • TomTom

    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?

  • tomtom

    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.

  • TomTom

    does anyone have a sample of using a class in this way? I tried looking up some examples but I did not understand it.

  • Clint RutkasClint I'm a "developer"

    @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"

  • Clint RutkasClint I'm a "developer"

    @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.

  • ajpajp

    Can we write this code in C?

  • Clint RutkasClint I'm a "developer"

    @Stephen thanks for providing useful feedback!

  • StephenStephen

    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 Big Smile

  • shashikantshashikant

    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

  • Clint RutkasClint I'm a "developer"

    @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

Comments Closed

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.