Figure 1 - Periodic Reminder Application
Introduction
I found that being a programmer, sometimes I find myself sitting in a poor posture in front of the computer. This can eventually lead to debilitating back pain. Upon a recent visit to the physical therapist, I was given the advice that I should set my computer once an hour to remind me to correct my posture. (It seems like a silly process, but you really need to retrain yourself if you've been sitting wrong for a long time. ) My wife figured this was a good opportunity to create a C# Application that reminds me every once in a while to sit correctly at the keyboard. (Ergonomicists out their can feel free to download this application for their clients.). The application will allow you to set a start time, an end time, and an interval for the reminder you wish to display. The reminder app will show up as a tiny hourglass icon in your system tray. The reminder message will popup in the system tray according to your settings. Optionally, you can set a sound beep (just in case you never notice the system tray).
Figure 2 - Reminder Balloon in the Task Bar
Design
The program handles the various states of the reminder timer inside a Windows Form. The states are controlled by comparing current time to the time settings set in the Windows Form. Figure 3 shows the state diagram describing the function of the reminder application:
Figure 3 - State Diagram drawn using the WithClass UML Tool
Most of the application is implemented every time the windows form timer triggers the interval event handler. In this event handler, the balloon is displayed and the optional sound is played. The timer triggers according to the Remind Every: field in the dialog shown in figure 1. In the state diagram the message balloon display is represented as a transition from the Started state to the Showing Balloon state. The balloon is hidden again when going from the Showing Balloon state to the Started State after 2 seconds have passed. The class diagram for this application only contains two classes the Windows Form and the Sound class as shown in figure 4:
Figure 4 - Periodic Reminder Design Reverse Engineered Using WithClass
Code
As you can see from the design in figure 4, the code for this project is mostly self contained in the Windows Form. When the start button is clicked, the notify icon is initiallized with values from the Windows Form by calling InitializeNotifyBalloon and SetupTimer shown in Listing 1:
Listing 1 - Initializing the notify icon and
private void InitializeNotifyBalloon() { notifyIcon1.BalloonTipTitle = "Reminder"; notifyIcon1.BalloonTipText = txtMessage.Text; }
private void SetupTimer() { // start the timer at the user desired interval timer1.Interval = (int)udInterval.Value * 1000 * 60; // convert minutes to milliseconds timer1.Start(); } |
Once the timer is started, we just need to show the balloon every time the timer event is triggered. The timer event handler does this for us as shown in listing 2:
Listing 2 - Showing the balloon via the timer event handler
private void timer1_Tick(object sender, EventArgs e) { // check to see if we reached the start time if (CheckIfStartTimeHappened()) { // show the balloon in the task bar hear ShowReminder(); CheckIfWeReachedTheEndTime(); }
} |
Showing the balloon message in the task bar happens through the Notify Icon's ShowBalloonTip method as seen in Listing 3. The number passed into the ShowBalloonTip method is the timeout. The timeout is supposed to be the amount of time in milliseconds when the balloon will fade away. Unfortunately this number is ignored by the operating system, because the operating system will not dismiss the balloon until after a minimum of 10 seconds and a maximum of 30 seconds. (Can't quite figure out why this number is even in the call).
Listing 3 - The ShowReminder Method
private void ShowReminder() {
// notify the user with a balloon message in the task bar notifyIcon1.ShowBalloonTip(2); if (chkSound.Checked) // play a beep sound if the user chose it { PlaySound(); } } |
After struggling for a bit, I figured out a way around the balloon message timeout bug though. If you turn the NotifyIcon invisible and then visible again, it causes the balloon to go away. Below is the code to make the balloon disappear 2 seconds after it is shown.
Listing 4 - Making the balloon go away on time
private void notifyIcon1_BalloonTipShown(object sender, EventArgs e) { // make sure the dialog is not being edited when we put the GUI thread to sleep if (this.Visible == false) { System.Threading.Thread.Sleep(2000); notifyIcon1.Visible = false; notifyIcon1.Visible = true; }
} |
Conclusion
Sometimes the computer can really come to your rescue with a day-to-day problem. (And reminding yourself to maintain good posture is not just some thing your third grade teacher told you for the heck of it.) This application can be used for other periodic reminders (like every hour get away from the code and breath the fresh air!!). Anyway, enjoy the periodic reminder and get back in shape.