Click here to Skip to main content
15,888,454 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.7M   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

 
GeneralHelp to include this project in a ASP .NET WEB Application Pin
shi12320-Feb-04 17:49
shi12320-Feb-04 17:49 
GeneralRe: Help to include this project in a ASP .NET WEB Application Pin
Anonymous20-Feb-04 18:01
Anonymous20-Feb-04 18:01 
GeneralRe: Help to include this project in a ASP .NET WEB Application Pin
shi12321-Feb-04 9:40
shi12321-Feb-04 9:40 
GeneralRe: Help to include this project in a ASP .NET WEB Application Pin
sjkd16-Mar-04 22:54
sjkd16-Mar-04 22:54 
GeneralRe: Help to include this project in a ASP .NET WEB Application Pin
John O'Byrne17-Mar-04 2:11
John O'Byrne17-Mar-04 2:11 
GeneralRe: Help to include this project in a ASP .NET WEB Application Pin
sjkdo17-Mar-04 5:38
sjkdo17-Mar-04 5:38 
GeneralRe: Help to include this project in a ASP .NET WEB Application Pin
shilpi12317-Mar-04 9:48
shilpi12317-Mar-04 9:48 
Questionhow I solved my popup problem Pin
jmacduff11-Feb-04 4:24
jmacduff11-Feb-04 4:24 
I had a problem with this class like many of you I think. What I saw was jittery pop ups, sometimes only getting the very top edge of the toast to appear, etc.

I found the problem was that the message qeue used by the notifyicon class is the same as the thread. So if you call icon.show() from a worker thread and then the thread exits the icon never shows or u get just the top edge. Also if you u call icon.show() and then sit in a sleep loop in the worker thread waiting for the icon/toast to go away.. while it's sleeping no messages are shown cause the message pump is in the sleep statement... so this was my approach:

1. Main UI thread
2. Worker thread based on forms() --> just hide the dialog and remove it from the alt+tab menu plus the taskbar. Worker thread is based on a class member from the UI thread.

For me, the UI thread has a timer that every X seconds looks for something to pop up.. if it does here is the series of events:

1. UI thread kicks off the worker thread.
2. Worker thread Calls back into a UI thread member using the Invoke() command. For this case, Invoke basiccly allows this worker thread to call a UI thread member function as if the worker thread was the UI thread. it's 100% non blocking, kind of a impersantion thing.
4. The worker thread creates the toast object and then puts the object into a array list that's a member of the UI thread class ( public ArrayList MyPopups )
5. This member on the UI thread ( called by the worker thread, UIThread.ShowPopUp() ) then shows the icon.
6. A Modified Icon class calls back into the UI thread using the invoke method again when the toast closes or is closed passing in the "this" pointer from the icon ( something like UIThread.ToastCloseEvent( this ). I changed the code in the toast class to accomodate this.
7. This member in the UI Thread (ToastCloseEvent) then removes the icon object from the arraylist and the CLR will then clean it up.

This allows me to show mulitlpe toasts from a timer , created in a seperate worker thread, and not have any paint issues. hope this helps Smile | :)

GeneralTaskbarNotifier Error Pin
jen0s5-Feb-04 4:26
jen0s5-Feb-04 4:26 
GeneralRe: TaskbarNotifier Error Pin
John O'Byrne5-Feb-04 5:20
John O'Byrne5-Feb-04 5:20 
GeneralRe: TaskbarNotifier Error Pin
jen0s5-Feb-04 7:00
jen0s5-Feb-04 7:00 
GeneralRe: TaskbarNotifier Error Pin
neozhu15-Feb-04 16:48
neozhu15-Feb-04 16:48 
QuestionHow about a Longhorn style Pin
Bydia1-Feb-04 14:20
Bydia1-Feb-04 14:20 
AnswerRe: How about a Longhorn style Pin
jmacduff11-Feb-04 4:28
jmacduff11-Feb-04 4:28 
GeneralI have a problem Pin
okantekeli28-Jan-04 10:55
okantekeli28-Jan-04 10:55 
GeneralGeneration from windows service problem Pin
mprince200312-Dec-03 6:54
mprince200312-Dec-03 6:54 
GeneralRe: Generation from windows service problem Pin
John O'Byrne12-Dec-03 7:01
John O'Byrne12-Dec-03 7:01 
GeneralRe: Generation from windows service problem Pin
mprince200312-Dec-03 8:52
mprince200312-Dec-03 8:52 
GeneralRe: Generation from windows service problem Pin
John O'Byrne12-Dec-03 14:31
John O'Byrne12-Dec-03 14:31 
GeneralVC++ Pin
Balkrishna Talele3-Dec-03 22:46
Balkrishna Talele3-Dec-03 22:46 
GeneralRe: VC++ Pin
John O'Byrne4-Dec-03 3:28
John O'Byrne4-Dec-03 3:28 
GeneralHelp me Pin
Member 71325818-Nov-03 13:27
Member 71325818-Nov-03 13:27 
Questiontaking too much memory? Pin
Joaquin Grech (Creative1)16-Nov-03 5:17
Joaquin Grech (Creative1)16-Nov-03 5:17 
AnswerRe: taking too much memory? Pin
Bojan Rajkovic10-May-04 16:00
Bojan Rajkovic10-May-04 16:00 
AnswerRe: taking too much memory? Pin
Mr SQL24-Apr-07 7:37
Mr SQL24-Apr-07 7:37 

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.