Jim O'Neil
Technology Evangelist
Join App Builder
Keep The Cash! Earn $100 for every app you publish! Let me know how I can help!
One of the more noticeable changes in the Windows 7 experience is the refinement of the taskbar.
Whoa! This looks like lots of reading; is there a movie?
In Windows 7, the taskbar has three distinct areas: the Start menu button, the taskband, and the notification area.
The Start menu has been enhanced to support the notion of most recently (or frequently used) documents and to better surface shutdown options, but overall it has pretty much the same role as it did in Windows Vista.
The notification area has been streamlined, so the most icons you’ll see by default there are just four. Associated with the notification area is an overflow (popup) to store application-specific icons that previously would have cluttered up the area. The idea here is that the user is in charge, so it’s up to them, not the application, to decide which icons to surface directly on taskbar. (Check here for user interface guidelines.)
The most dramatic change is undoubtedly in the taskband itself. Rather than provide an icon for launching an application and additional icons for currently executing applications, Windows 7 combines the notion of application launching and switching. The appearance of the icon indicates the current state of affairs.
For instance, in the snippet below, Windows Explorer is pinned to my taskbar, but there are no open windows for it. The frame around the Outlook icon indicates that indeed Outlook is open. The stacking effect on the IE icon signifies that there are multiple IE windows (or web pages) currently open. The last icon, for Live Writer, is framed indicating a window is open, but beyond that, the highlighting shows it’s the active application as well. Windows 7 will use the predominant color of your application icon to create the highlight effect, so your own icon’s design and color choice significantly affects your users’ experience.
For the most part, Windows 7 and the underlying Desktop Window Manager (DWM) manage the launching and switching experience for you. Items have an affinity for a specific taskband icon based on the Application User Model Id (or AppUserModelId), a string value assigned by the developer. Each application, or windows within the application, as well as jumplist items (introduced later in this article) can be assigned an AppUserModelId, which determines how the application and windows within it are represented on the taskbar.
By default, an AppUserModelId is generated heuristically for legacy applications, so they’ll just do the expected thing, but you have flexibility for instance to:
In your application, you might consider setting an AppUserModelId just in case you want to take advantage of this flexibility later. As you might expect, there’s a new API for that (the not-so-succinct SetCurrentProcessExplicitAppUserModelID).
Presuming you’re using the Windows API Code Pack (and I’ll assume you are for this and other articles in the series), you’ll use code such as the following:
1: String appId = "com.mycompany.PicViewer"; 2: TaskbarManager.Instance.ApplicationId = appId;
1: String appId = "com.mycompany.PicViewer";
2: TaskbarManager.Instance.ApplicationId = appId;
Windows 7 also expands on the notion of preview that debuted in Vista’s Aero feature. An application can expose multiple preview thumbnails, as IE does. When you hover over a thumbnail, the Aero Peek feature takes over, rendering all other windows in the application as transparent so you can immediately find the window of interest, as shown below.
The Desktop Windows Manager (DWM) does a lot of this work for you, but it only knows about ‘top-level’ windows by default. In IE, for instance, each of the thumbnails is not really a separate instance of IE, but rather a tab within the IE window. For tabbed-document interfaces (TDI) and multiple-document interfaces (MDI), you have to programmatically expose the child windows as main windows so that the DWM surfaces them as desired.
To do so, you essentially create an off-screen (or proxy) window for the child window, and let DWM do the rest. At a low level, you’re interacting with the RegisterTab method of the ITaskbarList3 interface. Within managed code and the Windows API Code Pack, you create a new instance of the TabbedThumbnail class. Registering that class with the Taskbar manager (line 19 below) creates the association with the main window and the tab or child window that should have its own preview thumbnail. You can also assign a title and icon to appear in the fly-out (lines 3 and 6):
1: TabbedThumbnail thumbnail = new TabbedThumbnail(this.Handle, childForm.Handle)
2: {
3: Title = System.IO.Path.GetFileName(PathOrUrl),
4: DisplayFrameAroundBitmap = true
5: };
6: thumbnail.SetWindowIcon(childForm.Icon);
7: thumbnail.TabbedThumbnailBitmapRequested += (o, e) =>
8: {
9: try
10: {
11: e.SetImage(new Bitmap(childForm.picImage.Image));
12: e.Handled = true;
13: }
14: catch
15: {
16: e.Handled = false;
17: }
18: };
19: TaskbarManager.Instance.TabbedThumbnail.AddThumbnailPreview(thumbnail);
The TabbedThumbnailBitmapRequested event (line 7) is the workhorse here. This event is a wrapper for responding to two new Window messages:
It’s up to your application to provide the image. In line 11 above, the assumption is that there’s an image control on the childForm that will provide the preview. The preview could, however, be a completely different image or perhaps a clip region of the original image.
Take a look at the enhanced experience provided by Windows Media Player to the left. Notice that the preview is accompanied by VCR-style buttons at the bottom, allowing the user to interact with the application just via the thumbnail.
You can programmatically add your own buttons (up to seven of them) as well; in managed code, it’s via the ThumbnailToolbarButton class (a THUMBBUTTON structure in the unmanaged world). Although you can’t add and remove them dynamically, you can toggle their visible and enabled properties.
Each button has, of course, a Click event and that’s where you can put your application-specific code.
In concert with the overall goal for Windows 7 to not take attention away from your task, as alerts and ‘toast’ in the notification area tend to do, you can surface application state directly on the icon itself.
Via the SetOverlayIcon method (available on the ITaskbarList3 interface and the managed TaskbarManager class) you can provide a 16x16 icon overlay to represent the state of the application: perhaps a connected/disconnected icon to indicate the state of the network connection, for instance.
You can also superimpose a progress bar on the icon, color-coded to the state of the progress (ok, paused, or error). There’s an API to provide the information explicitly (SetProgressValue and SetProgressState), but you get the feature free as well if you are already plugging into the standard progress dialog, as SHFileOperation and IFileOperation do.
The jumplist exposes an application-specific start menu for your application. Internet Explorer 8 takes advantage of this capability by exposing specific features of use to the consumer as you can see to the right.
Each jumplist has four distinct sections:
For an example that brings all of this together, take a look at PicViewer, a very simplistic MDI application I created to demonstrate programming against the Taskbar API for a recent Northeast Roadshow presentation.
PhotoView is a more substantial example that illustrates the user of this and other Windows 7 light-up features. As the “XP to Windows 7 reference app,” it also demonstrates how to retain backward compatibility for XP users while providing an enhanced experience to Windows 7 consumers.
Of course it’s not as good as the book (above), but spend 15 minutes and get the low down on everything in this post, including a peek at real, live code!