Click here to Skip to main content
15,890,185 members
Articles / Programming Languages / XML

TaskbarNotifier, a skinnable MSN Messenger-like Popup in C# and now in VB.NET too

Rate me:
Please Sign up or sign in to vote.
4.94/5 (413 votes)
30 Mar 20034 min read 2.8M   68.4K   1.1K   656
The TaskbarNotifier class allows to display an MSN Messenger-like animated popup with a skinned background

Image 1

Introduction

Since I am learning C#, I thought it would be helpful for me to port my C++ CTaskbarNotifier class (http://www.codeproject.com/dialog/TaskbarNotifier.asp[^]).

As a result, I coded an MSN Messenger-like skinnable popup, with a close button which looks almost like Microsoft's one (with the associated skin).

The TaskbarNotifier class inherits from System.Windows.Forms.Form and adds a few methods to it.

Features

The MSN messenger like popup supports:

  • A custom transparent bitmap background
  • A skinnable 3-State close button
  • A clickable title text
  • A clickable content text
  • A selection rectangle
  • Custom fonts and colors for the different states of the text (normal/hover)
  • Animation speed parameters

Compatibility

This class is stand alone and doesn't need any particular libraries except .NET default ones. It runs in managed code and hence should be portable.

How to Use the Class

  • First of all, copy TaskbarNotifier.cs in your project directory.
  • Add on the top of your source code, the directive:
    C#
    using CustomUIControls;
  • Add a member variable in your class:
    C#
    TaskbarNotifier taskbarNotifier;
  • In your constructor, add the following lines:
    C#
    taskbarNotifier=new TaskbarNotifier();
    taskbarNotifier.SetBackgroundBitmap("skin.bmp",
                        Color.FromArgb(255,0,255));
    taskbarNotifier.SetCloseBitmap("close.bmp",
            Color.FromArgb(255,0,255),new Point(127,8));
    taskbarNotifier.TitleRectangle=new Rectangle(40,9,70,25);
    taskbarNotifier.ContentRectangle=new Rectangle(8,41,133,68);
    taskbarNotifier.TitleClick+=new EventHandler(TitleClick);
    taskbarNotifier.ContentClick+=new EventHandler(ContentClick);
    taskbarNotifier.CloseClick+=new EventHandler(CloseClick);

Details

C#
taskbarNotifier.SetBackgroundBitmap("skin.bmp",
                    Color.FromArgb(255,0,255));
taskbarNotifier.SetCloseBitmap("close.bmp",
    Color.FromArgb(255,0,255),new Point(127,8));

The first line sets the background bitmap skin and transparency color (must be present), and the second line sets the 3-State close button with its transparency color and its location on the window (this line is optional if you don't want a close button).

C#
taskbarNotifier.TitleRectangle=new Rectangle(40,9,70,25);
taskbarNotifier.ContentRectangle=new Rectangle(8,41,133,68);

These two lines allow us to define the rectangles in which will be displayed, the title and content texts.

C#
taskbarNotifier.TitleClick+=new EventHandler(OnTitleClick);
taskbarNotifier.ContentClick+=new EventHandler(OnContentClick);
taskbarNotifier.CloseClick+=new EventHandler(OnCloseClick);

These 3 lines allow us to intercept events on the popup such as title/content or close button have been clicked

  • Then we are done, we just need to call:
    C#
    taskbarNotifier.Show("TitleText","ContentText",500,3000,500);

    This will show the popup animation with the showing/visible/hiding animations time set as 500ms/3000ms/500ms.

You can play with a few properties:

  • Title, content fonts and colors
  • Ability to click or not on the title/content/close button
  • You can disable the focus rect
  • ... (see below for more details)

Class Documentation

Methods

C#
void Show(string strTitle, string strContent, int nTimeToShow, 
                                            int nTimeToStay, int nTimeToHide)

Displays the popup for a certain amount of time.

Parameters

  • strTitle: The string which will be shown as the title of the popup
  • strContent: The string which will be shown as the content of the popup
  • nTimeToShow: Duration of the showing animation (in milliseconds)
  • nTimeToStay: Duration of the visible state before collapsing (in milliseconds)
  • nTimeToHide: Duration of the hiding animation (in milliseconds)
C#
void Hide()

Forces the popup to hide.

C#
void SetBackgroundBitmap(string strFilename, Color transparencyColor)

Sets the background bitmap and its transparency color.

Parameters

  • strFilename: Path of the background bitmap on the disk
  • transparencyColor: Color of the bitmap which won't be visible
C#
void SetBackgroundBitmap(Image image, Color transparencyColor)

Sets the background bitmap and its transparency color.

Parameters

  • image: Background bitmap
  • transparencyColor: Color of the bitmap which won't be visible
C#
void SetCloseBitmap(string strFilename, 
            Color transparencyColor, Point position)

Sets the 3-State close button bitmap, its transparency color and its coordinates.

Parameters

  • strFilename: Path of the 3-state close button bitmap on the disk (width must be a multiple of 3)
  • transparencyColor: Color of the bitmap which won't be visible
  • position: Location of the close button on the popup
C#
void SetCloseBitmap(Image image, Color transparencyColor, Point position)

Sets the 3-State close button bitmap, its transparency color and its coordinates.

Parameters

  • image: Image/Bitmap object which represents the 3-state close button bitmap (width must be a multiple of 3)
  • transparencyColor: Color of the bitmap which won't be visible
  • position: Location of the close button on the popup

Properties

C#
string TitleText (get/set)
string ContentText (get/set)
TaskbarStates TaskbarState (get)
Color NormalTitleColor (get/set)
Color HoverTitleColor (get/set)
Color NormalContentColor (get/set)
Color HoverContentColor (get/set)
Font NormalTitleFont (get/set)
Font HoverTitleFont (get/set)
Font NormalContentFont (get/set)
Font HoverContentFont (get/set)
Rectangle TitleRectangle (get/set) //must be defined before calling show())
Rectangle ContentRectangle (get/set) //must be defined before calling show())
bool TitleClickable (get/set) (default = false);
bool ContentClickable (get/set) (default = true);
bool CloseClickable (get/set) (default = true);
bool EnableSelectionRectangle (get/set) (default = true);

Events

C#
event EventHandler CloseClick
event EventHandler TitleClick
event EventHandler ContentClick

Technical Issues

The popup is skinned using a region generated dynamically from a bitmap and a transparency color:

C#
protected Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
{
    if (bitmap == null)
        throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!");

    int height = bitmap.Height;
    int width = bitmap.Width;

    GraphicsPath path = new GraphicsPath();

    for (int j=0; j<height; j++ )
        for (int i=0; i<width; i++)
        {
            if (bitmap.GetPixel(i, j) == transparencyColor)
                continue;

            int x0 = i;

            while ((i < width) && 
                    (bitmap.GetPixel(i, j) != transparencyColor))
                i++;

            path.AddRectangle(new Rectangle(x0, j, i-x0, 1));
        }

    Region region = new Region(path);
    path.Dispose();
    return region;
}

The refresh() of the popup is done using the double buffering technique to avoid flickering:

C#
protected override void OnPaintBackground(PaintEventArgs pea)
{
    Graphics grfx = pea.Graphics;
    grfx.PageUnit = GraphicsUnit.Pixel;

    Graphics offScreenGraphics;
    Bitmap offscreenBitmap;

    offscreenBitmap = new Bitmap(BackgroundBitmap.Width, 
                                BackgroundBitmap.Height);
    offScreenGraphics = Graphics.FromImage(offscreenBitmap);

    if (BackgroundBitmap != null)
    {
        offScreenGraphics.DrawImage(BackgroundBitmap, 
            0, 0, BackgroundBitmap.Width, BackgroundBitmap.Height);
    }

    DrawCloseButton(offScreenGraphics);
    DrawText(offScreenGraphics);

    grfx.DrawImage(offscreenBitmap, 0, 0);
}

Bugs/Limitations

Since I wanted to keep only managed code, I used the Screen.GetWorkingArea(WorkAreaRectangle) function instead of using unmanaged code to get the taskbar position. As a result, I made the popup always appear at the bottom of WorkAreaRectangle whichever position the taskbar has.

I didn't find any C# managed equivalent to the Win32 function ShowWindow(SW_SHOWNOACTIVATE) to make the popup, not steal the focus of the active window.

Updates

  • 01 April, 2003: Small bug fix in the OnMouseUp handler
  • 11 January, 2003: Patrick Vanden Driessche updated both the C# and VB.NET versions:
    • The popup now doesn't close automatically when the mouse is still over it
    • The popup is shown again when it was disappearing and the mouse comes over it
    • A few other bugs have been corrected
  • 10 January, 2003: A port of TaskbarNotifier has been done by Patrick Vanden Driessche in VB.NET
  • 05 December, 2002: The popup is now shown using the Win32 function ShowWindow(SW_SHOWNOACTIVATE), to prevent the popup from stealing the focus.

Conclusion

I hope this code will be useful to you. If you have suggestions to enhance this class functionalities, please post a comment.

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
Web Developer
United States United States
I live in Santa Clara CA and work as a software engineer for SAP Business Objects.

My areas of expertise are user interface developments in Eclipse RCP / SWT / Draw 2D and C#

Comments and Discussions

 
Generalayuda Pin
Member 267970918-Apr-08 10:37
Member 267970918-Apr-08 10:37 
Generallink bad Pin
Raphael Soares15-Apr-08 7:36
Raphael Soares15-Apr-08 7:36 
GeneralLicense Pin
Greg Campbell9-Jan-08 12:19
Greg Campbell9-Jan-08 12:19 
GeneralRe: License Pin
dittimon20-Sep-09 16:33
dittimon20-Sep-09 16:33 
GeneralSet XY coordinates for popup Pin
Manjero11-Nov-07 1:19
Manjero11-Nov-07 1:19 
AnswerRe: Set XY coordinates for popup Pin
richardtsa19-Jun-08 3:04
richardtsa19-Jun-08 3:04 
GeneralThank you for sharing ur knowledge with us Pin
Anandramankkd20-Sep-07 18:09
Anandramankkd20-Sep-07 18:09 
NewsSliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection [modified] Pin
Crusty Applesniffer5-Sep-07 5:27
Crusty Applesniffer5-Sep-07 5:27 
Please find below my contribution to this Project

I've added the following features:
  • New properties: AppearBySliding, Padding, ContentTextAlignement
  • Toast collection (that manages displaying several -stacked- 'Toasts' in the same time.)

  • The ToastCollection declaration has been append after the TaskbarNotifier class and should be used as follow:

    protected ToastCollection m_ColToast = new ToastCollection();

    private TaskbarNotifier InitTaskBarNotifier(TaskbarNotifier notifier, Color titleColor)
    {
        notifier.Base = m_ColToast;
        notifier.SetBackgroundBitmap(new Bitmap(GetType(), "Images.notifierLiveMessengerSkin.png"), Color.FromArgb(255, 0, 255));
        notifier.SetCloseBitmap(new Bitmap(GetType(), "Images.notifierLiveMessengerClose.png"), Color.FromArgb(255, 0, 255), new Point(184, 9));
        notifier.TitleRectangle = new Rectangle(10, 3, 180, 20);
        notifier.ContentRectangle = new Rectangle(4, 28, 195, 84);
        notifier.ContentTextAlignement = ContentAlignment.MiddleCenter;
        notifier.NormalTitleColor = titleColor;
        notifier.CloseClickable = true;
        notifier.TitleClickable = false;
        notifier.ContentClickable = false;
        notifier.EnableSelectionRectangle = true;
        notifier.KeepVisibleOnMousOver = true;
        notifier.ReShowOnMouseOver = true;
        notifier.Padding = 0;
        notifier.AppearBySliding = false;
        return notifier;
    }
    

    And each time you want to show a popup call the InitTaskBarNotifier method (see above), it will add the new toast to the Toast Collection.
    ...
    TaskbarNotifier m_NotifierTmp = InitTaskBarNotifier(new TaskbarNotifier(), titleColor);
    m_NotifierTmp.Show(title, content, appearingDuration, showingDuration, disappearingDuration);
    ...

    Finally, below, there is the full updated class and the new ToastCollection class (sorry for size and format)
    // C# TaskbarNotifier Class v1.0
    // by John O'Byrne - 02 december 2002
    // 01 april 2003 : Small fix in the OnMouseUp handler
    // 11 january 2003 : Patrick Vanden Driessche <pvdd@devbrains.be> added a few enhancements
    //           Small Enhancements/Bugfix
    //           Small bugfix: When Content text measures larger than the corresponding ContentRectangle
    //                         the focus rectangle was not correctly drawn. This has been solved.
    //           Added KeepVisibleOnMouseOver
    //           Added ReShowOnMouseOver
    //           Added If the Title or Content are too long to fit in the corresponding Rectangles,
    //                 the text is truncateed and the ellipses are appended (StringTrimming).
    // Rev 003-CrustyAppleSniffer: Sliding or fading effect
    // Rev 004-CrustyAppleSniffer: New Property: Padding
    // Rev 005-CrustyAppleSniffer: New feature: Management of Toasts' Collection and last position storage
    // Rev 006-CrustyAppleSniffer: New feature: Content alignement
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace CustomUIControls
    {
        /// <summary>
        /// TaskbarNotifier allows to display Skinned instant messaging popups
        /// </summary>
        public class TaskbarNotifier : Form
        {
            #region TaskbarNotifier Protected Members
            protected Bitmap BackgroundBitmap = null;
            protected Bitmap CloseBitmap = null;
            protected Point CloseBitmapLocation;
            protected Size CloseBitmapSize;
            protected Rectangle RealTitleRectangle;
            protected Rectangle RealContentRectangle;
            protected Rectangle WorkAreaRectangle;
            protected Timer timer = new Timer();
            protected TaskbarStates taskbarState = TaskbarStates.hidden;
            protected string titleText;
            protected string contentText;
            protected Color normalTitleColor = Color.FromArgb(255, 255, 255);
            protected Color hoverTitleColor = Color.FromArgb(255, 0, 0);
            protected Color normalContentColor = Color.FromArgb(0, 0, 0);
            protected Color hoverContentColor = Color.FromArgb(0, 0, 0x66);
            protected Font normalTitleFont = new Font("Arial", 12, FontStyle.Regular | FontStyle.Bold, GraphicsUnit.Pixel);
            protected Font hoverTitleFont = new Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Pixel);
            protected Font normalContentFont = new Font("Arial", 11, FontStyle.Regular, GraphicsUnit.Pixel);
            protected Font hoverContentFont = new Font("Arial", 11, FontStyle.Regular, GraphicsUnit.Pixel);
            protected int nShowEvents;
            protected int nHideEvents;
            protected int nVisibleEvents;
            protected int nIncrementShow;
            protected int nIncrementHide;
            protected bool bIsMouseOverPopup = false;
            protected bool bIsMouseOverClose = false;
            protected bool bIsMouseOverContent = false;
            protected bool bIsMouseOverTitle = false;
            protected bool bIsMouseDown = false;
            protected bool bKeepVisibleOnMouseOver = true;		// Added Rev 002
            protected bool bReShowOnMouseOver = false;		// Added Rev 002
            protected bool bAppearBySliding = true;		// Rev 003-CAS: Sliding or fading effect
            protected int nPadding = 10;				// Rev 004-CAS: New Property: Padding
            protected int nBaseWindowBottom = 0;			// Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            protected int nBaseWindowRight = 0;			// Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            protected ToastCollection colBase = null;		// Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            protected bool bMoving = false;			// Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            protected int nMouseDownX;				// Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            protected int nMouseDownY;				// Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            protected ContentAlignment caContentAlignement;         // Rev 006-CAS: New feature: Content alignement
    
            #endregion
    
            #region TaskbarNotifier Public Members
            public Rectangle TitleRectangle;
            public Rectangle ContentRectangle;
            public bool TitleClickable = false;
            public bool ContentClickable = true;
            public bool CloseClickable = true;
            public bool EnableSelectionRectangle = true;
            public event EventHandler CloseClick = null;
            public event EventHandler TitleClick = null;
            public event EventHandler ContentClick = null;
            #endregion
    
            #region TaskbarNotifier Enums
            /// <summary>
            /// List of the different popup animation status
            /// </summary>
            public enum TaskbarStates
            {
                hidden = 0,
                appearing = 1,
                visible = 2,
                disappearing = 3
            }
            #endregion
    
            #region TaskbarNotifier Constructor
            /// <summary>
            /// The Constructor for TaskbarNotifier
            /// </summary>
            public TaskbarNotifier()
            {
                // Window Style
                FormBorderStyle = FormBorderStyle.None;
                WindowState = FormWindowState.Minimized;
                //-CAS 29/08/2007: avoid taskbar flickering each time a Notifier is displayed
                // base.Show();
                base.Hide();
                WindowState = FormWindowState.Normal;
                ShowInTaskbar = false;
                TopMost = true;
                MaximizeBox = false;
                MinimizeBox = false;
                ControlBox = false;
    
                timer.Enabled = true;
                timer.Tick += new EventHandler(OnTimer);
            }
            #endregion
    
            #region TaskbarNotifier Properties
            /// <summary>
            /// Get the current TaskbarState (hidden, showing, visible, hiding)
            /// </summary>
            public TaskbarStates TaskbarState
            {
                get
                {
                    return taskbarState;
                }
            }
    
            /// <summary>
            /// Get/Set the popup Title Text
            /// </summary>
            public string TitleText
            {
                get
                {
                    return titleText;
                }
                set
                {
                    titleText = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the popup Content Text
            /// </summary>
            public string ContentText
            {
                get
                {
                    return contentText;
                }
                set
                {
                    contentText = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Normal Title Color
            /// </summary>
            public Color NormalTitleColor
            {
                get
                {
                    return normalTitleColor;
                }
                set
                {
                    normalTitleColor = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Hover Title Color
            /// </summary>
            public Color HoverTitleColor
            {
                get
                {
                    return hoverTitleColor;
                }
                set
                {
                    hoverTitleColor = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Normal Content Color
            /// </summary>
            public Color NormalContentColor
            {
                get
                {
                    return normalContentColor;
                }
                set
                {
                    normalContentColor = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Hover Content Color
            /// </summary>
            public Color HoverContentColor
            {
                get
                {
                    return hoverContentColor;
                }
                set
                {
                    hoverContentColor = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Normal Title Font
            /// </summary>
            public Font NormalTitleFont
            {
                get
                {
                    return normalTitleFont;
                }
                set
                {
                    normalTitleFont = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Hover Title Font
            /// </summary>
            public Font HoverTitleFont
            {
                get
                {
                    return hoverTitleFont;
                }
                set
                {
                    hoverTitleFont = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Normal Content Font
            /// </summary>
            public Font NormalContentFont
            {
                get
                {
                    return normalContentFont;
                }
                set
                {
                    normalContentFont = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Get/Set the Hover Content Font
            /// </summary>
            public Font HoverContentFont
            {
                get
                {
                    return hoverContentFont;
                }
                set
                {
                    hoverContentFont = value;
                    Refresh();
                }
            }
    
            /// <summary>
            /// Indicates if the popup should remain visible when the mouse pointer is over it.
            /// Added Rev 002
            /// </summary>
            public bool KeepVisibleOnMousOver
            {
                get
                {
                    return bKeepVisibleOnMouseOver;
                }
                set
                {
                    bKeepVisibleOnMouseOver = value;
                }
            }
    
            /// <summary>
            /// Indicates if the popup should appear again when mouse moves over it while it's disappearing.
            /// Added Rev 002
            /// </summary>
            public bool ReShowOnMouseOver
            {
                get
                {
                    return bReShowOnMouseOver;
                }
                set
                {
                    bReShowOnMouseOver = value;
                }
            }
    
            /// <summary>
            /// Indicates if the popup should diplayed with fadding or slidding effect
            /// Added Rev 003-CAS
            /// </summary>
            public bool AppearBySliding
            {
                get
                {
                    return bAppearBySliding;
                }
                set
                {
                    bAppearBySliding = value;
                }
            }
            /// <summary>
            /// Get/Set the popup padding (distance between 2 popups)
            /// Added Rev 004-CAS: New Property: Padding
            /// </summary>
            public new int Padding
            {
                get
                {
                    return nPadding;
                }
                set
                {
                    nPadding = value;
                    Refresh();
                }
            }
            /// <summary>
            /// Get/Set the popup distance from the working area bottom border due to popup stacking
            /// Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            /// </summary>
            public int BaseWindowBottom
            {
                get
                {
                    return nBaseWindowBottom;
                }
                set
                {
                    nBaseWindowBottom = value;
                    Refresh();
                }
            }
            /// <summary>
            /// Get/Set the popup distance from the working area right border due to popup stacking
            /// Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            /// </summary>
            public int BaseWindowRight
            {
                get
                {
                    return nBaseWindowRight;
                }
                set
                {
                    nBaseWindowRight = value;
                    Refresh();
                }
            }
            /// <summary>
            /// Get/Set the toast collection the popup belongs to
            /// Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
            /// </summary>
            public ToastCollection Base
            {
                get
                {
                    return colBase;
                }
                set
                {
                    colBase = value;
                    Refresh();
                }
            }
            /// <summary>
            /// Get/Set the Content alignement property
            /// Added Rev 006-CAS: New feature: Content alignement
            /// </summary>
            public ContentAlignment ContentTextAlignement
            {
                get
                {
                    return caContentAlignement;
                }
                set
                {
                    caContentAlignement = value;
                    Refresh();
                }
            }
            #endregion
    
            #region TaskbarNotifier Public Methods
            [DllImport("user32.dll")]
            private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);
            /// <summary>
            /// Displays the popup for a certain amount of time
            /// </summary>
            /// <param name="strTitle">The string which will be shown as the title of the popup</param>
            /// <param name="strContent">>The string which will be shown as the content of the popup</param>
            /// <param name="nTimeToShow">Duration of the showing animation (in milliseconds)</param>
            /// <param name="nTimeToStay">Duration of the visible state before collapsing (in milliseconds)</param>
            /// <param name="nTimeToHide">Duration of the hiding animation (in milliseconds)</param>
            /// <returns>Nothing</returns>
            public void Show(string strTitle, string strContent, int nTimeToShow, int nTimeToStay, int nTimeToHide)
            {
                WorkAreaRectangle = Screen.GetWorkingArea(WorkAreaRectangle);
                titleText = strTitle;
                contentText = strContent;
                nVisibleEvents = nTimeToStay;
                CalculateMouseRectangles();
    
                // We calculate the pixel increment and the timer value for the showing animation
                int nEvents = 0;
                if (nTimeToShow > 10)
                {
                    nEvents = Math.Min((nTimeToShow / 10), BackgroundBitmap.Height);
                    nShowEvents = nTimeToShow / nEvents;
                    nIncrementShow = BackgroundBitmap.Height / nEvents;
                }
                else
                {
                    nShowEvents = 10;
                    nIncrementShow = BackgroundBitmap.Height;
                }
    
                // We calculate the pixel increment and the timer value for the hiding animation
                if (nTimeToHide > 10)
                {
                    nEvents = Math.Min((nTimeToHide / 10), BackgroundBitmap.Height);
                    nHideEvents = nTimeToHide / nEvents;
                    nIncrementHide = BackgroundBitmap.Height / nEvents;
                }
                else
                {
                    nHideEvents = 10;
                    nIncrementHide = BackgroundBitmap.Height;
                }
    
                // Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                if (colBase != null)
                    colBase.AddToast(this, this.WorkAreaRectangle.Height,
                                    ref nBaseWindowBottom, ref nBaseWindowRight);
    
    
                switch (taskbarState)
                {
                    case TaskbarStates.hidden:
                        taskbarState = TaskbarStates.appearing;
                        // Updated Rev 003-CAS: Sliding or fading effect
                        if (bAppearBySliding)
                        {
                            // Added Rev 003-CAS: Sliding or fading effect						
                            this.Opacity = 1.0;
                            // Updated Rev 004-CAS: New Property: Padding
                            // Updated Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                            SetBounds(WorkAreaRectangle.Right - BackgroundBitmap.Width - nPadding - nBaseWindowRight,
                                WorkAreaRectangle.Bottom,
                                BackgroundBitmap.Width, 0);
                        }
                        else
                        {
                            // Added Rev 003-CAS: Sliding or fading effect
                            this.Opacity = 0.0;
                            // Updated Rev 004-CAS: New Property: Padding
                            // Updated Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                            SetBounds(WorkAreaRectangle.Right - BackgroundBitmap.Width - nPadding - nBaseWindowRight,
                                  WorkAreaRectangle.Bottom - BackgroundBitmap.Height - nPadding - nBaseWindowBottom,
                                  BackgroundBitmap.Width, BackgroundBitmap.Height);
    
                        }
                        timer.Interval = nShowEvents;
                        timer.Start();
    
                        // We Show the popup without stealing focus
                        ShowWindow(this.Handle, 4);
                        break;
    
                    case TaskbarStates.appearing:
                        Refresh();
                        break;
    
                    case TaskbarStates.visible:
                        timer.Stop();
                        timer.Interval = nVisibleEvents;
                        timer.Start();
                        Refresh();
                        break;
    
                    case TaskbarStates.disappearing:
                        timer.Stop();
                        taskbarState = TaskbarStates.visible;
                        // Updated Rev 003-CAS: Sliding or fading effect
                        if (bAppearBySliding)
                        {
                            // Updated Rev 004-CAS: New Property: Padding
                            // Updated Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                            SetBounds(WorkAreaRectangle.Right - BackgroundBitmap.Width - nPadding - nBaseWindowRight,
                                WorkAreaRectangle.Bottom - BackgroundBitmap.Height - nPadding - nBaseWindowBottom,
                                BackgroundBitmap.Width, BackgroundBitmap.Height);
                        }
                        else
                        {
                            // Updated Rev 004-CAS: New Property: Padding
                            // Updated Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                            SetBounds(WorkAreaRectangle.Right - BackgroundBitmap.Width - nPadding - nBaseWindowRight,
                                WorkAreaRectangle.Bottom - nPadding - nBaseWindowBottom,
                                BackgroundBitmap.Width, 0);
                        }
                        timer.Interval = nVisibleEvents;
                        timer.Start();
                        Refresh();
                        break;
                }
            }
    
            /// <summary>
            /// Hides the popup
            /// </summary>
            /// <returns>Nothing</returns>
            public new void Hide()
            {
                if (taskbarState != TaskbarStates.hidden)
                {
                    timer.Stop();
                    taskbarState = TaskbarStates.hidden;
                    base.Hide();
                    // Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                    if (colBase != null)
                        colBase.KillWindow(this);
                }
            }
            /// <summary>
            /// Sets the background bitmap and its transparency color
            /// </summary>
            /// <param name="strFilename">>Path of the Background Bitmap on the disk</param>
            /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
            /// <returns>Nothing</returns>
            public void SetBackgroundBitmap(string strFilename, Color transparencyColor)
            {
                BackgroundBitmap = new Bitmap(strFilename);
                Width = BackgroundBitmap.Width;
                Height = BackgroundBitmap.Height;
                Region = BitmapToRegion(BackgroundBitmap, transparencyColor);
            }
    
            /// <summary>
            /// Sets the background bitmap and its transparency color
            /// </summary>
            /// <param name="image">Image/Bitmap object which represents the Background Bitmap</param>
            /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
            /// <returns>Nothing</returns>
            public void SetBackgroundBitmap(Image image, Color transparencyColor)
            {
                BackgroundBitmap = new Bitmap(image);
                Width = BackgroundBitmap.Width;
                Height = BackgroundBitmap.Height;
                Region = BitmapToRegion(BackgroundBitmap, transparencyColor);
            }
    
            /// <summary>
            /// Sets the 3-State Close Button bitmap, its transparency color and its coordinates
            /// </summary>
            /// <param name="strFilename">Path of the 3-state Close button Bitmap on the disk (width must a multiple of 3)</param>
            /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
            /// <param name="position">Location of the close button on the popup</param>
            /// <returns>Nothing</returns>
            public void SetCloseBitmap(string strFilename, Color transparencyColor, Point position)
            {
                CloseBitmap = new Bitmap(strFilename);
                CloseBitmap.MakeTransparent(transparencyColor);
                CloseBitmapSize = new Size(CloseBitmap.Width / 3, CloseBitmap.Height);
                CloseBitmapLocation = position;
            }
    
            /// <summary>
            /// Sets the 3-State Close Button bitmap, its transparency color and its coordinates
            /// </summary>
            /// <param name="image">Image/Bitmap object which represents the 3-state Close button Bitmap (width must be a multiple of 3)</param>
            /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
            /// /// <param name="position">Location of the close button on the popup</param>
            /// <returns>Nothing</returns>
            public void SetCloseBitmap(Image image, Color transparencyColor, Point position)
            {
                CloseBitmap = new Bitmap(image);
                CloseBitmap.MakeTransparent(transparencyColor);
                CloseBitmapSize = new Size(CloseBitmap.Width / 3, CloseBitmap.Height);
                CloseBitmapLocation = position;
            }
            #endregion
    
            #region TaskbarNotifier Protected Methods
            protected void DrawCloseButton(Graphics grfx)
            {
                if (CloseBitmap != null)
                {
                    Rectangle rectDest = new Rectangle(CloseBitmapLocation, CloseBitmapSize);
                    Rectangle rectSrc;
    
                    if (bIsMouseOverClose)
                    {
                        if (bIsMouseDown)
                            rectSrc = new Rectangle(new Point(CloseBitmapSize.Width * 2, 0), CloseBitmapSize);
                        else
                            rectSrc = new Rectangle(new Point(CloseBitmapSize.Width, 0), CloseBitmapSize);
                    }
                    else
                        rectSrc = new Rectangle(new Point(0, 0), CloseBitmapSize);
    
    
                    grfx.DrawImage(CloseBitmap, rectDest, rectSrc, GraphicsUnit.Pixel);
                }
            }
    
            protected void DrawText(Graphics grfx)
            {
                if (titleText != null && titleText.Length != 0)
                {
                    StringFormat sf = new StringFormat();
                    sf.Alignment = StringAlignment.Near;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.FormatFlags = StringFormatFlags.NoWrap;
                    sf.Trimming = StringTrimming.EllipsisCharacter;				// Added Rev 002
                    if (bIsMouseOverTitle)
                        grfx.DrawString(titleText, hoverTitleFont, new SolidBrush(hoverTitleColor), TitleRectangle, sf);
                    else
                        grfx.DrawString(titleText, normalTitleFont, new SolidBrush(normalTitleColor), TitleRectangle, sf);
                }
    
                if (contentText != null && contentText.Length != 0)
                {
                    StringFormat sf = new StringFormat();
                    // Rev 006-CAS: New feature: Content alignement
                    switch (caContentAlignement)
                    {
                        case ContentAlignment.BottomCenter:
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Far;
                            break;
    
                        case ContentAlignment.BottomLeft:
                            sf.Alignment = StringAlignment.Near;
                            sf.LineAlignment = StringAlignment.Far;
                            break;
    
                        case ContentAlignment.BottomRight:
                            sf.Alignment = StringAlignment.Far;
                            sf.LineAlignment = StringAlignment.Far;
                            break;
    
                        case ContentAlignment.MiddleCenter:
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;
                            break;
    
                        case ContentAlignment.MiddleLeft:
                            sf.Alignment = StringAlignment.Near;
                            sf.LineAlignment = StringAlignment.Center;
                            break;
    
                        case ContentAlignment.MiddleRight:
                            sf.Alignment = StringAlignment.Far;
                            sf.LineAlignment = StringAlignment.Center;
                            break;
    
                        case ContentAlignment.TopCenter:
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Near;
                            break;
    
                        case ContentAlignment.TopLeft:
                            sf.Alignment = StringAlignment.Near;
                            sf.LineAlignment = StringAlignment.Near;
                            break;
                        case ContentAlignment.TopRight:
                            sf.Alignment = StringAlignment.Far;
                            sf.LineAlignment = StringAlignment.Near;
                            break;
    
    
                        default:
                            sf.Alignment = StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Center;
                            break;
                    }
                    //sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
                    //sf.Trimming = StringTrimming.Word;							// Added Rev 002
                    sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.LineLimit;
                    sf.Trimming = StringTrimming.EllipsisWord;
    
    
                    if (bIsMouseOverContent)
                    {
                        grfx.DrawString(contentText, hoverContentFont, new SolidBrush(hoverContentColor), ContentRectangle, sf);
                        if (EnableSelectionRectangle)
                            ControlPaint.DrawBorder3D(grfx, RealContentRectangle, Border3DStyle.Etched, 
                                                      Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Left | Border3DSide.Right);
                    }
                    else
                        grfx.DrawString(contentText, normalContentFont, new SolidBrush(normalContentColor), ContentRectangle, sf);                
                }
            }
    
            protected void CalculateMouseRectangles()
            {
                Graphics grfx = CreateGraphics();
                StringFormat sf = new StringFormat();
                // Rev 006-CAS: New feature: Content alignement
                // --- Replace
                //sf.Alignment = StringAlignment.Center;
                //sf.LineAlignment = StringAlignment.Center;            
                // --- With
                switch (caContentAlignement)
                {
                    case ContentAlignment.BottomCenter:
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Far;
                        break;
    
                    case ContentAlignment.BottomLeft:
                        sf.Alignment = StringAlignment.Near;
                        sf.LineAlignment = StringAlignment.Far;
                        break;
    
                    case ContentAlignment.BottomRight:
                        sf.Alignment = StringAlignment.Far;
                        sf.LineAlignment = StringAlignment.Far;
                        break;
    
                    case ContentAlignment.MiddleCenter:
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        break;
    
                    case ContentAlignment.MiddleLeft:
                        sf.Alignment = StringAlignment.Near;
                        sf.LineAlignment = StringAlignment.Center;
                        break;
    
                    case ContentAlignment.MiddleRight:
                        sf.Alignment = StringAlignment.Far;
                        sf.LineAlignment = StringAlignment.Center;
                        break;
    
                    case ContentAlignment.TopCenter:
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Near;
                        break;
    
                    case ContentAlignment.TopLeft:
                        sf.Alignment = StringAlignment.Near;
                        sf.LineAlignment = StringAlignment.Near;
                        break;
                    case ContentAlignment.TopRight:
                        sf.Alignment = StringAlignment.Far;
                        sf.LineAlignment = StringAlignment.Near;
                        break;
    
    
                    default:
                        sf.Alignment = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Center;
                        break;
                }
                // --- End Of replace
    
                sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
                SizeF sizefTitle = grfx.MeasureString(titleText, hoverTitleFont, TitleRectangle.Width, sf);
                SizeF sizefContent = grfx.MeasureString(contentText, hoverContentFont, ContentRectangle.Width, sf);
                grfx.Dispose();
    
                // Added Rev 002
                //We should check if the title size really fits inside the pre-defined title rectangle
                if (sizefTitle.Height > TitleRectangle.Height)
                {
                    RealTitleRectangle = new Rectangle(TitleRectangle.Left, TitleRectangle.Top, 
                                                       TitleRectangle.Width, TitleRectangle.Height);
                }
                else
                {
                    RealTitleRectangle = new Rectangle(TitleRectangle.Left, TitleRectangle.Top, 
                                                      (int)sizefTitle.Width, (int)sizefTitle.Height);
                }
                RealTitleRectangle.Inflate(0, 2);
    
                // Added Rev 002
                //We should check if the Content size really fits inside the pre-defined Content rectangle
    
                // Added Rev 006-CAS: New feature: Content alignement            
                // use of ContentTextAlignement
                int RealHeight = (sizefContent.Height > ContentRectangle.Height) ? ContentRectangle.Height : (int)sizefContent.Height;
                switch (caContentAlignement)
                {
                    case ContentAlignment.BottomCenter:
                        RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) / 2 + ContentRectangle.Left,
                                                            (ContentRectangle.Height - RealHeight) + ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
                    case ContentAlignment.BottomLeft:
                        RealContentRectangle = new Rectangle(ContentRectangle.Left,
                                                            (ContentRectangle.Height - RealHeight) + ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
                    case ContentAlignment.BottomRight:
                        RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) + ContentRectangle.Left,
                                                             (ContentRectangle.Height - RealHeight) + ContentRectangle.Top,
                                                             (int)sizefContent.Width, RealHeight);
    
                        break;
    
                    case ContentAlignment.MiddleCenter:
                        RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) / 2 + ContentRectangle.Left,
                                                            (ContentRectangle.Height - RealHeight) / 2 + ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
                    case ContentAlignment.MiddleLeft:
                        RealContentRectangle = new Rectangle(ContentRectangle.Left,
                                                            (ContentRectangle.Height - RealHeight) / 2 + ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
                    case ContentAlignment.MiddleRight:
                        RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) + ContentRectangle.Left,
                                                            (ContentRectangle.Height - RealHeight) / 2 + ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
                    case ContentAlignment.TopCenter:
                        RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) / 2 + ContentRectangle.Left,
                                                             ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
                    case ContentAlignment.TopLeft:
                        RealContentRectangle = new Rectangle(ContentRectangle.Left,
                                                             ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
                    case ContentAlignment.TopRight:
                        RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) + ContentRectangle.Left,
                                                             ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
    
    
                    default:
                        RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) / 2 + ContentRectangle.Left,
                                                            (ContentRectangle.Height - RealHeight) / 2 + ContentRectangle.Top,
                                                            (int)sizefContent.Width, RealHeight);
                        break;
                }
                // Updated rev 006-CAS:             
                RealContentRectangle.Inflate(4, 2);
            }
    
            protected Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
            {
                if (bitmap == null)
                    throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!");
    
                int height = bitmap.Height;
                int width = bitmap.Width;
    
                GraphicsPath path = new GraphicsPath();
    
                for (int j = 0; j < height; j++)
                    for (int i = 0; i < width; i++)
                    {
                        if (bitmap.GetPixel(i, j) == transparencyColor)
                            continue;
    
                        int x0 = i;
    
                        while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
                            i++;
    
                        path.AddRectangle(new Rectangle(x0, j, i - x0, 1));
                    }
    
                Region region = new Region(path);
                path.Dispose();
                return region;
            }
            #endregion
    
            #region TaskbarNotifier Events Overrides
            private void OnTimer(Object obj, EventArgs ea)
            {
                switch (taskbarState)
                {
                    case TaskbarStates.appearing:
                        // Updated Rev 003-CAS: Sliding or fading effect
                        if (bAppearBySliding)
                        {
                            if (Height < BackgroundBitmap.Height)
                                SetBounds(Left, Top - nIncrementShow, Width, Height + nIncrementShow);
                            else
                            {
                                // Updated Rev 004-CAS: New Property: Padding
                                // Updated Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                                if (Bottom > WorkAreaRectangle.Bottom - nPadding - nBaseWindowBottom)
                                    SetBounds(Left, Top - nIncrementShow, Width, Height);
                                else
                                {
                                    timer.Stop();
                                    Height = BackgroundBitmap.Height;
                                    timer.Interval = nVisibleEvents;
                                    taskbarState = TaskbarStates.visible;
                                    timer.Start();
                                }
                            }
                        }
                        else
                        {// Added Rev 003-CAS: Sliding or fading effect
                            if (Opacity < 1.0)
                                Opacity = Opacity + (1.0 / (BackgroundBitmap.Height / nIncrementShow));
                            else
                            {
                                timer.Stop();
                                Height = BackgroundBitmap.Height;
                                timer.Interval = nVisibleEvents;
                                taskbarState = TaskbarStates.visible;
                                timer.Start();
                            }
                        }
                        break;
    
                    case TaskbarStates.visible:
                        timer.Stop();
                        timer.Interval = nHideEvents;
                        // Added Rev 002
                        if ((bKeepVisibleOnMouseOver && !bIsMouseOverPopup) || (!bKeepVisibleOnMouseOver))
                        {
                            taskbarState = TaskbarStates.disappearing;
                        }
                        //taskbarState = TaskbarStates.disappearing;		// Rev 002
                        timer.Start();
                        break;
    
                    case TaskbarStates.disappearing:
                        // Added Rev 002
                        if (bReShowOnMouseOver && bIsMouseOverPopup)
                        {
                            taskbarState = TaskbarStates.appearing;
                        }
                        else
                        {
                            // Updated Rev 003-CAS: Sliding or fading effect
                            if (bAppearBySliding)
                            {
                                // Added Rev 006-CAS: Slide to the bottom and then reduce the popup height
                                if ((Top + Height) < WorkAreaRectangle.Bottom)
                                    SetBounds(Left, Top + nIncrementHide, Width, Height);
                                else
                                    if (Top < WorkAreaRectangle.Bottom)
                                        SetBounds(Left, Top + nIncrementHide, Width, Height - nIncrementHide);
                                    else
                                        Hide();
                                //	Removed Rev 006-CAS: Slide to the bottom and then reduce the popup height
                                //	 if (Top < WorkAreaRectangle.Bottom)
                                //	   SetBounds(Left, Top + nIncrementHide, Width, Height - nIncrementHide);
                                //	 else
                                //	   Hide();
                            }
                            else
                            {
                                if (Opacity > 0.1)
                                    Opacity = Opacity - (1.0 / (BackgroundBitmap.Height / nIncrementHide));
                                else
                                    Hide();
                            }
                        }
                        break;
                }
            }
    
            protected override void OnMouseEnter(EventArgs ea)
            {
                base.OnMouseEnter(ea);
                bIsMouseOverPopup = true;
                Refresh();
            }
    
            protected override void OnMouseLeave(EventArgs ea)
            {
                base.OnMouseLeave(ea);
                bIsMouseOverPopup = false;
                bIsMouseOverClose = false;
                bIsMouseOverTitle = false;
                bIsMouseOverContent = false;
                Refresh();
            }
    
            protected override void OnMouseMove(MouseEventArgs mea)
            {
                base.OnMouseMove(mea);
    
                // Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage			 
                if (bMoving)
                {
                    Point temp = new Point(0, 0);
                    temp.X = Location.X + (mea.X - nMouseDownX);
                    temp.Y = Location.Y + (mea.Y - nMouseDownY);
                    if ((temp.X + this.Size.Width) > Screen.GetWorkingArea(this.WorkAreaRectangle).Width)
                        temp.X = Screen.GetWorkingArea(this.WorkAreaRectangle).Width - this.Size.Width;
                    if ((temp.Y + this.Size.Height) > Screen.GetWorkingArea(this.WorkAreaRectangle).Height)
                        temp.Y = Screen.GetWorkingArea(this.WorkAreaRectangle).Height - this.Size.Height;
    
                    if (temp.X < 0)
                        temp.X = 0;
                    if (temp.Y < 0)
                        temp.Y = 0;
    
                    Location = temp;
                    Application.UserAppDataRegistry.SetValue("ToastBottom", WorkAreaRectangle.Height - Top - Height - Padding);
                    Application.UserAppDataRegistry.SetValue("ToastRight", WorkAreaRectangle.Width - Left - Width - Padding);
                    nBaseWindowBottom = WorkAreaRectangle.Height - Top - Height - Padding;
                    nBaseWindowRight = WorkAreaRectangle.Width - Left - Width - Padding;
                }
    
                bool bContentModified = false;
    
                if ((mea.X > CloseBitmapLocation.X) 
                     && (mea.X < CloseBitmapLocation.X + CloseBitmapSize.Width) 
                     && (mea.Y > CloseBitmapLocation.Y) 
                     && (mea.Y < CloseBitmapLocation.Y + CloseBitmapSize.Height) 
                     && CloseClickable)
                {
                    if (!bIsMouseOverClose)
                    {
                        bIsMouseOverClose = true;
                        bIsMouseOverTitle = false;
                        bIsMouseOverContent = false;
                        Cursor = Cursors.Hand;
                        bContentModified = true;
                    }
                }
                else if (RealContentRectangle.Contains(new Point(mea.X, mea.Y)) && ContentClickable)
                {
                    if (!bIsMouseOverContent)
                    {
                        bIsMouseOverClose = false;
                        bIsMouseOverTitle = false;
                        bIsMouseOverContent = true;
                        Cursor = Cursors.Hand;
                        bContentModified = true;
                    }
                }
                else if (RealTitleRectangle.Contains(new Point(mea.X, mea.Y)) && TitleClickable)
                {
                    if (!bIsMouseOverTitle)
                    {
                        bIsMouseOverClose = false;
                        bIsMouseOverTitle = true;
                        bIsMouseOverContent = false;
                        Cursor = Cursors.Hand;
                        bContentModified = true;
                    }
                }
                else
                {
                    if (bIsMouseOverClose || bIsMouseOverTitle || bIsMouseOverContent)
                        bContentModified = true;
    
                    bIsMouseOverClose = false;
                    bIsMouseOverTitle = false;
                    bIsMouseOverContent = false;
                    Cursor = Cursors.Default;
                }
    
                if (bContentModified)
                    Refresh();
            }
    
            protected override void OnMouseDown(MouseEventArgs mea)
            {
                base.OnMouseDown(mea);
    
                bIsMouseDown = true;
    
                if (bIsMouseOverClose)
                    Refresh();
                // Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                else
                    if (mea.Button == MouseButtons.Left)
                    {
                        bMoving = true;
                        nMouseDownX = mea.X;
                        nMouseDownY = mea.Y;
                    }
    
            }
    
            protected override void OnMouseUp(MouseEventArgs mea)
            {
                base.OnMouseUp(mea);
                bIsMouseDown = false;
    
                // Added Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
                if (mea.Button == MouseButtons.Left)
                    bMoving = false;
    
                if (bIsMouseOverClose)
                {
                    Hide();
    
                    if (CloseClick != null)
                        CloseClick(this, new EventArgs());
                }
                else if (bIsMouseOverTitle)
                {
                    if (TitleClick != null)
                        TitleClick(this, new EventArgs());
                }
                else if (bIsMouseOverContent)
                {
                    if (ContentClick != null)
                        ContentClick(this, new EventArgs());
                }
            }
    
            protected override void OnPaintBackground(PaintEventArgs pea)
            {
                Graphics grfx = pea.Graphics;
                grfx.PageUnit = GraphicsUnit.Pixel;
    
                Graphics offScreenGraphics;
                Bitmap offscreenBitmap;
    
                offscreenBitmap = new Bitmap(BackgroundBitmap.Width, BackgroundBitmap.Height);
                offScreenGraphics = Graphics.FromImage(offscreenBitmap);
    
                if (BackgroundBitmap != null)
                {
                    offScreenGraphics.DrawImage(BackgroundBitmap, 0, 0, BackgroundBitmap.Width, BackgroundBitmap.Height);
                }
    
                DrawCloseButton(offScreenGraphics);
                DrawText(offScreenGraphics);
    
                grfx.DrawImage(offscreenBitmap, 0, 0);
            }
            #endregion
    
            private void InitializeComponent()
            {
                this.SuspendLayout();
                // 
                // TaskbarNotifier
                // 
                this.ShowInTaskbar = false;
                this.ClientSize = new System.Drawing.Size(284, 264);
                this.Name = "TaskbarNotifier";
                this.ResumeLayout(false);
    
            }
    
        }
        #region Rev 005-CAS: New feature: Management of Toasts' Collection and last position storage
        /// <summary>
        /// ToastCollection allows to Manage a set of TaskbarNotifier object
        /// </summary>
        public class ToastCollection
        {
            #region ToastCollection Private Members
            protected int nToastCount = 0;
            protected int nBaseWindowBottom = 0;
            protected int nBaseWindowRight = 0;
            #endregion
    
            #region ToastCollection Public Methods
            /// <summary>
            /// The Constructor for ToastCollection
            /// </summary>
            public ToastCollection()
            {
                nBaseWindowBottom = Convert.ToInt32(Application.UserAppDataRegistry.GetValue("ToastBottom", "0"));
                nBaseWindowRight = Convert.ToInt32(Application.UserAppDataRegistry.GetValue("ToastRight", "0"));
            }
            /// <summary>
            /// Add the toast to the collection and calculate the coordinate of the next toast.
            /// </summary>
            /// <param name="newToast">TaskbarNotifier object to add to the collection.</param>
            /// <param name="screenTop">Max height to reach before changing column.</param>
            /// <param name="baseWindowBottom">Current distance from the bottom of the screen (updated in the Method)</param>
            /// <param name="baseWindowRight">Current distance from the right of the screen (updated in the Method)</param>
            /// <returns>Nothing</returns>
            public void AddToast(TaskbarNotifier newToast,
                int screenTop,
                ref int baseWindowBottom,
                ref int baseWindowRight)
            {
                // If this window would be placed above visible screen
                // move the window to a new column of windows and reset the bottom
                if (nBaseWindowBottom > (screenTop - newToast.Height))
                {
                    if (nBaseWindowRight > newToast.Width)
                        nBaseWindowRight = 0;
                    else
                        nBaseWindowRight = nBaseWindowRight + newToast.Width + newToast.Padding;
                    nBaseWindowBottom = Convert.ToInt32(Application.UserAppDataRegistry.GetValue("ToastBottom", "0"));
                }
                nToastCount += 1;
                baseWindowBottom = nBaseWindowBottom;
                baseWindowRight = nBaseWindowRight;
    
                // Increment bottom for next window
                nBaseWindowBottom = nBaseWindowBottom + newToast.Height + newToast.Padding;
            }
            /// <summary>
            /// Close the Toast object and calculate, if needed the new coordinates.
            /// </summary>
            /// <param name="toast">TaskbarNotifier object to close and dispose.</param>
            /// <returns>Nothing</returns>
            public void KillWindow(TaskbarNotifier toast)
            {
                nToastCount -= 1;
                if (nToastCount == 0)
                {
                    nBaseWindowBottom = Convert.ToInt32(Application.UserAppDataRegistry.GetValue("ToastBottom", "0"));
                    nBaseWindowRight = Convert.ToInt32(Application.UserAppDataRegistry.GetValue("ToastRight", "0"));
                }
                toast.Close();
                toast.Dispose();
            }
            #endregion
        }
        #endregion
    
    }

    I hope it will help you Wink | ;)

                  _________________________________ 
                 /    Crusty.Applesniffer@free.fr  \ 
    |^^^^^^|    /http://Crusty.Applesniffer.free.fr \
    |      |   |------------------------------------| 
    |      |   |                                    |
    | (o)(o) o | Programmers don't die,             | 
    @     _) o | they just GOSUB without RETURN     | 
    | ,___| o   \                                  / 
    |    /       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    /____\ 

    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    kurimus22-Jan-08 23:25
    kurimus22-Jan-08 23:25 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    kurimus22-Jan-08 23:25
    kurimus22-Jan-08 23:25 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    angie198314-May-08 9:13
    angie198314-May-08 9:13 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    Crusty Applesniffer8-Oct-08 4:47
    Crusty Applesniffer8-Oct-08 4:47 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    easycodes8-Oct-08 4:22
    easycodes8-Oct-08 4:22 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    Crusty Applesniffer8-Oct-08 4:47
    Crusty Applesniffer8-Oct-08 4:47 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    Dragon Chuang23-Jul-09 19:09
    Dragon Chuang23-Jul-09 19:09 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    thermo_ll21-Jun-10 10:07
    thermo_ll21-Jun-10 10:07 
    GeneralRe: Sliding/Fading, Padding, ContentTextAlignment Properties and Toasts Collection Pin
    thermo_ll21-Jun-10 10:07
    thermo_ll21-Jun-10 10:07 
    GeneralThe popup steals focus in my class library app. Pin
    Mustafa Özçetin25-Aug-07 10:31
    Mustafa Özçetin25-Aug-07 10:31 
    GeneralRe: The popup steals focus in my class library app. Pin
    Mustafa Özçetin25-Aug-07 10:44
    Mustafa Özçetin25-Aug-07 10:44 
    GeneralRe: The popup steals focus in my class library app. Pin
    Mark de Haan2-Jun-08 22:19
    Mark de Haan2-Jun-08 22:19 
    GeneralCompliments Pin
    bluetwistie21-Aug-07 20:24
    bluetwistie21-Aug-07 20:24 
    GeneralNot steaing the Focus, when the window popup;s up Pin
    TgParmar18-Aug-07 4:42
    TgParmar18-Aug-07 4:42 
    GeneralRe: Not steaing the Focus, when the window popup;s up Pin
    Derek Bartram13-Mar-08 5:00
    Derek Bartram13-Mar-08 5:00 
    Generalshow on top Pin
    floweb8116-Aug-07 1:50
    floweb8116-Aug-07 1:50 
    Generalcool! Pin
    flyingchen8-Aug-07 14:57
    flyingchen8-Aug-07 14:57 

    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.