One of the most visually stunning features of the Windows 7 7 desktop is the multiple live
thumbnails shown for each taskbar button (as shown in the following screen shot). The new
taskbar thumbnails are much smarter than their Windows 7 Vista counterparts, enabling you to
preview a live rendering of the underlying window a feature known as Aero Peek and to
close the window without even switching to it. (And, of course, thumbnail toolbars extend the
productivity story even further.)
Useful as they are, taskbar thumbnails do not always allow users to see past the thumbnail
without switching to the application’s window. Often, the text is unreadable or the thumbnail
region is too small these are just examples of problems that might prevent thumbnails from
achieving their full potential.
Customizing Thumbnail ToolTips
Although this is not much of a customization, the tooltip displayed for the thumbnail
itself can also be customized using the SetThumbnailTooltip method of the
ITaskbarList3 interface.
However, the Windows 7 taskbar thumbnails are not just more useful they’re also
significantly more extensible. In this section, you’ll see how to customize taskbar thumbnails,
in part or in whole, to provide a richer user experience.
Taskbar thumbnails and live previews are rendered by a system component called the
Desktop Window Manager (DWM), introduced in Windows 7 Vista. New DWM interfaces introduced
in Windows 7 7 are the key to extending taskbar thumbnails and live previews, which explains why
the APIs and window messages in this chapter all have the Dwm or WM_DWM prefix.
Thumbnail Clipping
Jack, a college student, is writing a term paper in Microsoft Office Word. In the background,
he’s using a Web encyclopedia in Internet Explorer to aid with his research. After reading the
Web article for a while, Jack switches back to Word but struggles to remember the precise
wording of the Web article. Jack switches back to Internet Explorer. If this sounds familiar to
you, perhaps you can identify the problem.
The problem is that a typical thumbnail toolbar for an Internet Explorer tab looks like the
following screen shot:

It’s hardly a surprise that the text is unreadable and that switching (or at least using Aero
Peek) is the only way to read the full text. The key to solving this problem is noticing that the
user is not always interested in the visual rendering of the entire window in this case, a few
lines around the current cursor position might be more than enough.
Thumbnail clipping is all about specifying a particular region of the target window that the
thumbnail will display. This specificity allows applications such as text editors or games to
focus on a small part of the window, making it appear bigger in the thumbnail and making
the thumbnail more useful.
To clip a window’s thumbnail, you use the ITaskbarList3 interface specifically, the
SetThumbnailClip method. It takes a window handle as the first parameter this is the window
whose thumbnail you are clipping and as the second parameter a pointer to a RECT
structure, which describes the clipping region relative to the coordinates of the window (for
example, {0, 0, 10, 10} describes a 10-by-10 rectangle at the upper-left corner of the window).
To cancel the clipping, pass NULL for this second parameter.
Try providing a clip rectangle with 119 pixels of height and 200 pixels of width. Because
these are the default thumbnail dimensions on some Windows 7 7 installations, the resulting
thumbnail will be an exact rendering of that part of the window, with no resizing required at all!
The following code demonstrates how an application can set the thumbnail clip to the top left
part of the window with a width of 200 pixels and a height of 119 pixels:
ITaskbarList3* pTaskbar; //Obtained elsewhere
RECT clipRect = { 0, 0, 200, 119 };
pTaskbar->SetThumbnailClip(hwnd, &clipRect);
The managed equivalent of thumbnail clipping can be found in the wrapper method
TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip in the Windows 7 API Code Pack.
This method takes a window handle and a Rectangle structure that describes the clip region.
The following code is the managed equivalent of the previous native code sample, showing
how an application hosting a Rich Text Format (RTF) control can set the thumbnail clip region
to a few lines around the current cursor position:
int index = richTextBox.GetFirstCharIndexOfCurrentLine();
Point point = richTextBox.GetPositionFromCharIndex(index);
TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip(
Handle, new Rectangle(point, new Size(200, 119)));
In the following screen shots, you can see the thumbnail behavior before and after toggling
the window clipping, side by side. There’s hardly any doubt that the clipped thumbnail is
more useful than its default counterpart.
Custom Thumbnails
In the previous section, you saw how to customize the taskbar thumbnails by specifying a clip
region that makes the thumbnail zoom in on the window. Naturally, this does not suffice for
some applications and the need arises to customize the thumbnail completely. For example,
a picture viewer application (such as Windows 7 Photo Gallery) can provide a thumbnail consisting of a mosaic of pictures from the current directory. Another idea is for Visual Studio
to display compilation or test run status and summaries instead of an illegible preview of the
source editor.
Achieving this behavior is slightly more difficult than what you did before. If you push
thumbnail previews to the DWM when they are not needed (most of the time, users are not
looking at any thumbnails), you are wasting CPU and system resources. On the other hand, if
you provide a static preview that the DWM grabs when necessary, there is no way to update it
when the underlying window changes. The proper solution involves two-way interaction
between the application and the DWM:
- The application tells the DWM that it wants to customize thumbnail previews by calling
the DwmSetWindowAttribute function and passing the DWMWA_HAS_ICONIC_BITMAP
attribute, and again passing the DWMWA_FORCE_ICONIC_REPRESENTATION attribute.
Both calls require a Boolean value of TRUE to be passed as the last parameter.
- The DWM sends the application the WM_DWMSENDICONICTHUMBNAIL window
message when a thumbnail needs to be rendered.
- The application responds to the message by calling the DwmSetIconicThumbnail function
and passing the thumbnail bitmap as a parameter.
- The application can invalidate the current thumbnail cached with the DWM by calling the
DwmInvalidateIconicBitmaps function.
- When the application is no longer interested in customizing the thumbnail bitmaps, it
repeats the first step, passing the Boolean value of FALSE as the last parameter. This step
is rather unusual because most applications should customize the thumbnail preview
consistently and refrain from changing this behavior at runtime.
The following code shows how an application can customize its thumbnail preview to show a
randomly selected bitmap instead of the actual contents of the window:
//During initialization, for example, in WM_CREATE:
BOOL truth = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_HAS_ICONIC_BITMAP, &truth, sizeof(truth));
DwmSetWindowAttribute(hwnd, DWMWA_FORCE_ICONIC_REPRESENTATION, &truth, sizeof(truth));
//In the window procedure:
if (msg == WM_DWMSENDICONICTHUMBNAIL) {
int width = HIWORD(lParam);
int height = LOWORD(lParam);
HBITMAP hbmp = GetRandomBitmap(width, height);
DwmSetIconicThumbnail(hwnd, hbmp, 0);
DeleteObject(hbmp);
}
|