Use Windows XP's appearance style and printwindow in Windows applications
Click here to download the sample - Taskswitch.exe.
Paul HellyArmiRosoft Corporation October 25, 2001
Download the sample application of this article from MSDN Downloads (English).
Note: This example is only available for computers running Windows XP. Open the example and open two or more application windows, use the AltTab function to run the Taskswitcher application.
Summary: This article introduces an enhanced AltTab application Taskswitcher, and uses this way to demonstrate the use of Windows XP new appearance and PrintWindow methods in the Windows application.
table of Contents
Introduction Taskswitcher Application Intercept Keyboard Enumeration Top Application Window Show The top-level application window Using ComctL32.dll version 6 summary
Introduction
Microsoft® Windows® XP introduces a new appearance style, which is convenient, and the user interface is also more rich. For example, the Rounded window, the more texture taskbar, and the hovering of the mouse over the UI element, you can realize the thermal tracking of the UI element.
Figure 1: Calculator and Display Properties in the new appearance style dialog
Windows XP also introduces a new printing API: PrintWindow. The API allows the caller to make a snapshot of the window and insert it into the device environment.
For an introduction to the appearance style and the introduction of the application, see the technical article in MSDN Library "using Windows XP appearance style." This article provides related summary and introduction information, and the main purpose of this article is to provide an example of using an appearance-style API and PrintWindow API. This article also provides a refresh program for using some previous WIN32 APIs.
This article will specifically explain the Taskswitcher application, which has the same features as the AltTab mechanisms currently in Windows. In addition to the display of the icon list, the application will also display the thumbnail preview of the application to be switched. The container window that displays the application icon and preview will be displayed through the API, enabling the application's appearance in line with the currently selected appearance style.
Taskswitcher application
Taskswitcher is designed for existing AltTab applications instead of Windows XP. AltTab is a built-in Windows Super User feature that enables end users to quickly switch between the top-level application window. When pressing the hotkey combination Alt Tab, Windows generates a list of open windows that end users are using. The list of opened the window will be displayed in the form of a set of icons, one of the icons with a rectangular selection border. When the end user continues to hold down the Alt key and press the Tab key, the rectangle selection box will move to the next icon. After the Alt key is released, Windows will put the application represented by the selected icon on the front desk.
Figure 2: Windows XP AltTab Container Window
This feature can be logically divided into three parts: First, the application must listen to the combination of Alt Tab; when the combination is received, the application needs to enumerate the top application window on the desktop; Finally, the application needs These windows are displayed in a UI container, allowing users to select the icon for the application to switch to.
Intercept keyboard input
Using the Win32 API, you can create an application that is listening to a particular keystroke through one of several ways. The easiest way is to use API RegisterhotKey. The API contains an HWnd, an ID, a virtual key, and a key combination. If this call is successful, you will receive a WM_HOTKEY message whenever you press the virtual key and a combination key, the WPARAM of the message is equal to ID. This is the case regardless of whether the listening application window is active. Whenever AltTab is pressed, the following calls will receive a WM_HOTKEY message: RegisterhotKey (hwndApp, idh_alttab, mod_alt, vk_tab)
Before Windows XP, you cannot register AltTab as a hotkey. In Windows XP, you can not only register AltTab as a hotkey, but Windows XP also allows you to handle this event without launching its own built-in AltTAB hotkey handler.
// Create a virtual window for listening hot keys
HWND HWNDAPP = CREATEWINDOW (WC_APP, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
NULL, this_exe, null;
IF (hwnd)
{
// Register Alt Tab
RegisterhotKey (hwndApp, IDH_NEXT, MOD_ALT, VK_TAB);
RegisterhotKey (HWndApp, IDH_PREV, MOD_ALT | MOD_SHIFT, VK_TAB);
MSG msg;
While (GetMessage (& MSG, NULL, 0, 0))
{
TranslateMessage (& MSG);
DispatchMessage (& MSG);
}
}
LRESULT WNDPROC (HWND HWND, UINT UMSG, WPARAM WPARAM, LPARAM LPARAM)
{
Switch (UMSG)
{
Case WM_HOTKEY:
{
Switch (WPARAM)
{
// If the container window is not displayed, the enumeration
// top window, extract icons and text,
/ / And display it in the container window
Case IDH_NEXT:
{
// Select in the window hierarchy
// The icon of the next top window
Break;
}
Case IDH_PREV:
{
// Select in the window hierarchy
// Icon on the top window
}
}
}
}
}
The second more advanced method for implementing keyboard listening is to use API SetWindowsHookex (English) and WH_Keyboard_LL. This method creates a low-level keyboard hook layer within the current desktop global range. The specified LowlevelKeyboardProc callback function will receive all keyboard inputs when calling SetWindowsHooKex. After processing the keyboard input, LowlevelKeyboardProc should call CallNextHooKex to enable the next hookchain (which is likely to be a target application) to receive input. Since LowLevelKeyboardProc receives all keyboard events, it can be easily used as a state machine to listen for simultaneous Press ALT and Tab Complete. If the application implements its own AltTab mechanism, the window enumeration algorithm is executed and returned from the LowlevelKeyboardHook without transferring the last AltTab key event to another application.
HHOOK = SETWINDOWSHOKEX (Wh_Keyboard_LL, LowlevelKeyboard, Hinst, 0); LRESULT LowlevelKeyboardProc (int Ncode, WPARAM WPARAM, LPARAM LPARAM)
{
Static bool fshiftpressed = false;
Bool fhand = false;
IF (ncode == hc_action)
{
KBDLLHOOKSTRUCT * PKBDLLHOOK = (KBDLLHOKSTRUCT *) LPARAM;
Switch (WPARAM)
{
Case WM_SYSKEYDOWN:
Switch (pkbdllhook-> vkcode)
{
Case vk_lshift:
Case VK_RSHIFT:
{
// User presses the Shift key
Fshiftpressed = true;
Break;
}
Case VK_TAB:
{
IF (pkbdllhook-> flags & llkhf_altdown)
{
// User Press Alt Tab, execute the AltTAB hotkey handler
FHANDLED = True;
}
Break;
}
Case vk_escape:
{
IF (pkbdllhook-> flags & llkhf_altdown)
{
// Use the ESC button to turn off the AltTab container window
/ / Do not switch to the selected window
FHANDLED = True;
}
Break;
}
}
Break;
Case WM_KEYUP:
Case WM_SYSKEYUP:
Switch (pkbdllhook-> vkcode)
{
Case vk_lmenu:
Case vk_rmenu:
{
/ / The user releases the Alt key, close the AltTab container window
/ / And switch to the selected window
Break;
}
Case vk_lshift:
Case VK_RSHIFT:
{
// Users release shift keys
fshiftpressed = false;
Break;
}
}
Break;
}
}
RETURN (Fhand? True: CallNexthookex (HHOOK, NCODE, WPARAM, LPARAM);
}
Enumeration top application window
Using Win32 API EnumWindows (English) can directly enumerate the top application window. This API accepts the enumfunc callback function as a parameter. For each top window on the desktop, the system will use the top window handle as a parameter to call the enumfunc function. Not all top-level windows should be displayed in the AltTab list. Need some properties of the window and must meet several conditions: Does the window are the application window? Can the window be activated? Does the window visible? Is the window ToolWindow?
After receiving the AltTab event, Taskswitcher starts using the EnumWindows to enumerate the top window on the desktop. The system calls the callback function for each top window. A window that satisfies the condition will be added to the window list and is displayed in the AltTab list.
Show the top application window
In the UI display of the AltTab list, Taskswitcher uses a lot of new programming features for Windows XP. It uses new API DrawShadowText to display the text of the selected application, use the new API PrintWindow to generate window previews. Finally, and perhaps the most interested in application developers, Taskswitcher uses the new appearance style of Windows XP. Collect window information
After generating a list of window you want to display in the AltTab list, you retrieve various properties of each window in the list and display it in the preview container. The icon of each window is displayed in the list by sending a WM_GETICON window message to the window. When the user moves in the list in the list, the icon and text of the selected application icon and text will appear at the top of the preview container. Retrieve the title text of each window by using the API GetWindowText (English). Interestingly, it uses a new API ComctL32 V6 API DrawShadowText (English) to display the application text. The API is a new feature of Windows XP, using all the same parameters of the API DrawText, and two ColorRef parameters indicating text colors and shadow colors, as well as the shadow X offset and Y offset.
Drawing window preview
Taskswitcher can also display thumbnail previews for the selected window. (Unless the preview window is minimized, only the title bar of the window will only display the thumbnail preview, Taskswitcher uses some advanced Win32 drawing techniques, such as double buffer and halftone. However, the core technology for obtaining a window preview is the new Windows XP User32 API PrintWindow. PrintWindow has a window handle, an HDC and a reserved flag. The API uses a window redirection to draw the snapshot of the window into the HDC.
// Make a snapshot of the window hWnd, which is stored in the memory device environment HDCMEM
HDC HDC = GetWindowDC (HWND);
IF (HDC)
{
HDC HDCMEM = CREATECOMPATIBLEDC (HDC);
IF (HDCMEM)
{
Rect RC;
GetWindowRect (hwnd, & rc);
Hbitmap hbitmap = createcompatiblebitmap (HDC, Rectwidth (RC), RectHeight (RC));
IF (HBitmap)
{
SelectObject (HDCMEM, HBitmap);
PrintWindow (HWND, HDCMEM, 0);
DeleteObject (HbitMap);
}
DeleteObject (HDCMEM);
}
ReleaseDC (HWND, HDC);
}
Use an appearance style API to display the container
All of this is drawn on the container window. The background of the container window reflects the new appearance style of Windows XP. That is, it has the same appearance and the remainder of Windows XP, including rounded windows, and a more texture pattern background similar to the title bar. When the container background is displayed, Taskswitcher uses many new topics APIs in UXTHEME.H, such as OpenThemedata (English), ClosetHemedata (English), GetthemeBackgroundRegion (English) and DrawThemebackground. In this example, we use the look of the appearance of the top panel to be used as the background of the container window. #include
#include
// AltTab list container window dialog box
INT_PTR CALLBACK DLGPROC (HWND HWND, UINT UMSG, WPARAM, LPARAM LPARAM)
{
Static htheme htheme = NULL;
Switch (UMSG)
{
Case WM_INITDIALOG:
{
Htheme = OpenThemedata (HWND, L "StartPanel");
IF (htheme)
{
/ / Get the use of the container window
// Background area part and apply it to
// dialog.
HRGN HRGN = NULL;
GetWindowRect (hwnd, & rc);
OffsetRect (& RC, -RC.LEFT, -RC.TOP);
IF (ChengtheMebackGroundRegion (Htheme, NULL,
SPP_USERPANE, 0, & RC, & HRGN)))))
{
SetwindowRGN (HWND, HRGN, FALSE);
}
}
Break;
}
Case WM_Paint:
{
Paintstruct PS;
HDC HDC = BeginPaint (HWND, & PS);
IF (HDC)
{
IF (htheme)
{
// The appearance style is active, use the appearance
// Style API is drawn.
Rect RC;
GetWindowRect (hwnd, & rc);
OffsetRect (& RC, -RC.LEFT, -RC.TOP);
DrawThemebackground (Htheme, HDC, SPP_USERPANE, 0, & RC, NULL);
}
Else
{
// The appearance style is not active, according to the traditional
// Window style draws.
}
}
Endpaint (hwnd, & ps);
Break;
}
Case WM_THEMECHANGED:
{
// The appearance style has been changed, close the existing Htheme and try
// Open a new Htheme.
IF (htheme)
{
ClosetHemedata (htheme);
}
Htheme = OpenThemedata (HWND, L "StartPanel");
Break;
}
}
}
Figure 3: Taskswitcher AltTab Container Window
Use ComctL32.dll version 6
Taskswitcher uses some of the new features in ComctL32.dll version 6. For example, the icon list uses a listView control; the container's background uses a matching background watermark to achieve natural fusion of the rest of the window. In addition, API DrawshadowText is also found in COMCTL32 V6. The ComctL32 version 6 is a parallel DLL, namely COMCTL32.DLL version 5 and version 6 are installed on the system. By default, versions 5 will be used when the application is static links with COMCTL32.LIB. In order to enable the application to use version 6, a following application declaration file must be provided:
XML Version = "1.0" Encoding = "UTF-8" Standalone = "YES"?>
Version = "1.0.0.0" Processrarchitecture = "x86" Name = "Microsoft.Shell.Taskswitch" TYPE = "Win32" /> TYPE = "Win32" Name = "Microsoft.Windows.common-Controls" Version = "6.0.0.0" Processrarchitecture = "x86" PublickeyToken = "6595b64144ccf1df" Language = "*" /> dependentassembly> dependency> askMBLY> Then use the declaration file to the application's resource section by specifying the following line in the .rc file. CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "taskswitch.exe.manifest" to sum up Windows XP provides a new user interface, including new appearance, and ability to visually capture the window content. Using the technique described herein, developers can use the appearance-style API to design a unique appearance that can match the appearance of the Windows XP. With PrintWindow, developers can make a snapshot of the specified window and insert them into the device environment.