Click here to Skip to main content
14,207,243 members
Click here to Skip to main content
Add your own
alternative version

Stats

154.9K views
5.3K downloads
143 bookmarked
Posted 3 Feb 2003
Licenced CPOL

SystemTrayNotifyIcon with Event Generator

, 3 Feb 2003
Rate this:
Please Sign up or sign in to vote.
This article provides a generic class using which one can easily use a SystemTrayNotifyIcon class with the key functionalities of hiding, showing and animating NotifyIcon and generating events on every changed state of NotifyIcon.

Sample Image - SystemTrayNotifyIcon.gif

Introduction

This is my first article in C#. Here I have tried to provide a generic class that can be used for adding the System Tray Notification property to your C# project. Besides the more common features of any System Tray Notification class (i.e. Hide, Unhide, Animate etc.), this class provides events that are triggered for every change in state of the Notify Icon. My best efforts were to make this class as easy to use as possible and to some extent I am sure I got success but I am waiting for the views of some good critics, which I am sure I will definitely get very soon ;)

Using SytemTrayNotifyIcon class

Step I

Add SystemTrayNotifyIcon.cs in your project.

Step II

Insert the SystemTrayNotification namespace in your project as shown below.

// Step II for using SystemTrayNotifyIcon class in your project
   using SystemTrayNotification;
//

Step III

Declare a reference variable of class SystemTrayNotifyIcon with access modifier of your choice. I am declaring it as private.

// Step III for using SystemTrayNotifyIcon class in your project
   private SystemTrayNotifyIcon m_SysTrayNotify;    
//

Step IV

Now you have to instantiate the above declared reference variable. The best place for this initialization is your main forms constructor. Here you will get five overloaded constructors which you will have to use according to your requirement.

Constructor 1 

// Step IV for using SystemTrayNotifyIcon class in your project
// This is the first constructor, which takes two parameters
// (parameter 1) System.Windows.Forms.Form form 
// (passing reference of main form)
// (parameter 2) bool visible (pass true to show icon 
// in System Tray else false)
   m_SysTrayNotify = new SystemTrayNotification.SystemTrayNotifyIcon(
            this, true);    
//

Constructor  2

// Step IV for using SystemTrayNotifyIcon class in your project
// This is the first constructor, which takes two parameters
// (parameter 1) System.Windows.Forms.Form form 
// (passing reference of main form)
// (parameter 2) bool visible (pass true to show icon 
// in System Tray else false)
// (parameter 3) string toolTip (pass a string to be set
// as tooltip for System Tray Icon)
   m_SysTrayNotify = new SystemTrayNotification.SystemTrayNotifyIcon(
         this, true, "Hoowa!");    
//

Constructor  3

// Step IV for using SystemTrayNotifyIcon class in your project
// This is the first constructor, which takes two parameters
// (parameter 1) System.Windows.Forms.Form form 
// (passing reference of main form)
// (parameter 2) bool visible (pass true to show icon in 
// System Tray else false)
// (parameter 3) string toolTip (pass a string to be set as
// tooltip for System Tray Icon)
// (parameter 4) Icon icon (pass an icon to be set in System Tray)
   m_SysTrayNotify = new SystemTrayNotification.SystemTrayNotifyIcon(
        this, true, "Hoowa!,
        new System.Drawing.Icon("..\\..\\Default Icon\\PakFlag.ico")");    
//

Constructor  4

// Step IV for using SystemTrayNotifyIcon class in your project
// This is the first constructor, which takes two parameters
// (parameter 1) System.Windows.Forms.Form form 
// (passing reference of main form)
// (parameter 2) bool visible (pass true to show icon
// in System Tray else false)
// (parameter 3) string toolTip (pass a string to be set as
// tooltip for System Tray Icon)
// (parameter 4) ContextMenu contextMenu (pass a ContextMenu
// System Tray Notifications)
   m_SysTrayNotify = new SystemTrayNotification.SystemTrayNotifyIcon(
            this, true, "Hoowa!",
            contextMenu);    
//
// Help for creating context menu
// Declaration
   private ContextMenu contextMenu = new ContextMenu();
// Initialization
   contextMenu.MenuItems.Add(new MenuItem("&Hide"));
   contextMenu.MenuItems.Add(new MenuItem("&Show"));
   contextMenu.MenuItems.Add(new MenuItem("-"));
   contextMenu.MenuItems.Add(new MenuItem("E&xit"));

Constructor 5

// Step IV for using SystemTrayNotifyIcon class in your project
// This is the first constructor, which takes two parameters
// (parameter 1) System.Windows.Forms.Form form (passing
// reference of main form)
// (parameter 2) bool visible (pass true to show icon in System
// Tray else false)
// (parameter 3) string toolTip (pass a string to be set as tooltip
// for System Tray Icon)
// (parameter 4) Icon icon (pass an icon to be set in System Tray)
// (parameter 5) ContextMenu contextMenu (pass a ContextMenu
// System Tray Notifications)
   m_SysTrayNotify = new SystemTrayNotification.SystemTrayNotifyIcon(
     this, true, "Hoowa!,
     new System.Drawing.Icon("..\\..\\Default Icon\\PakFlag.ico")",
         contextMenu);    
//

Note: At least, you will have to provide two parameters for a constructor. Even in this case the program will work fine as it will be with default values, which are given below.

  • string toolTip : Application Name by default.
  • Icon icon : Application Icon by default.
  • ContextMenu contextMenu : Menu provided by SystemTrayNotifyIcon class by default.

Step V (optional)

This step is very interesting and useful but I am keeping it optional for beginners who are still afraid of using events and delegates in their program though using events in C# is pretty easy. Declare an event handler for SystemTrayNotificationEventArgs in
your main form class and attach it with SystemTrayNotifyIcon.OnStatusChanged event right after initialing SystemTrayNotifyIcon variable in your main forms constructor. The code is given below.

// Step V for using SystemTrayNotifyIcon class in your project
// Add this function any where in your main form class to 
// catch System Tray Notifications
protected void SystemTrayNotificationHandler(object sender, 
    SystemTrayNotificationEventArgs e)
{
  switch (e.State)
  {
    case SystemTrayNotification.SystemTrayNotificationEventType.Hiding:
          break;
    case SystemTrayNotification.SystemTrayNotificationEventType.Showing:
          break;
    case 
    SystemTrayNotification.SystemTrayNotificationEventType.StartingAnimation:
          break;
    case 
     SystemTrayNotification.SystemTrayNotificationEventType.StopingAnimation:
          break;
    case SystemTrayNotification.SystemTrayNotificationEventType.IconChanged:
          break;
    case SystemTrayNotification.SystemTrayNotificationEventType.Disposing:
          break;
    default:      
          break;
  }
}
// Now attach this above function with 
// SystemTrayNotifyIcon.OnStatusChanged event right 
// after the initialization of SystemTrayNotifyIcon variable. 
// Add the following code.
   m_SysTrayNotify.OnStatusChanged += 
      new SystemTrayNotifyIcon.StatusChanged(SystemTrayNotificationHandler);
//

Step VI (optional - Making SystemTrayNotifyIcon to animate)

This step is quite easy and provides an extra functionality. If you want to animate SytemTrayNotifyIcon then you will have to provide series of icons which will be loaded and the shown in the form of animation. For animation at least two icons are required. I am using eight icons in my demo program. You can load these icons at any point in your program. Note that these icons are for different purpose so these are not mixed with the default icon given in the SystemTrayNotifyIcon constructor. Here is the code example of loading icon array.

// Step VI for using SystemTrayNotifyIcon class in your project
// Here I am giving some helping code not related to 
// SystemTrayNotifyIcon class
// The extra code shows process of laoding icons in an icon array from files 
// Declaration of iconArray
   private System.Drawing.Icon [] iconArray;
// after the initialization of SystemTrayNotifyIcon variable.
// Add the following code.
   iconArray = new Icon[8];
   for (int i = 1; i <= iconArray.Length; i++)
   {
      try
      {
    iconArray[i-1] = new Icon("..\\..\\Animation Icons\\icon" + i +".ico");
      }
      catch (Exception e)
      {
    MessageBox.Show(e.Message, "Error", 
         MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
   }
   // Actual code
   m_SysTrayNotify.LoadIcons(iconArray); 

   // Now to animate just call any one of the two overloaded 
   // Animate functions

   // It will animate five times now but INFINITELY if -1 is passed
   m_SysTrayNotify.Animate(5); 
                        OR
   // Actual code (1000 = 1 sec: Rate of change of icons during animation)
   m_SysTrayNotify.Animate(5, 1000); 

Step VII (Must - Disposing SystemTrayNotifyIcon)

This step is very important and if missed it might result in an exception. All you have to do is to just call

SystemTrayNotifyIcon 
Dispose() method in the first line of your main forms Dispose() method.

// Step VII for using SystemTrayNotifyIcon class in your project
// Concentrate on the highlighted code
   protected override void Dispose( bool disposing )
   {
      m_SysTrayNotify.Dispose();    
      if( disposing )
      {
    if (components != null) 
    {
       components.Dispose();
    }
      }
      base.Dispose( disposing );
   }
// 

Stopping Animation: The animation which has been started by calling Animate() method can be stopped at once if the KeepAnimationAlive property of 

SystemTrayNotifyIcon 
class is set false. Once the Animate() method has been called,  you can start and stop animation with the values set by Animate() method just by makeing
KeepAnimationAlive 
property true and false.

// Stopping animation using KeepAnimationAlive property of
SystemTrayNotifyIcon class
// here is the code
   m_SysTrayNotify.KeepAnimationAlive = false;
// 

Hiding and Showing NotifyIcon: For this case the

Visibility 
property of SystemTrayNotifyIcon class is used. Make it true and the icon will appear in System Tray, make it false and the icon will vanish from System Tray. Easy isn't it?

// Hiding NotifyIcon using Visibility property of SystemTrayNotifyIcon class
// here is the code
   m_SysTrayNotify.Visibility = false;
// 

Conclusion

Though providing a System Tray Notification functionality is not a difficult task in C# but I think this class will help some new comers to C# in knowing the basics of Timers, Events, delegates to some extent and last but not the least, implementing System Tray Notification in their applications.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Devpro AB
Software Developer (Senior)
Pakistan Pakistan
No Biography provided

Comments and Discussions

 
GeneralImprove code Pin
Member 1084523230-Nov-14 4:04
memberMember 1084523230-Nov-14 4:04 
Hello, the comments on constructor samples are incorrect, all state "This is the first constructor, which takes two parameters".
Publishing code with comments like "Summary description for SystemTrayNotificationEventType." is quite lame.
Check docs for xml comment syntax.
Instead of this use parameter comments:
/// <summary>
/// Overloaded Constructor -- 2 --
/// Icon = Application Icon (Default),
/// Tooltip = Programmer must provide,
/// Visibility = Programmer must provide,
/// ContextMenu = SystemTrayNotifyIcon class generated menu (Default).
///

/// <param name="visible" />
/// Controls whether icon is visible.
///
The difference is not only visual: parameter comments are displayed by intellisense, and references are renamed when parameters are renamed, and compiler checks names so you'll not have incorrect comments like above with Icon, Tooltip, Visibility, ContextMenu parameters on a constructor with form, visible and toolTip parameters.

Constructor 3 sample doesn't seem to compile.

It is a good practice to give descriptive name to values so that code can be understood without reading tons of comments.
I.e.
var owner = this;
const bool visible = true;

notifyIcon = new SystemTrayNotification.SystemTrayNotifyIcon(owner, visible);

This can be understood without any comments.

Even more useful when there are more parameters:

var owner = this;
const bool visible = true;
const bool tooltipText = "Sample  tooltip";
var icon = new System.Drawing.Icon("..\\..\\Default Icon\\PakFlag.ico");
notifyIcon = new SystemTrayNotification.SystemTrayNotifyIcon(owner, visible, tooltipText, icon)


C# coding convention doesn't use Hungarian notation and any other sort of prefixes for members, i.e. no m_. Hungarian notation and prefixes in general are redundant in strongly typed languages.

General Naming Conventions
X DO NOT use underscores, hyphens, or any other nonalphanumeric characters.
X DO NOT use Hungarian notation.

I.e. why would the name of iconArray change if type would be changed to List or IEnumerable? The name should rather describe what the value is, i.e. animationIcons and this would be consistent with animationCounter.

Overloaded methods, including constructors should call each other instead of copying same code to all overloads. Ie.
public SystemTrayNotifyIcon(Form form, bool visible)
: this(form, visible, defaultToolTip)

To have Dispose you'll have to implement IDisposable.
Dispose Pattern

Instead of testing for false or negate the condition test for true or the not negated condition, i.e.
if (keepAnimationAlive)

Don't have more than one statement in a line because is easy to be overlooked.
I.e. this should be two lines of code:
notifyIcon.Icon = iconArray[iconCounter++];
Correct:
notifyIcon.Icon = iconArray[iconCounter];
iconCounter++;
Maintainability is much more important than the number of lines. Compact code is hard to read and as such is more error prone.

Don't comment the obvious, only increases the noise:
new NotifyIcon(); // NotifyIcon object

modified 30-Nov-14 11:00am.

Questionany updates in 2011?? Pin
kiquenet.com21-Jan-11 5:53
professionalkiquenet.com21-Jan-11 5:53 
GeneralThank you Pin
M_Menon11-Jul-08 22:45
memberM_Menon11-Jul-08 22:45 
QuestionBy the way can your message load from resource file? Pin
beonhope3-Jan-08 19:05
memberbeonhope3-Jan-08 19:05 
AnswerRe: By the way can your message load from resource file? Pin
Member 1084523230-Nov-14 4:06
memberMember 1084523230-Nov-14 4:06 
GeneralExcellent Pin
amirali25-Dec-07 21:45
memberamirali25-Dec-07 21:45 
GeneralThank you Pin
SteveBeds2-Nov-07 5:28
memberSteveBeds2-Nov-07 5:28 
GeneralGreat, but... Pin
L4k119-Oct-07 22:11
memberL4k119-Oct-07 22:11 
QuestionHave any idea how to access Clock in system tray Pin
illegalguy7-Nov-05 12:51
memberillegalguy7-Nov-05 12:51 
GeneralUrgent Help Needed :context menu does not appear Pin
Gul Hunerkar13-Jul-05 1:38
memberGul Hunerkar13-Jul-05 1:38 
GeneralRe: Urgent Help Needed :context menu does not appear Pin
Anonymous13-Jul-05 4:48
memberAnonymous13-Jul-05 4:48 
General"System Tray" ? *tisk* *tisk* Pin
1-Nov-04 11:53
suss1-Nov-04 11:53 
GeneralRe: "System Tray" ? *tisk* *tisk* Pin
Devpro AB2-Nov-04 2:24
memberDevpro AB2-Nov-04 2:24 
GeneralRe: &quot;System Tray&quot; ? *tisk* *tisk* Pin
Axel Rietschin17-Jun-05 16:58
professionalAxel Rietschin17-Jun-05 16:58 
GeneralRe: &quot;System Tray&quot; ? *tisk* *tisk* Pin
Spiff Dog20-Feb-09 9:46
memberSpiff Dog20-Feb-09 9:46 
GeneralGood! Pin
Peff14-Mar-04 12:36
memberPeff14-Mar-04 12:36 
GeneralRe: Good! Pin
Devpro AB20-Mar-04 1:30
memberDevpro AB20-Mar-04 1:30 
GeneralNat bad Pin
Anonymous26-Jan-04 12:14
memberAnonymous26-Jan-04 12:14 
GeneralRe: Nat bad Pin
Devpro AB28-Jan-04 19:42
memberDevpro AB28-Jan-04 19:42 
GeneralNice Pin
qskdfhklqshdf17-Nov-03 21:56
memberqskdfhklqshdf17-Nov-03 21:56 
GeneralRe: Nice Pin
Devpro AB18-Nov-03 17:00
memberDevpro AB18-Nov-03 17:00 
GeneralNot a good design Pin
sytelus11-Feb-03 4:54
membersytelus11-Feb-03 4:54 
GeneralRe: Not a good design Pin
Devpro AB18-Feb-03 8:50
memberDevpro AB18-Feb-03 8:50 
GeneralRe: Not a good design Pin
sytelus19-Feb-03 3:46
membersytelus19-Feb-03 3:46 
GeneralRe: Not a good design Pin
Devpro AB19-Feb-03 23:10
memberDevpro AB19-Feb-03 23:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190612.1 | Last Updated 4 Feb 2003
Article Copyright 2003 by Devpro AB
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid