Introduction
This article describes how to use Windows 7 new taskbar features, progress indication and overlay icon, from unmanaged .NET code. The second part shows you how to manage progress indication and overlay icons in case of multiple views (windows) and provides appropriate missing classes for Windows API Code Pack.
Windows 7, New Taskbar, Progress Bar and Overlay Icon
If you look at the “What’s New” feature list on the Windows 7 official web site, the top most one is the improved taskbar.
Yes the taskbar has undergone a facelift, but there are also a number of really new key features. In this article, I’d like to treat two things: progress indication and icon overlays. Nearly each modern application which performs some activities in the background wants to notify the user without interrupting him/her that the job is done/failed or some kind of attention is needed.
This screenshot shows some taskbar buttons with different progress states and overlay icons:
- 0 - Normal progress 70%
- 1 - Indeterminate progress (travelling strip) with a red cross overlay icon
- 2 - Error progress 80%
- 3 - No progress with a star overlay icon
Do We Need It At All?
The functionality of progress indication and overlay icons is not only nice to have for applications which target Windows 7, but it is also essential for many applications which need to provide progress information in the taskbar. Most applications currently use window title which always appears in taskbar (at list its beginning). So in this case, you see usually a text “27% done”, or "New Message" on the taskbar button behind the icon of an application.
In Windows 7 per default you see only a large button with the high resolution icon on it without a caption (window title), it means the information which was communicated through window title is lost now if we do not use taskbar progress indication and overlay icon features.
How To Use It?
Windows 7 API provides appropriate methods SetOverlayIcon
, SetProgressState
and SetProgressValue
on ITaskBarList3
interface. To enable usage of this and many other features, Microsoft provides a .NET library Windows® API Code Pack for Microsoft® .NET Framework. For more information and download see Windows® API Code Pack for Microsoft® .NET Framework under code.msdn.microsoft.com/WindowsAPICodePack.
Taskbar handling is really very easy using these .NET classes, which are provided together with C# code. For detailed step by step instructions, see Gunther Lenz's webcasts here.
Basically you need only to include projects Core
and Shell
into your solution and use classes Microsoft.WindowsAPICodePack.Shell.Taskbar
, Microsoft.WindowsAPICodePack.Shell.Taskbar.ProgressBar
, Microsoft.WindowsAPICodePack.Shell.Taskbar.OverlayIcon
which are described in the supplied online documentation.
My first sample project Gma.Windows7.TaskbarDemo1
demonstrates basic progress indication and overlay icon functionality as provided by Code Pack.
How About Multiple Views?
What if we have multiple windows (forms) in the same application?
Are they able to each have their own progress and overlay icon?
How are these multiple views displayed in Windows 7 taskbar?
Having multiple windows each with individual progress is quite a common scenario; you might have several downloads running concurrently. Unfortunately (as of today) Windows API Code Pack is designed to manage a single progress bar and a single overlay icon. Although there is a class MultipleViewProgressBar
and an appropriate member on Taskbar
it does not provide the right behavior. I think the whole concept was misinterpreted during implementation, because you can read in online help: "MultipleViewProgressBar - Represents a taskbar button’s progress bar feature that is associated with multiple windows. Only one progress bar will get displayed on the taskbar, but states for different windows can be maintained." This is untrue. At the first sight you really need only one progress bar and overlay icon, because in Windows 7 you see only one button for all the windows of the same application. They are shown stacked, like laying upon another.
But there is an option you can change in Windows 7 taskbar properties. You can select between "Always combine, hide labels", "Combine when taskbar is full" and "Never combine". Let us select the "Never combine" option.
Now we see a button per window and want to manage progress and overlay icon for each of them separately. If you look at native API, you will see that methods SetProgressState
and SetProgressValue
have a window handle as the first argument. It seems that the Windows API Code Pack managed wrapper reduced functionality.
Yes We Can!
My second sample project Gma.Windows7.TaskbarDemo2
uses extensions to Windows API Code Pack which enable these lost features. I hope that future versions of Code Pack will improve on that scope. The only difference between the original Code Pack and our "patched" Code pack are two additional classes Microsoft.WindowsAPICodePack.Shell.Taskbar.ProgressBarExt
and Microsoft.WindowsAPICodePack.Shell.Taskbar.OverlayIconExt
. They take an additional parameter in the constructor and are bound to a specific window. So you can manipulate progress state and overlays individually for each window.
These additional classes can be found under the following paths inside the downloaded ZIP file:
- \WindowsAPICodePack\Shell\Taskbar\ProgressBarExt.cs
- \WindowsAPICodePack\Shell\Taskbar\OverlayIconExt.cs
Code Examples
Setting progress indicator and overlay icon for the single taskbar button using Code Pack:
using Microsoft.WindowsAPICodePack.Shell.Taskbar;
...
Taskbar.ProgressBar.CurrentValue = 50;
Taskbar.ProgressBar.State = TaskbarButtonProgressState.Error;
Taskbar.OverlayImage=new OverlayImage(new Icon("Star.ico"), "Star");
Setting progress indicators and overlay icons for multiple taskbar buttons using Code Pack extensions: Note: Do not forget to include additional classes Microsoft.WindowsAPICodePack.Shell.Taskbar.ProgressBarExt
and Microsoft.WindowsAPICodePack.Shell.Taskbar.OverlayIconExt
into the Shell
project.
using Microsoft.WindowsAPICodePack.Shell.Taskbar;
...
ProgressBarExt ownProgressBar = new ProgressBarExt(this);
OverlayImageExt overlayImage = new OverlayImageExt(this);
...
ownProgressBar.CurrentValue = 50;
ownProgressBar.State = TaskbarButtonProgressState.Error;
overlayImage.Icon = new Icon("Star.ico");
overlayImage.Text = "Star";
History
- 19th June, 2009: Initial post