vbAccelerator - Contents of code file: SysTrayTester_SysTray.cs

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace vbAccelerator.Components.Shell
{

   //As Platform SDK rather sniffily has it in the Remarks section:
   // 'The taskbar notification area is sometimes erroneously called the
    "tray."'
   
   #region Public Enumerations
   [Flags]   
   public enum NotifyIconBalloonIconFlags : int
   {
      /// <summary>
      /// No Icon
      /// </summary>
      NIIF_NONE  = 0x00000000,
      /// <summary>
      /// Information icon
      /// </summary>
      NIIF_INFO  = 0x00000001,
      /// <summary>
      /// Warning icon
      /// </summary>
      NIIF_WARNING = 0x00000002,
      /// <summary>
      /// Error icon
      /// </summary>
      NIIF_ERROR = 0x00000003,
      /// <summary>
      /// Don't play sound. XP only
      /// </summary>
      NIIF_NOSOUND = 0x00000010         
   }
   #endregion

   #region SysTray 
   /// <summary>
   /// Allows a form to create a taskbar notification icon which
   /// supports balloon tips under XP.
   /// </summary>
   public class SysTray : System.Windows.Forms.NativeWindow, IDisposable
   {
      #region Events
      /// <summary>
      /// Raised when the icon in the SysTray area is clicked.
      /// </summary>
      public event EventHandler Click;
      /// <summary>
      /// Raised when the icon in the SysTray area is double clicked.
      /// </summary>
      public event EventHandler DoubleClick;
      /// <summary>
      /// Occurs when the user presses the mouse button while the pointer 
      /// is over the icon in the status notification area of the taskbar.
      /// </summary>
      public event MouseEventHandler MouseDown;
      /// <summary>
      /// Occurs when the user moves the mouse while the pointer is over the 
      /// icon in the status notification area of the taskbar.
      /// </summary>
      public event MouseEventHandler MouseMove;
      /// <summary>
      /// Occurs when the user releases the mouse button while the pointer 
      /// is over the icon in the status notification area of the taskbar.
      /// </summary>
      public event MouseEventHandler MouseUp;
      /// <summary>
      /// Raised if a user selects a notify icon with the keyboard and
       activates 
      /// it with the space bar or ENTER key.  SE/2000 or above only.
      /// </summary>
      public event EventHandler KeySelect;
      /// <summary>
      /// Raised if a user selects a notify icon with the mouse and activates 
      /// it with the space bar or ENTER key.  SE/2000 or above only.
      /// </summary>
      public event EventHandler EnterSelect;
      /// <summary>
      /// Fired when a balloon tip is shown (balloons are queued up by the
      /// system). ME/2000 or above only.
      /// </summary>      
      public event EventHandler BalloonShow;
      /// <summary>
      /// Sent if the balloon is hidden for a reason other than it timing
      /// out or the user clicking it. ME/2000 or above only.
      /// </summary>
      public event EventHandler BalloonHide;
      /// <summary>
      /// Sent if the balloon is being hidden because it has timed out.
      /// ME/2000 or above only.
      /// </summary>
      public event EventHandler BalloonTimeOut;
      /// <summary>
      /// Send if the user dismisses the balloon by clicking it.
      /// ME/2000 or above only.
      /// </summary>
      public event EventHandler BalloonClicked;
      #endregion

      #region Private Enumerations
      [Flags]
         private enum NotifyIconDataFlags : int
      {
         /// <summary>
         /// The uCallbackMessage member is valid. 
         /// </summary>
         NIF_MESSAGE  = 0x1,
         /// <summary>
         /// The hIcon member is valid.  
         /// </summary>
         NIF_ICON = 0x2,
         /// <summary>
         /// The szTip member is valid. 
         /// </summary>
         NIF_TIP = 0x4, 
         /// <summary>
         /// The dwState and dwStateMask members are valid. 
         /// </summary>
         NIF_STATE = 0x8, 
         /// <summary>
         /// Use a balloon ToolTip instead of a standard ToolTip. The szInfo, 
         /// uTimeout, szInfoTitle, and dwInfoFlags members are valid.
         /// </summary>
         NIF_INFO = 0x10,
         /// <summary>
         /// Reserved. 
         /// </summary>
         NIF_GUID = 0x20 
      }

      [Flags]
         private enum NotifyIconDataStateFlags : int
      {
         /// <summary>
         /// The Icon is hidden
         /// </summary>
         NIS_HIDDEN = 0x00000001,
         /// <summary>
         /// The icon is shared
         /// </summary>
         NIS_SHAREDICON = 0x00000002
      }
      
      private enum NotifyIconMessages : int
      {
         /// <summary>
         /// Adds an icon to the status area. The hWnd and uID members 
         /// of the NOTIFYICONDATA structure pointed to by lpdata will be 
         /// used to identify the icon in later calls to Shell_NotifyIcon. 
         /// </summary>
         NIM_ADD = 0x00000000,
         /// <summary>
         /// Modifies an icon in the status area. Use the hWnd and uID members 
         /// of the NOTIFYICONDATA structure pointed to by lpdata to identify 
         /// the icon to be modified. 
         /// </summary>
         NIM_MODIFY = 0x00000001,
         /// <summary>
         /// Deletes an icon from the status area. Use the hWnd and uID 
         /// members of the NOTIFYICONDATA structure pointed to by lpdata 
         /// to identify the icon to be deleted. 
         /// </summary>
         NIM_DELETE = 0x00000002,
         /// <summary>
         /// Returns focus to the taskbar notification area. Taskbar icons 
         /// should use this message when they have completed their user 
         /// interface operation. For example, if the taskbar icon displays a 
         /// shortcut menu, but the user presses ESCAPE to cancel it, use 
         /// NIM_SETFOCUS to return focus to the taskbar notification area
         /// </summary>
         NIM_SETFOCUS = 0x00000003,
         /// <summary>
         /// Instructs the taskbar to behave according to the version number 
         /// specified in the uVersion member of the structure pointed to by 
         /// lpdata. This message allows you to specify whether you want the 
         /// version 5.0 behavior found on Microsoft Windows 2000 systems, or 
         /// that found with earlier Shell versions. The default value for 
         /// uVersion is zero, indicating that the original Windows 95 notify 
         /// icon behavior should be used.
         /// </summary>
         NIM_SETVERSION = 0x00000004
      }

      #endregion

      #region Private Structures

      [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0,
       CharSet=CharSet.Auto)]
      private struct NOTIFYICONDATA 
      { 
         /// <summary>
         /// Size of structure.  Note for pre-Windows 2000 systems the
         /// szTip member is 64 characters long and ends the structure.
         /// </summary>
         public int cbSize; 
         /// <summary>
         /// Window handle to sed messages to
         /// </summary>
         public IntPtr hWnd; 
         /// <summary>
         /// Application-defined identifier for the taskbar item.  A
         /// single hWnd can have multiple taskbar icons using this
         /// member.
         /// </summary>
         public int uID; 
         /// <summary>
         /// Flags that indicate which of the other members contain valid data
         /// </summary>
         [MarshalAs(UnmanagedType.U4)] public NotifyIconDataFlags uFlags; 
         /// <summary>
         /// Application-defined message identifier. The system uses this 
         /// identifier to send notifications to the window identified in hWnd. 
         /// These notifications are sent when a mouse event occurs in the 
         /// bounding rectangle of the icon, or when the icon is selected or
          activated 
         /// with the keyboard. The wParam parameter of the message contains
          the 
         /// identifier of the taskbar icon in which the event occurred. 
         /// The lParam parameter holds the mouse or keyboard message
          associated 
         /// with the event. For example, when the pointer moves over a taskbar
          icon, 
         /// lParam is set to WM_MOUSEMOVE. 
         /// </summary>
         public int uCallbackMessage; 
         /// <summary>
         /// Handle to the icon to be added, modified or deleted.
         /// </summary>
         public IntPtr hIcon; 
         /// <summary>
         /// Tool tip string
         /// </summary>
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string
          szTip;
         /// <summary>
         /// State of the icon
         /// </summary>
         [MarshalAs(UnmanagedType.U4)] public NotifyIconDataStateFlags dwState; 
         /// <summary>
         /// A mask to determine which items are retrieved/set by the dwState
         /// member.
         /// </summary>
         [MarshalAs(UnmanagedType.U4)] public NotifyIconDataStateFlags
          dwStateMask;
         /// <summary>
         /// Text for a balloon tool-tip.
         /// </summary>
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public string
          szInfo; 
         /// <summary>
         /// When used as timeout:
         /// The timeout value, in milliseconds, for a balloon ToolTip. The 
         /// system enforces minimum and maximum timeout values. uTimeout
          values that 
         /// are too large are set to the maximum value and values that are too
          small 
         /// default to the minimum value. The system minimum and maximum
          timeout 
         /// values are currently set at 10 seconds and 30 seconds,
          respectively.
         /// When used as version:
         /// Specifies whether the Shell notify icon interface should use
          Windows 95 or 
         /// Windows 2000 behavior.  Allowable values are 0 or
          NOTIFYICON_VERSION
         /// </summary>
         public int uTimeoutOrVersion; 
         /// <summary>
         /// Title for the balloon tip.
         /// </summary>
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)] public string
          szInfoTitle; 
         /// <summary>
         /// Flags for controlling the icon in the balloon tip
         /// </summary>
         [MarshalAs(UnmanagedType.U4)] public NotifyIconBalloonIconFlags
          dwInfoFlags; 
         /// <summary>
         /// Reserved. XP only.
         /// </summary>
         public Guid guidItem;
      }
      private const int NOTIFYICON_VERSION = 3;
      private const int NOTIFYICONDATAA_V1_SIZE = 88;
      private const int NOTIFYICONDATAA_V2_SIZE = 488;

      private const int WM_DESTROY = 0x2;

      private const int WM_MOUSEMOVE = 0x200;
      private const int WM_LBUTTONDOWN = 0x201;
      private const int WM_LBUTTONUP = 0x202;
      private const int WM_LBUTTONDBLCLK = 0x203;
      private const int WM_RBUTTONDOWN = 0x204;
      private const int WM_RBUTTONUP = 0x205;
      private const int WM_RBUTTONDBLCLK = 0x206;

      private const int WM_USER = 0x400;

      
      private const int NIN_SELECT = WM_USER;
      private const int NINF_KEY = 0x1;
      private const int NIN_KEYSELECT = (NIN_SELECT | NINF_KEY);
      private const int NIN_BALLOONSHOW = (WM_USER + 2);
      private const int NIN_BALLOONHIDE = (WM_USER + 3);
      private const int NIN_BALLOONTIMEOUT = (WM_USER + 4);
      private const int NIN_BALLOONUSERCLICK = (WM_USER + 5);

      /// <summary>
      /// For sending private messages within a window class,
      /// an application can use any integer in the range WM_USER through 
      /// 0x7FFF
      /// </summary>      
      private const int NOTIFYMESSAGE = WM_USER + 0x4FB5;
      
      #endregion

      #region UnManagedMethods

      [DllImport("shell32.dll", CharSet = CharSet.Auto)]
      private extern static int Shell_NotifyIcon(
         [MarshalAs(UnmanagedType.U4)] NotifyIconMessages dwMessage,
         ref NOTIFYICONDATA lpData);

      /* Could use this to generate our message, but it adds
       * overhead because the message is globally registered...
      [DllInport("user32.dll", CharSet=CharSet.Auto)]
      private extern static IntPtr RegisterWindowMessage(
         [MarshalAs(UnmanagedType.LPTStr)] string lpString   // message string
         );
      */

      [DllImport("user32.dll")]
      private extern static int DestroyIcon(
         IntPtr hIcon);

      [DllImport("user32.dll")]
      private extern static int GetCursorPos(
         ref System.Drawing.Point lpPoint);

      [DllImport("user32.dll")]
      private extern static int TrackPopupMenu(
         IntPtr hMenu, 
         int wFlags, 
         int x, 
         int y, 
         int nReserved, 
         IntPtr hwnd, 
         ref System.Drawing.Rectangle lprc);

      [DllImport("user32.dll")]
      private extern static int SetForegroundWindow (
         IntPtr hwnd );

      private const int TPM_RETURNCMD = 0x0100;

      [DllImport("comctl32.dll")]
      private extern static IntPtr ImageList_GetIcon(
         IntPtr himl,
         int i,  
         int flags       
         );

      #endregion

      #region Unmanaged Icon
      private class UnManagedIcon : IDisposable
      {
         private IntPtr hIcon = IntPtr.Zero;

         public IntPtr Handle
         {
            get
            {
               return this.hIcon;
            }
            set
            {
               this.hIcon = value;
            }
         }

         public UnManagedIcon(IntPtr hIcon)
         {
            this.hIcon = hIcon;
         }
         public UnManagedIcon()
         {
         }

         public void Dispose()
         {            
            if (hIcon != IntPtr.Zero)
            {
               DestroyIcon(hIcon);
            }
            hIcon = IntPtr.Zero;
         }
      }
      #endregion

      #region Member Variables
      /// <summary>
      /// The Form to associate the SysTray with
      /// </summary>
      private System.Windows.Forms.Form ownerForm = null;
      /// <summary>
      /// The ImageList to use
      /// </summary>
      private System.Windows.Forms.ImageList ilsIcons = null;
      /// <summary>
      /// The context menu to use
      /// </summary>
      private System.Windows.Forms.ContextMenu mnuContext = null;
      /// <summary>
      /// The icon index to show
      /// </summary>
      private int iconIndex = 0;
      /// <summary>
      /// The Unmanaged version of the icon extracted from the 
      /// image list
      /// </summary>
      private UnManagedIcon icon = null;
      /// <summary>
      /// The ToolTip to show
      /// </summary>
      private string toolTip = "";
      /// <summary>
      /// Whether we're currently in the SysTray or not
      /// </summary>
      private bool inSysTray = false;
      /// <summary>
      /// Whether we were installed in the SysTray before the
      /// handle changed.
      /// </summary>
      private bool wasInSysTray = false;
      #endregion

      #region Constructor, Dispose
      /// <summary>
      /// Creates a new instance of the SysTray object, associating
      /// it with the top level Form.
      /// </summary>
      /// <param name="form">The top level Form to
      /// associate with</param>
      public SysTray(System.Windows.Forms.Form form)
      {
         this.ownerForm = form;
         this.AssignHandle(this.ownerForm.Handle);
      }

      /// <summary> 
      /// Clean up any resources being used.
      /// </summary>
      public void Dispose()
      {
         showInSysTray(false);
         if (this.Handle != IntPtr.Zero)
         {
            this.ReleaseHandle();
         }
      }

      #endregion

      #region Methods and Properties
      /// <summary>
      /// Gets/sets the ImageList used as a source of icons
      /// in the SysTray
      /// </summary>
      public System.Windows.Forms.ImageList IconImageList
      {
         get
         {
            return this.ilsIcons;
         }
         set
         {
            this.ilsIcons = value;
         }
      }
      /// <summary>
      /// Gets/sets the context menu to show in response 
      /// to a SysTray click
      /// </summary>
      public System.Windows.Forms.ContextMenu Menu
      {
         get
         {
            return this.mnuContext;
         }
         set
         {
            this.mnuContext = value;
         }
      }

      /// <summary>
      /// Gets/sets the IconIndex to use in the SysTray
      /// </summary>
      public int IconIndex
      {
         get
         {
            return this.iconIndex;
         }
         set
         {
            this.iconIndex = value;
            if (this.inSysTray)
            {
               NOTIFYICONDATA ids = newNotifyIconData();
               setIcon(ref ids);
               int ret = Shell_NotifyIcon(
                  NotifyIconMessages.NIM_MODIFY,
                  ref ids);            
            }
         }
      }

      /// <summary>
      /// Gets/sets the tool tip text to display when the
      /// user hovers above the item
      /// </summary>
      public string ToolTipText
      {
         get
         {
            return this.toolTip;
         }
         set
         {
            this.toolTip = value;
            if (this.inSysTray)
            {
               NOTIFYICONDATA ids = newNotifyIconData();
               setMessage(ref ids);
               int ret = Shell_NotifyIcon(
                  NotifyIconMessages.NIM_MODIFY,
                  ref ids);         
            }
         }
      }
   
      /// <summary>
      /// Shows a balloon tip over the item with no icon, no title
      /// and for the maximum timeout value.  ME/2000 or above only.
      /// </summary>
      /// <param name="message">Balloon tip message to display (max 256
       chars)</param>
      public void ShowBalloonTip(
         string message)
      {
         ShowBalloonTip(
            message,
            NotifyIconBalloonIconFlags.NIIF_NONE,
            "",
            30000);
      }
      /// <summary>
      /// Shows a balloon tip over the item with the specified icon
      /// and message for the maximum timeout value.  ME/2000 or above only.
      /// </summary>
      /// <param name="message">Balloon tip message to display (max 256
       chars)</param>
      /// <param name="icon">Icon to show</param>
      public void ShowBalloonTip(
         string message,
         NotifyIconBalloonIconFlags icon
         )
      {
         ShowBalloonTip(
            message,
            icon,
            "",
            100000);
      }
      /// <summary>
      /// Shows a balloon tip over the item with the specified icon,
      /// message and title, for the maximum timeout value.  ME/2000 or above
       only.
      /// </summary>
      /// <param name="message">Balloon tip message to display (max 256
       chars)</param>
      /// <param name="icon">Icon to show</param>
      /// <param name="title">Title of the balloon tip (max 64 chars)</param>
      public void ShowBalloonTip(
         string message,
         NotifyIconBalloonIconFlags icon,
         string title
         )
      {
         ShowBalloonTip(
            message,
            icon,
            title,
            100000);
      }
      /// <summary>
      /// Shows a balloon tip over the item with the specified icon,
      /// message and title for the specified timeout interval.  ME/2000 or
       above only.
      /// </summary>
      /// <param name="message">Balloon tip message to display (max 256
       chars)</param>
      /// <param name="icon">Icon to show</param>
      /// <param name="title">Title of balloon tip (max 64 chars)</param>
      /// <param name="timeOut">Timeout in milliseconds.  The system restricts
       timeouts
      /// to the range 10,000 - 30,000 ms.</param>
      public void ShowBalloonTip(
         string message,
         NotifyIconBalloonIconFlags icon,
         string title,
         int timeOut
         )
      {
         if (this.inSysTray)
         {
            // show the balloon tip:
            NOTIFYICONDATA ids = newNotifyIconData();
            ids.uFlags = NotifyIconDataFlags.NIF_INFO;
            ids.szInfo  = message;
            ids.szInfoTitle = title;
            ids.dwInfoFlags = icon;
            ids.uTimeoutOrVersion = timeOut;

            int ret = Shell_NotifyIcon(
               NotifyIconMessages.NIM_MODIFY,
               ref ids);            
         }
         else
         {
            // should throw exception?
         }
      }
      /// <summary>
      /// Gets/sets whether the item is shown in the SysTray or not.
      /// </summary>
      public bool ShowInSysTray
      {
         get
         {
            return this.inSysTray;
         }
         set
         {
            showInSysTray(value);
         }
      }
      /// <summary>
      /// Sets focus to your icon in the SysTray.  Should be called
      /// once you've completed a UI operation such as a menu.
      /// ME/2000 or above only.
      /// </summary>
      public void SetFocus()
      {
         NOTIFYICONDATA ids = newNotifyIconData();
         int ret = Shell_NotifyIcon(
            NotifyIconMessages.NIM_SETFOCUS,
            ref ids);            
         
      }
      #endregion

      #region Private helper routines
      private NOTIFYICONDATA newNotifyIconData()
      {
         return this.newNotifyIconData(false);
      }

      private NOTIFYICONDATA newNotifyIconData(bool useLastHandle)
      {
         NOTIFYICONDATA ids = new NOTIFYICONDATA();
            
         ids.uCallbackMessage = NOTIFYMESSAGE;
         ids.hWnd = this.Handle;
         ids.uID = 1;         

         if (Environment.OSVersion.Version.Major >= 5)
         {
            ids.cbSize = Marshal.SizeOf(ids);
            ids.uTimeoutOrVersion = NOTIFYICON_VERSION;
         }
         else
         {
            ids.cbSize = NOTIFYICONDATAA_V1_SIZE;
         }
         return ids;
      }

      private void setIcon(ref NOTIFYICONDATA ids)
      {
         if (this.ilsIcons != null)
         {
            // Let's see if we can get the icon:
            if (icon != null)
            {
               icon.Dispose();
            }
            IntPtr hIcon = ImageList_GetIcon(
               ilsIcons.Handle,
               iconIndex,
               0);
            if (hIcon != IntPtr.Zero)
            {
               icon = new UnManagedIcon(hIcon);
               ids.uFlags |= NotifyIconDataFlags.NIF_ICON;
               ids.hIcon = icon.Handle;
            }
               
         }
      }

      private void setMessage(ref NOTIFYICONDATA ids)
      {
         if (this.toolTip.Length > 0)
         {
            ids.uFlags |= NotifyIconDataFlags.NIF_TIP;
            ids.szTip = this.toolTip;
         }
      }

      private void showInSysTray(bool state)
      {
         NOTIFYICONDATA ids = newNotifyIconData(!state);
         ids.uFlags = NotifyIconDataFlags.NIF_MESSAGE;

         if (state)
         {   
            if (!this.inSysTray)
            {
               setIcon(ref ids);
               setMessage(ref ids);

               // add to systray:
               int ret = Shell_NotifyIcon(
                  NotifyIconMessages.NIM_ADD,
                  ref ids);
               // set version:
               if (ids.uTimeoutOrVersion == NOTIFYICON_VERSION)
               {
                  ret = Shell_NotifyIcon(
                     NotifyIconMessages.NIM_SETVERSION,
                     ref ids);
               }
            }
         }
         else
         {
            if (this.inSysTray)
            {
               // remove from systray
               Shell_NotifyIcon(
                  NotifyIconMessages.NIM_DELETE,
                  ref ids);
               if (icon != null)
               {
                  icon.Dispose();
               }
            }
         }
         this.inSysTray = state;
         this.wasInSysTray = this.inSysTray;

      }
      private MouseEventArgs getMouseEventArgs(
         MouseButtons button
         )
      {
         Point pt = new Point(0,0);
         GetCursorPos(ref pt);
         int delta = 0;
         int clicks = 0;
         MouseEventArgs e = new MouseEventArgs(
            button,
            clicks,
            pt.X, pt.Y,
            delta);
         return e;
      }
      #endregion

      #region Message Processing
      protected override void WndProc(ref System.Windows.Forms.Message m)
      {
         if (m.Msg == NOTIFYMESSAGE)
         {
            // process SysTray notification
            switch ((int)m.LParam)
            {
               case WM_MOUSEMOVE:
                  if (MouseMove != null)
                  {
                     MouseEventArgs e = getMouseEventArgs(MouseButtons.None);
                     MouseMove(this, e);
                  }
                  break;
               case WM_LBUTTONUP:
                  if (MouseUp != null)
                  {
                     MouseEventArgs e = getMouseEventArgs(MouseButtons.Left);
                     MouseUp(this, e);
                  }
                  if (Click != null)
                  {
                     Click(this, null);
                  }
                  break;
               case WM_LBUTTONDOWN:
                  if (MouseDown != null)
                  {
                     MouseEventArgs e = getMouseEventArgs(MouseButtons.Left);
                     MouseDown(this, e);
                  }
                  break;
               case WM_LBUTTONDBLCLK:
                  if (DoubleClick != null)
                  {
                     DoubleClick(this, null);
                  }
                  break;
               case WM_RBUTTONDOWN:
                  if (MouseDown != null)
                  {
                     MouseEventArgs e = getMouseEventArgs(MouseButtons.Right);
                     MouseDown(this, e);
                  }
                  break;
               case WM_RBUTTONUP:
                  if (MouseUp != null)
                  {
                     MouseEventArgs e = getMouseEventArgs(MouseButtons.Right);
                     MouseUp(this, e);
                  }

                  // if a context menu is set then show it
                  if (mnuContext != null)
                  {
                     System.Drawing.Point pos = new System.Drawing.Point(0,0);
                     GetCursorPos(ref pos);                     
                     IntPtr hMenu = mnuContext.Handle;
                     if (hMenu != IntPtr.Zero)
                     {
                        Rectangle rc = new Rectangle(0,0,0,0);
                        SetForegroundWindow(this.Handle);
                        TrackPopupMenu(
                           hMenu, 
                           0, 
                           pos.X, pos.Y, 
                           0, 
                           this.Handle, 
                           ref rc);
                        SetFocus();
                     }
                  }
                  
                  if (Click != null)
                  {
                     Click(this, null);
                  }
                  break;

               case WM_RBUTTONDBLCLK:
                  if (DoubleClick != null)
                  {
                     this.DoubleClick(this, null);
                  }
                  break;

               case NIN_KEYSELECT:
                  if (KeySelect != null)
                  {
                     KeySelect(this, null);
                  }
                  break;

               case NIN_SELECT:
                  if (EnterSelect != null)
                  {
                     EnterSelect(this, null);
                  }
                  break;

               case NIN_BALLOONSHOW:
                  if (BalloonShow != null)
                  {                     
                     BalloonShow(this, null);
                  }
                  break;

               case NIN_BALLOONHIDE:
                  if (BalloonHide != null)
                  {
                     BalloonHide(this, null);
                  }
                  break;

               case NIN_BALLOONTIMEOUT:
                  if (BalloonTimeOut != null)
                  {
                     BalloonTimeOut(this, null);
                  }
                  break;

               case NIN_BALLOONUSERCLICK:
                  if (BalloonClicked != null)
                  {
                     BalloonClicked(this, null);
                  }
                  break;
            }
         }
         // Added 2003-09-27 to prevent problem with
         // handle changing
         else if (m.Msg == WM_DESTROY)
         {
            // remove.
            this.wasInSysTray = this.inSysTray;
            showInSysTray(false);
         }
         base.DefWndProc(ref m);
      }
      #endregion

      private void SysTray_Load(object sender, System.EventArgs e)
      {
      
      }
   }
   #endregion
}