4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
...printwindow in windows applications paul hellyarmicrosoft...
来自 : CSDN技术社区 发布时间:2021-03-24

October 25, 2001

Summary: This article develops an augmented AltTab application, TaskSwitcher, as a framework for demonstrating how the new visual styles of Windows XP, and PrintWindow, can be used in Windows applications. (13 printed pages)

Contents

Introduction
TaskSwitcher Application
Intercepting Keyboard Input
Enumerating Top-level Application Windows
Presenting the Top-level Application Windows
Using Comctl32.dll Version 6
Conclusion

Introduction

Microsoft® Windows® XP introduces a new visual style that provides an easy-to-use and richer user interface—for instance, windows with rounded corners, the more tactile appearance of the taskbar, and the UI elements that hot track when the mouse hovers over them.

\"\"

Figure 1. Calculator and the Display Properties dialog box rendered in the new visual style

Windows XP also introduces the new printing API, PrintWindow. This API enables the caller to snapshot a visual copy of a window into a device context.

For an introductory article on visual styles and applying them to an application, see the technical article Using Windows XP Visual Styles in the MSDN Library. Whereas that article offers general, introductory information, the main purpose of this article is to provide a practical example of using the visual style APIs and the PrintWindow API. It will also provide a refresher on using some of the previously existing Win32 APIs.

Specifically, I will develop a TaskSwitcher application, which provides the same functionality as the existing AltTab mechanism in Windows today. In addition to displaying an icon list, however, the application will also show a thumbnail preview of the application that will be switched to. The container window, in which the application icons and preview are displayed, will be rendered using the visual style APIs—allowing the application to match the look and feel of whatever visual style the end user currently has selected.

TaskSwitcher Application

TaskSwitcher is designed to replace the existing AltTab application-switching mechanism of Windows XP. AltTab is the built-in Windows power user functionality allowing end users to quickly switch between their top-level application windows. When the hotkey combination Alt Tab is pressed, Windows generates the list of open windows in which the end user is working. This list of open windows is presented as a group of icons, with one outlined by a selection rectangle. As the end user continues to hold the Alt key and presses the Tab key, the selection rectangle moves to the next icon. The selected icon represents the application that Windows will bring to the foreground once the Alt key is released.

\"\"

Figure 2. Windows XP AltTab container window

Logically, this functionality can be broken down into three components. First, an application must listen for the key combination Alt Tab. Upon receiving that key combination, it enumerates top-level application windows on the desktop. Lastly, it presents those windows in some sort of UI container, allowing the user to select the icon of the application they would like to switch to.

Intercepting Keyboard Input

Using the Win32 API, you can create an application that listens for particular keystrokes by utilizing any one of several methods. The simplest method involves using the API RegisterHotKey. This API takes an hwnd, an ID, a virtual key, and a key modifier. If this call is successful, the hwnd s WndProc will receive a WM_HOTKEY message with the wParam of the message equal to ID whenever the virtual key and key modifier is pressed. This occurs whether the listener application window is active or not. The following call would cause hwndApp to be notified with a WM_HOTKEY message whenever AltTab is pressed:

RegisterHotKey(hwndApp, IDH_ALTTAB, MOD_ALT, VK_TAB)

Before Windows XP, attempting to register AltTab as a hot key would fail. As of Windows XP, not only can you successfully register AltTab as a hotkey, Windows XP will also allow you to handle this event yourself, rather than initiate its own built-in AltTab hotkey handler.

// Create a dummy window that listens for the hotkeyHWND 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 showing, enumerate // the top-level windows, extract their icon and text, // and present them in a container window case IDH_NEXT: // select the icon of the next top-level window // in the window hierarchy break; case IDH_PREV: // select the icon of the previous top-level // window in the window hierarchy

A second more advanced method of implementing a keyboard listener is to use the API SetWindowsHookEx with WH_KEYBOARD_LL. This method creates a low-level keyboard hook layer globally across the current desktop. The LowLevelKeyboardProc callback function specified in the call to SetWindowsHookEx, receives all keyboard input. The LowLevelKeyboardProc should call CallNextHookEx after processing keyboard input, in order to allow the next hook chain (most likely the destination application) to receive the input. Since the LowLevelKeyboardProc receives all keyboard events, it can easily be implemented as a state machine that listens for the combination of Alt and Tab pressed simultaneously. If the application implements its own AltTab mechanism, it would execute the window enumeration algorithm at this point, and return from the LowLevelKeyboardHook without forwarding the last AltTab key event.

hhook SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hinst, 0);LRESULT LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam) static BOOL fShiftPressed FALSE; BOOL fHandled FALSE; if (nCode HC_ACTION) KBDLLHOOKSTRUCT *pkbdllhook (KBDLLHOOKSTRUCT *)lParam; switch (wParam) case WM_SYSKEYDOWN: switch (pkbdllhook- vkCode) case VK_LSHIFT: case VK_RSHIFT: // the user pressed the shift key fShiftPressed TRUE; break; case VK_TAB: if (pkbdllhook- flags LLKHF_ALTDOWN) // the user pressed Alt Tab, execute AltTab hotkey handler fHandled TRUE; break; case VK_ESCAPE: if (pkbdllhook- flags LLKHF_ALTDOWN) // the user pressed Escape, end the AltTab container  // window without switching the selected window fHandled TRUE; break; break; case WM_KEYUP: case WM_SYSKEYUP: switch (pkbdllhook- vkCode) case VK_LMENU: case VK_RMENU: // the user let go of the Alt key, end the AltTab container // window switching to the selected window break; case VK_LSHIFT: case VK_RSHIFT: // the user released the shift key fShiftPressed FALSE; break; break; return (fHandled ? TRUE : CallNextHookEx(hhook, nCode, wParam, lParam));
Enumerating Top-level Application Windows

Enumerating top-level application windows is straight forward using the Win32 API EnumWindows. This is a well-documented API that takes an EnumFunc callback function as a parameter. For each top-level window on the desktop, the EnumFunc will be called back by the system with the window handle of the top-level window as a parameter. Not all top-level windows should appear in the AltTab list. A number of properties of the window are queried, and various conditions must be satisfied: Is the window an application window? Can the window be activated? Is it visible? Is it a ToolWindow?

Upon receiving the AltTab event, TaskSwitcher begins enumerating top-level windows on the desktop using EnumWindows. The system calls back the callback function for each top-level window. Those windows that qualify are added to the list of windows that will be displayed in the AltTab list.

Presenting the Top-level Application Windows

In the UI presentation of the AltTab list, the TaskSwitcher uses a number of the new programmatic features of Windows XP. The selected application s text is rendered using the new API DrawShadowText. Window previews are generated using the new API PrintWindow. Lastly, and perhaps most interesting to application developers, TaskSwitcher uses the new visual style of Windows XP.

Gathering Window Information

After generating the list of windows to be displayed in the AltTab list, various attributes of each window in the list are retrieved and rendered in a preview container. The icon of each window is represented in a list by sending the window a WM_GETICON window message. As the user presses the Tab key to move through the list, the icon and text of the selected application icon in the list are displayed across the top of the preview container. I retrieved each window s caption text by using the API GetWindowText. An interesting point regarding the rendering of the application text is that it uses the new API comctl32 v6 API DrawShadowText. This API, new with Windows XP, takes all the same parameters as the API DrawText, in addition to two COLORREFs indicating the color of the text and the color of the shadow, and an x and y offset for the shadow.

Painting the Window Preview

TaskSwitcher also shows a thumbnail preview of the selected window. (Unless the window you re previewing is minimized, in which case only that window s title bar will be shown.) TaskSwitcher employs some advanced Win32 painting techniques, such as double buffering and halftone scaling, when painting the thumbnail preview. At the heart of obtaining the window preview, however, is the new Windows XP user32 API PrintWindow. PrintWindow takes a window handle, an hdc, and a reserved flag. The API uses window redirection to paint a snapshot of the window into the hdc.

// Takes a snapshot of the window hwnd, stored in the memory device context hdcMemHDC 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);
Using Visual Style APIs to Render the Container

All this is painted on a container window. The container window background is aware of the new visual styles of Windows XP. That is, it has the same look and feel of the rest of Windows XP, including rounded window corners and a tactile pattern background similar to that of the title bars. When rendering the container background, TaskSwitcher uses many of the new theme APIs in uxtheme.h, such as OpenThemeData, CloseThemeData, GetThemeBackgroundRegion, and DrawThemeBackground. In this example, we apply the visual style used at the top of the start panel as the background for the container window.

#include uxtheme.h #include tmschema.h // Dialog proc for the AltTab list container window 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 background region for the part we are going to // paint the container window with and apply it to the // dialog. HRGN hrgn NULL; GetWindowRect(hwnd, rc); OffsetRect( rc, -rc.left, -rc.top); if (SUCCEEDED(GetThemeBackgroundRegion(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) // Visual styles are active, paint using the visual style // APIs RECT rc; GetWindowRect(hwnd, rc); OffsetRect( rc, -rc.left, -rc.top); DrawThemeBackground(htheme, hdc, SPP_USERPANE, 0, rc, NULL); else // Visual styles are not active, paint in the classic windows // style. EndPaint(hwnd, ps); break; case WM_THEMECHANGED: // the visual style has changed, close your existing htheme and try to // open a new one. if (htheme) CloseThemeData(htheme); htheme OpenThemeData(hwnd, L StartPanel  break;

\"\"

Figure 3. TaskSwitcher AltTab container window

Using Comctl32.dll Version 6

Taskswitcher utilizes some of the of the new functionality features found in comctl32.dll version 6. For instance, the icon list is implemented using a ListView control with a background watermark that matches the background of the container, allowing it to blend in seamlessly with the rest of the window. In addition, the API DrawShadowText is found in comctl32 v6.

Comctl32 version 6 is a side-by-side DLL, which means both comctl32.dll versions 5 and 6 are installed on the system at one time. By default, when an application statically links with comctl32.lib, the application will use version 5. In order for an application to utilize version 6, it must provide an application manifest file similar to the following:

 ?xml version 1.0 encoding UTF-8 standalone yes ?  assembly xmlns urn:schemas-microsoft-com:asm.v1 manifestVersion 1.0  assemblyIdentity version 1.0.0.0 processorArchitecture X86 name Microsoft.Shell.TaskSwitch type win32  description TaskSwitch an AltTab alternative. /description  dependency  dependentAssembly  assemblyIdentity type win32 name Microsoft.Windows.Common-Controls version 6.0.0.0 processorArchitecture X86 publicKeyToken 6595b64144ccf1df language *  /dependentAssembly  /dependency  /assembly 

The manifest file is then compiled into the resource section of the application by specifying the following line in the .rc file.

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST TaskSwitch.exe.manifest 
Conclusion

Windows XP delivers a radically redesigned user interface, including a new visual style, and the ability to visually capture windows contents. Using the techniques demonstrated in this article, developers can utilize the visual style APIs to give their application a unique look that yet matches the look and feel of the rest of Windows XP. Using PrintWindow, developers can snapshot a visual copy of a given window into a device context.

 

 

///

要创建声明并使您的应用程序能够使用外观风格 请执行以下步骤

链接到 ComCtl32.lib 并调用 InitCommonControls 请参阅 MSDN Library 中的 Platform SDK 文档 。

将名为 YourApp.exe.manifest 的文件添加到具有以下 XML 格式的源代码树中

?xml version 1.0 encoding UTF-8 standalone yes ?

assembly xmlns urn:schemas-microsoft-com:asm.v1 manifestVersion 1.0

assemblyIdentity

    version 1.0.0.0

    processorArchitecture X86

    name CompanyName.ProductName.YourApp

    type win32

/

description 此处是您的应用程序说明。 /description

dependency

     dependentAssembly

         assemblyIdentity

            type win32

            name Microsoft.Windows.Common-Controls

            version 6.0.0.0

            processorArchitecture X86

            publicKeyToken 6595b64144ccf1df

            language *

        /

     /dependentAssembly

/dependency

/assembly

将声明添加到应用程序的资源文件中 如下所示

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST YourApp.exe.manifest

注意 如果将前一项添加到资源中 则必须在一行中对其进行格式设置。或者 您可以将 XML 声明文件放置在与应用程序的可执行文件相同的目录中。操作系统将首先从文件系统加载声明 然后检查可执行文件的资源部分。文件系统版本优先。

在使用扩展、插件或进程内运行的 DLL 的应用程序中使用 ComCtl32 版本 6

下面是一些使用扩展的应用程序的示例。

Microsoft Management Console (Mmc.exe)

Windows Shell

Microsoft® Visual Studio®

要创建声明并使您的应用程序能够使用外观风格 请执行以下步骤

使用 Windows XP Beta 2 SDK 或更高版本。

包括常用控件标题文件 如下所示

#include commctrl.h

定义编译器变量预处理程序定义 如下所示

#define SIDEBYSIDE_COMMONCONTROLS 1

将名为 YourApp.manifest 文件添加到具有以下 XML 格式的源代码树中

?xml version 1.0 encoding UTF-8 standalone yes ?

assembly xmlns urn:schemas-microsoft-com:asm.v1 manifestVersion 1.0

      assemblyIdentity

    version 1.0.0.0

    processorArchitecture X86

    name CompanyName.ProductName.YourApp

    type win32

/

description 此处是您的应用程序说明。 /description

dependency

     dependentAssembly

         assemblyIdentity

            type win32

            name Microsoft.Windows.Common-Controls

            version 6.0.0.0

            processorArchitecture X86

            publicKeyToken 6595b64144ccf1df

            language *

        /

     /dependentAssembly

/dependency

/assembly

将声明添加到应用程序的资源文件中 如下所示

CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST YourApp.manifest

Winuser.rh 包括以下定义

#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1

#define CONTROL_PANEL_RESOURCE_ID 123

#define RT_MANIFEST 24

本文链接: http://hellyar.immuno-online.com/view-679333.html

发布于 : 2021-03-24 阅读(0)