7 on 7: Taskbar
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:
create a taskbar presence for a specific window within the application, by assigning a unique AppUserModelId to that window (a one-to-many approach).
create a taskbar presence that different executables can share by reusing the same AppUserModelId across those applications (a many-to-one approach).
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;
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):
The TabbedThumbnailBitmapRequested event (line 7) is the workhorse here. This event is a wrapper for responding to two new Window messages:
- WM_DWMSENDICONICTHUMBNAIL: sent when hovering over the taskband icon as a request for the window to provide a bitmap representation in the thumbnail
- WM_DWMSENDICONICLIVEPREVIEWBITMAP: sent when hovering over a thumbnail preview as a request for an image to appear via Aero Peek
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.
Thumbnail Toolbar Buttons
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.
Overlay and Progress indicators
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:
Pinned – these are documents and links the customer wants to always see in the list. Since the ‘user is in charge,’ an application cannot programmatically manipulate this area.
Launch area – this is the bottommost section which always contains three options for running applications or two for pinned applications (where “close” is omitted). The DWM surfaces these items automatically, even for legacy applications. As with the Pinned section, applications cannot modify these options.
Destinations – these are (generally) documents that the application has acted upon (recent or frequent list) or which your application wants to surface to the user. Above you can see that IE shows a Frequent group; Office applications instead show a Recent group. These categories and the documents within them area managed by the Windows Shell. For an application to take advantage of these groups, it merely needs to associate itself with the various file extensions supported by the applications. File associations (such as .docx with Microsoft Word) are typically addressed as part of the installation of the application via registry entries, something that many legacy application are already plugged into.
In addition to the built-in Frequent and Recent options, you can add your own custom categories and documents within them. At the OS level, these entries are IShellItem instances and wrapped via the JumpListItem class in the Windows API Code Pack. To build a custom category, you merely populate a collection of the items you want and apply them to the taskbar instance (via ICustomDestinationList.AppendCategory for unmanaged developers or Jumplist.AddCustomCategories for the managed folks).
Tasks – while destinations are typically documents that the application will act on, tasks are common operations that user carries out from the context of the current application; tasks themselves can launch other applications. There can be only one task list per jumplist, but the mechanism for adding tasks is similar to what you do to add custom destinations. Tasks generally equate to IShellLink instances (JumpListLink in the managed world), and collections of them are added via the AddUserTasks method.
Show Me the Code
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.
The Movie Version
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!