Animate an Icon on the Taskbar when the Application Is Minimized

Introduction

This article will show the technique to animate an application's icon on the Taskbar when the application is minimized. The main usage of this implementation is to inform the user about some background tasks that are still active in the application when it is minimized.

Integrate to an Existing Project

Some Information about Windows Icons

Before the integration, it's good to understand how Windows make use of the icon attached to a specific application. Normally, there will be more than one icon (with a difference in sizes) associated in a single icon file (.ico). At run time, Windows will determine the correct icon size to use based on the different interfaces.

Icon sizes:

  • 16x16: Displayed in Taskbar, Windows upper-left corner, detailed lists
  • 24x24: Displayed in Windows XP start menu
  • 32x32: Displayed on desktop, by Windows Explorer
  • 48x48: Displayed in Windows XP Explorer and system lists

Color depths:

  • Monochrome: Not used anymore
  • 16 colors: Displayed by Windows if the screen is 16 or 256 colors
  • 256 colors: Displayed by Windows if the screen is 64K or 16M colors
  • 16M colors (XP): Displayed by Windows XP if screen is 16M or more

First, additional icons are needed in the application; these icons will act as the "animation frames." Because the animated icons will appear only on the Taskbar, you will create 16x16 icons. One way is to use Application Studio to create them. Or, there are also many free icon tools you can download from the Internet. If you are using an external icon tool, you need to import your newly created icons back to your project's resource. Once the new icons are added to the resource, any one of them can be chosen to replace the current one at run time.

In this demo project, a timer event will be fired twice a second to inform the application when it's time to change the icon. To achieve this, you add two message-handling functions:

Object ID Function Message
CMainFrame OnTimer WM_TIMER
CMainFrame OnDestroy WM_DESTROY
#define _totalArrayItem(array) (sizeof(array) / sizeof(array[0]) )
void CMainFrame::OnTimer(UINT nIDEvent) 
{
   static int icons[] = {
      IDI_ICON1, IDI_ICON2, IDI_ICON3, IDI_ICON4, IDI_ICON5,
      IDI_ICON6
   };


   static long nIndex = 0;

   if (IsIconic()) {
      SetWindowText("Processing");
      ChangeIcon(icons[nIndex ++ % _totalArrayItem(icons)]);
   }
   else {
      nIndex = 0;
      SetWindowText("My Icon Will Animate On Taskbar When I am
                     Minimized!");
      ChangeIcon(IDR_MAINFRAME);
   }

}

To ease the arrangement of the animation sequence, an icon array is used to keep a pool of icons.

Don't forget to destroy the timer on exit.

void CMainFrame::OnDestroy()
{
   CFrameWnd::OnDestroy();

   KillTimer(TIMER_ANIM_ID);
}

A new method called ChangeIcon will be created. You can call this method at ru time to change the icon. This method loads the requested icon and replaces the current window icon. The old icon is then removed.

protected:
   void ChangeIcon(UINT nNewIconID);

void CMainFrame::ChangeIcon(UINT nNewIconID)
{
   //get new icon handle
   HICON hIconNew = AfxGetApp()->LoadIcon(nNewIconID);
   //get current showing icon handle
   HICON hIconCurr = (HICON) GetClassLong(m_hWnd, GCL_HICON);

   ASSERT(hIconNew);
   ASSERT(hIconCurr);

   // replace current icon with new one and redraw the window
   if (hIconNew != hIconCurr) {
      DestroyIcon(hIconCurr);
      SetClassLong(m_hWnd, GCL_HICON, (long) hIconNew);
      RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME |
                   RDW_INVALIDATE);
   }
}

The Window Class Word

The window class word holds information about the windows's icon, windows style, cursor, menu, and brush. ChangeIcon uses GetClassLong and SetClassLong to change the icon.

GetClassLong Function

The GetClassLong function retrieves the specified 32-bit (long) value from the WNDCLASSEX structure associated with the specified window.

DWORD GetClassLong(
   HWND hWnd,    // handle to window
   int nIndex    // offset of value to retrieve
);

SetClassLong Function

The SetClassLong function replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the WNDCLASSEX structure for the class to which the specified window belongs.

DWORD SetClassLong(
   HWND hWnd,        // handle to window
   int nIndex,       // index of value to change
   LONG dwNewLong    // new value
);

Passing nIndex with GCL_HICON will retrieve a handle to the icon associated with the class.



About the Author

Kevin Choong

Kevin is a C++ & C# developer with proven ability to architect, program, and optimize code. He has more than 10 years programming experience for business solutions. He also has the passion for both playing and developing video games. Kevin can be reached via kevin.choong@hotmail.com.

Downloads

Comments

  • nice idea

    Posted by kirants on 10/07/2006 01:09pm

    Minor thing. The icon on the alt-tab doesn't show up though. It looks like you missed to update the non 16 X 16 icons

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

Top White Papers and Webcasts

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

  • Event Date: April 15, 2014 The ability to effectively set sales goals, assign quotas and territories, bring new people on board and quickly make adjustments to the sales force is often crucial to success--and to the field experience! But for sales operations leaders, managing the administrative processes, systems, data and various departments to get it all right can often be difficult, inefficient and manually intensive. Register for this webinar and learn how you can: Align sales goals, quotas and …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds