Contents

Introduction

One of the major changes to how the Windows 7 Taskbar operates is in an area that Microsoft calls peripheral
status. This covers two types of status indicators: progress for long operations, and icons for important notifications.
Apps can continue to use progress dialogs during long operations, but the Windows 7 Taskbar lets the app show a
progress bar in its Taskbar button as well, so the user can see the progress indicator at a glance, without having
to switch to the app.

Many apps also use the notification area to convey important status information. For example, Outlook shows
an icon when you have new email. However, in Windows 7, notification area icons are hidden by default, so the notification
area is no longer useful for displaying this kind of status. The Taskbar lets an app display a 16x16 icon that
is overlaid on the existing icon in its Taskbar button. This prevents the notification area from getting too crowded,
and keeps the status icon visually associated with the app that created it.

This article's sample app is a re-write of the file downloader from my article Using
Internet Explorer to download files for you. The app shows the download progress in its Taskbar button,
in addition to a traditional progress bar in the dialog. This app didn't have a notification area icon before,
but for the purposes of demonstrating the API calls involved, it has commands for showing a status icon as well.

Using the New Taskbar Interfaces

Here is a screen shot of the revised downloader app:

As with jump lists, progress indicators are exposed through a new COM interface.

The ITaskbarList3 interface

Before our app can use peripheral status features, we must create an ITaskbarList3 interface. ITaskbarList3
is a new interface in Windows 7 that provides access to many of the new Taskbar features. There is a bit more to
this than just calling CoCreateInstance(), however. We must wait for Windows to tell us that our Taskbar
button has been created. Windows does this by sending our main window a registered message called TaskbarButtonCreated.
Once we receive that message, it's safe to create an ITaskbarList3 interface and call its methods.

The main dialog class has a private data member that holds the ID of this message. This member is initialized
during the app's startup sequence, and used in the message map:

It's possible for the Taskbar to send this message multiple times. For instance, if Explorer crashes and restarts,
it will recreate the Taskbar, and notify all running apps again that their buttons have been created. To handle
the case where we get multiple TaskbarButtonCreated messages, we release any existing interface we
might have, and create a new one.

If your app will run on versions of Windows before Windows 7, be aware that anyone could register a window message
called TaskbarButtonCreated and broadcast it. To protect against this, you should ignore the message
if the OS is older than Windows 7. Here's the updated message handler that checks the OS version:

There's one final detail to take care of: We have to tell Windows to allow the TaskbarButtonCreated
message to be sent to our window if our app is running elevated. We do this in our WM_INITDIALOG handler:

As before, hwnd is the HWND of our dialog. ullCompleted represents the
amount of work completed so far, and ullTotal represents the total amount of work. The Taskbar will
convert ullCompleted to a percentage, and the progress bar will display that percentage. If the bar
is currently in the indeterminate state, calling SetProgressValue() will automatically put the bar
into the normal state.

How the sample project uses the progress bar

Since the dialog has a progress bar as well, that progress bar and the Taskbar progress bar are typically in
the same state and showing the same information. For instance, when a download starts, we reset the progress bar
and clear any existing progress indicator:

The app also uses the paused state to indicate that the download timed out, and the error state to indicate
that the download stopped because of an error. For example, if you cancel the download, the progress bars look
like this:

You can look at the CMainDlg::OnThreadExited() function in the sample code to see how this is done.

Showing an Overlay Status Icon

An app can add an overlay icon to its Taskbar button by calling SetOverlayIcon():

As with the progress indicator methods, hwnd is our dialog's HWND. hIcon
is a 16x16 icon. You can also pass NULL to remove the overlay icon altogether. pszDescription
is textual version of the status indicator; this string will be used by accessibility applications to convey the
status to users that can't see the icon. The Taskbar makes its own copy of the icon, so the caller can destroy
its HICON immediately if it wants to.

There are two things to watch out for when using overlay icons:

If the Taskbar is set to show small icons, then overlay icons are not shown at all.

If several windows are grouped into one Taskbar button, only one icon can be shown at a time - the last app
to call SetOverlayIcon() wins. But if one of the windows in the group removes its overlay icon, and
a previous icon has not been removed, it is shown again.

To try out overlay icons in the sample app, click the Taskbar Icon button. You'll get a menu with three
commands: Green, Red, and None. Green and Red each set a different icon, and
None removes the icon. Here's how the green overlay icon looks:

Share

About the Author

Michael lives in sunny Mountain View, California. He started programming with an Apple //e in 4th grade, graduated from UCLA with a math degree in 1994, and immediately landed a job as a QA engineer at Symantec, working on the Norton AntiVirus team. He pretty much taught himself Windows and MFC programming, and in 1999 he designed and coded a new interface for Norton AntiVirus 2000.Mike has been a a developer at Napster and at his own lil' startup, Zabersoft, a development company he co-founded with offices in Los Angeles and Odense, Denmark. Mike is now a senior engineer at VMware.

He also enjoys his hobbies of playing pinball, bike riding, photography, and Domion on Friday nights (current favorite combo: Village + double Pirate Ship). He would get his own snooker table too if they weren't so darn big! He is also sad that he's forgotten the languages he's studied: French, Mandarin Chinese, and Japanese.