Animating System Tray Icons


This article explains how to animate an icon in the Shell tray and assign dynamically changing tooltips for each icon phase. So the end result will be that your icon can now visually indicate what your application is currently doing along with corresponding tooltip descriptions. User notifications like left click and right click on the icon are also handled. The Windows NT  resource usage indicator on the Shell Tray is a wonderful example of animating icons on the Shell Tray. Let's animate now !.

Step 1: (Setting up the data for the animation)

The first step involves setting up well organized arrays that kind of keep track of the icons lined up for animation along with their tooltip description strings. Also define a user defined notification that will let you know if the user clicked on the animating icon. Swing by at your resource editor and create all the icons that you need and give them the same ids specified in the array.


static int iconResourceArray[NUM_ICONS_IN_ANIMATION] =

static CString strToolTipArray[NUM_ICONS_IN_ANIMATION] = 
 CString("Resource Usage = 20%") ,
 CString("Resource Usage = 40%") ,
 CString("Resource Usage = 60%") ,
 CString("Resource Usage = 80%"),
 CString("Resource Usage = 100%") }; 


Step 2:(Adding an useful helper function)

Take a look at this useful helper function below that wraps up the Shell_NotifyIcon call. The first  parameter indicates to the helper whether you need to add,delete, or modify an icon in the Shell Tray by specifying NIM_ADD, NIM_DELETE, or NIM_MODIFY. The second parameter indicates the index of the icon in the array that you set up in Step 1. The third parameter indicates the tooltip string for the currently displayed icon.

void CShellAnimDlg::InstallAnimatedIcon(DWORD dwMsgType,UINT nIndexOfIcon, CString strToolTip)

	//Load the specified icon from the array
	HICON hIconAtIndex = AfxGetApp()->LoadIcon(iconResourceArray[nIndexOfIcon]);

	///Fill up the NOTIFYICONDATA Structure
	iconData.cbSize		= sizeof(NOTIFYICONDATA);
	iconData.hWnd		= GetSafeHwnd();  //window's handle
	iconData.uID			= 100 ;  //identifier
	iconData.uFlags		= NIF_MESSAGE|NIF_ICON|NIF_TIP; //flags
	iconData.uCallbackMessage	= MYMSG_NOTIFYICON; //notification handler
	iconData.hIcon		= hIconAtIndex;    //icon handle   
	//Fill up tool tip
	LPCTSTR lpszToolTip = strToolTip.GetBuffer(strToolTip.GetLength());
	//Tell the shell what we intend doing
	//Add,Delete,Modify ---> NIM_ADD,NIM_DELETE, NIM_MODIFY in dwMsgType
	Shell_NotifyIcon(dwMsgType, &iconData); 

	//Resources are precious !
	if (hIconAtIndex)


Step 3: (Animating the icon)

Whenever you need to start the animation, begin by adding an icon first on the tray by calling the helper function with NIM_ADD. Subsequently, cycle through the animation by calling NIM_MODIFY. The following code which is a dialog based application adds the first icon in OnInitDialog() and then sets up a timer that cycles through the animation.

BOOL CShellAnimDlg::OnInitDialog()
    ///usual initialization goes here   	
    int nIndexFirstIcon = 0;
    return TRUE; // return TRUE unless you set the focus to a control
void CShellAnimDlg::OnTimer(UINT nIDEvent) 
	// TODO: Add your message handler code here and/or call default
	static int nCounter = 0;
	m_nCounter = nCounter; //Store it here to keep track of the last displayed icon
	nCounter = nCounter%(NUM_ICONS_IN_ANIMATION);


Please Note: You may need to get the last icon off the tray when the application closes. So make sure you get the icon off the tray when your application closes by calling:



Step 4: (Handling notifications)

We now  need to keep track of  user actions on our icon.. Remember the user defined message id MYMSG_NOTIFYICON that we passed for callback notification to the NOTIFYICONDATA structure in the helper function. Well, the icon posts a message whenever the user performs an action on the icon. We are interested only on mouse clicks and so let's handle them. Firstly, go ahead and define a user defined message as shown in step 1. Once you're done with that , map the message handler to a function as shown below.

afx_msg void OnHandleIconNotify(UINT wParam, LONG lParam);                //function to handle notifications

ON_MESSAGE(MYMSG_NOTIFYICON,OnHandleIconNotify)      //message mapped to function

void CShellAnimDlg::OnHandleIconNotify(UINT wParam, LONG lParam)
    CString strTest;
    CString strCurrPosition(strToolTipArray[m_nCounter]);
    switch (lParam)
        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
        case WM_LBUTTONDBLCLK:
            ///Do whatever you need to do when the click occured
            //Current icon animation position is at m_nCounter


You now have your animated icon cycling through it's phases on the Shell Tray with different tool tips depending on the icon position in the cycle order.

Last updated: 17 June 1998


  • Using AVI file

    Posted by Legacy on 05/17/2002 12:00am

    Originally posted by: Naresh

    Should include animation using AVI FILE.

  • This is what I needed

    Posted by Legacy on 02/03/2001 12:00am

    Originally posted by: Mark Benchley

    This stuff is really nice!.
    I needed something like this for my application

  • A Usefull Artical

    Posted by Legacy on 09/22/1999 12:00am

    Originally posted by: Philip Heald

    Thanks I found this artical extreamly usefull, it described exactly how to do something I've been trying to do for a few days !!!!

  • Other implementations

    Posted by Legacy on 04/05/1999 12:00am

    Originally posted by: Scott Seely

    For another implementation of a similar concept, you can go to I wrote an article for the November 98 issue of WDJ that covers the same topic, although with a slightly different angle. All the animation jive is hidden from the user. Anyhow, if you want another implementation, download the above file. The archive within NOV98.ZIP that you want is SEELY.ZIP.

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: May 11, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT One of the languages that have always been supported with the Intel® RealSense™ SDK (Software Developer Kit) is JavaScript, specifically so that web-enabled apps could be created. Come hear from Intel Expert Bob Duffy as he reviews his own little "space shooting" game where the orientation of your face controls the aiming reticle to help teach developers how to write apps and games in JavaScript that can use facial and gesture …

  • Several technologies are driving big changes at federal agencies, but at the forefront is cloud computing. Cloud -- the use of remote, Internet-hosted servers for storing, managing and processing data in place of on-site technology -- is helping along technologies such as those related to collaboration and enabling new ones, such as the analysis of Big Data. Cloud is complicated but also growing in importance at federal agencies. Read this technology article to learn how governmental entities are creating a …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date