Writing DPI Aware Applications _ www.bit.ly/taiho123

35 1.5K 0
Writing DPI Aware Applications _ www.bit.ly/taiho123

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Writing DPI-Aware Win32 Applications Ryan Haveson Ken Sykes Microsoft Corporation September 2008 Applies to: Windows® XP Windows Vista® Summary: Explains how to make your Win32 applications DPI-aware and why you should so This paper shows how to use the high-DPI features in Windows XP and Windows Vista to make your UI more consistent, attractive, and readable It also explains how to identify and fix common DPI issues, and how to use the manifest to declare your application to be DPI Aware Legal Notice The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication This White Paper is for informational purposes only MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT Complying with all applicable copyright laws is the responsibility of the user Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property © 2008 Microsoft Corporation All rights reserved Microsoft, MS-DOS, Windows, Windows NT, Windows Server, Windows Vista, Active Directory, ActiveSync, ActiveX, Direct3D, DirectDraw, DirectInput, DirectMusic, DirectPlay, DirectShow, DirectSound, DirectX, Expression, FrontPage, HighMAT, Internet Explorer, JScript, Microsoft Press, MSN, Outlook, PowerPoint, SideShow, Silverlight, Visual Basic, Visual C++, Visual InterDev, Visual J++, Visual Studio, WebTV, Windows Media, Win32, Win32s, and Zune are either registered trademarks or trademarks of Microsoft Corporation in the U.S.A and/or other countries The names of actual companies and products mentioned herein may be the trademarks of their respective owners Contents Introduction High-DPI Features in Windows Setting DPI by Using Control Panel DPI Virtualization DPI-Related APIs Common High-DPI Issues Clipped UI Elements or Text Incorrect Font Size Incorrect Layout Blurred UI Elements Pixelated Text Drag and Drop and Other Input Issues Partial Rendering of a Full-Screen Application Incorrect Use of Effective Resolution Assessing DPI Compatibility High-DPI Issues Checklist Testing DPI Compatibility Step by Step Guide Existing Win32 Applications New Win32 Applications Addressing High DPI Issues Declaring DPI Awareness Using an Application Manifest SetProcessDPIAware Function 10 Getting System Information 11 GetDeviceCaps Function 11 GetSystemMetrics Function 12 SystemParametersInfo Function 12 Determining the DPI Scale Factor 12 Scaling Text 13 CreateFont Functions 13 GetTextExtent Functions 13 Selecting Fonts 14 Scaling Graphics 15 Multiple Resolution Support 15 Closest Fit 15 Icons 18 Scaling Layout 18 Layout and DPI Virtualization Enabled 20 Handling Minimum Effective Resolution 23 Conclusion 24 For More Information 24 Appendix A: Setting High DPI in Windows 25 Setting High DPI in Windows XP 25 Setting High DPI in Windows Vista 27 Appendix B: DPI Sample Code 30 Appendix C: Optimal DPI Configuration Examples 32 Writing DPI-Aware Win32 Applications Introduction This white paper is a practical guide to adding DPI awareness to existing or new Win32® applications Writing a DPI-aware application is the key to making a user interface (UI) look consistently good across a wide variety of high-DPI display settings An application that is not DPIaware but is running on a high DPI display setting can suffer from many visual artifacts, including incorrect scaling of UI elements, clipped text, and blurry images By adding support in your application for DPI-awareness, you guarantee that the presentation of your application’s UI is more predictable, making it more visually appealing to users Since the introduction of Windows Vista®, users are more frequently following the recommended advice to change DPI settings as a way to enlarge the size of the text and UI elements on high DPI displays As more manufacturers ship greater numbers of high-resolution displays, the default 96 DPI setting can no longer be assumed by applications For a list of optimal DPI configuration examples, see Appendix C To promote the best user experience, developers must ensure that their applications are DPI-aware This paper explores DPI features and examines high-DPI issues in Windows® XP and Windows Vista It also provides a set of guidelines for assessing DPI awareness and some solutions that can help you address DPI-awareness issues in your application This paper contains the following sections:  High-DPI Features in Windows Provides an overview of high-DPI support in Windows XP and Windows Vista  Common High-DPI Issues Provides a list of the key visual artifacts and usability issues that impact applications at high-DPI settings  Assessing DPI Compatibility Provides test matrix and test strategy recommendations for assessing DPI compatibility  Addressing High DPI Issues Provides coding recommendations for resolving issues in your application related to high DPI High-DPI Features in Windows This section provides an overview of the high-DPI features supported in Windows® XP and Windows Vista® The following table shows a list of high-DPI-related features that are supported by each platform Feature Control Panel setting of DPI Windows XP Yes Windows Vista Yes Custom DPI setting Yes Yes DPI virtualization No Yes API to declare DPI awareness No Yes APIs to retrieve system metrics and DPI Yes Yes © 2008 Microsoft Corporation All rights reserved Writing DPI-Aware Win32 Applications Setting DPI by Using Control Panel Windows XP and Windows Vista both support the ability to change high-DPI display settings For information about setting high DPI on Windows XP and Windows Vista, refer to Appendix A: Setting High DPI in Windows When the DPI settings are changed, the system fonts and system UI elements change in size This is the primary reason that applications need to consider the system DPI setting in their rendering and layout code Applications that are not DPI aware can potentially exhibit some visual artifacts such as mismatched font sizes, clipped text, or clipped UI elements DPI Virtualization Windows Vista introduces a feature called DPI virtualization which provides some level of automatic scaling support to applications which are not DPI aware Without this feature, the size of the text and UI elements of DPI unaware applications would typically be smaller on high DPI settings compared to rest of the system, potentially causing usability and readability problems This feature works by providing “virtualized” system metrics and UI elements to the application, as if it were running at 96 DPI The application then renders to a 96-DPI off-screen surface and the Desktop Windows Manager then scales the resulting application window to match the DPI setting For example, if the DPI display setting is 144, DWM scales the application’s window by 150%, or 144/96 The type of scaling that DPI virtualization uses is based on pixel stretching As a result, blurring occurs due to the stretched pixels The following screenshot shows the type of visual artifact caused by stretched pixels due to DPI virtualization The goal of the DPI virtualization feature is to increase the size of the text for non-DPI aware applications In some cases, however, virtualization infrastructure can cause significant compatibility problems If your application has issues on Windows Vista that are caused by DPI virtualization, users can turn DPI virtualization off for your application without affecting other applications To disable DPI virtualization for a single application, right-click the name of the application executable file, click Properties, click the Compatibility tab, and then select the box labeled Disable display scaling on high DPI settings Note Users can disable DPI virtualization on a system-wide basis by selecting the Use Windows XP style DPI scaling checkbox in the Windows Vista Custom DPI Setting dialog box For more information, see Appendix A: Setting High DPI in Windows For more information about DPI virtualization, see the High DPI Support in Windows Vista Aero posting on Greg Schechter's Blog For more information on compatibility settings for Windows Vista, see the Make older programs run in this version of Windows topic in Windows Help and How-to DPI-Related APIs The Win32® API provides functions for enabling DPI awareness in applications To learn how to declare your application to be DPI-aware, see Declaring DPI Awareness To learn how to retrieve system information and metrics related to DPI awareness, see Getting System Information © 2008 Microsoft Corporation All rights reserved Writing DPI-Aware Win32 Applications Common High-DPI Issues Applications that not check the system DPI setting and not adjust for the larger font and UI sizes can raise various classes of issues This section describes the most common categories of issues and shows examples that illustrate them The categories of high DPI issues include:  Clipped UI elements or text  Incorrect font size  Incorrect layout  Blurred UI elements  Pixelated text and bitmaps  Misalignment of coordinate space affecting input  Partial rendering of a full-screen application  Incorrect use of virtual resolution In the Assessing DPI Awareness section, you can find a summary of the high-DPI issues, the potential root cause of each issue, and possible techniques for resolving each issue Clipped UI Elements or Text Applications that are not DPI-aware sometimes exhibit clipped UI elements or text In the following screen shot, notice that the text “Print this page” is clipped off at the bottom by the button This is a result of text being resized while other UI elements containing the text, such as list box items and buttons, are not resized In this case the application has failed to scale the size of the UI layout in proportion to the larger text Here are other scenarios that can result in clipped UI elements or text:  UI elements no longer fit into the application window due to increased sizes of text and controls  The application resizes partially in response to system metrics, but fails to resize completely For example, the application may resize buttons to fit the new text font, but fails to increase the size of the child window that contains the buttons Incorrect Font Size Applications that are not DPI-aware often display incorrect font sizes for text In the following screen shot, notice the inconsistent font sizes in the application’s UI © 2008 Microsoft Corporation All rights reserved Writing DPI-Aware Win32 Applications This type of artifact is typically caused when an application incorrectly creates and uses fonts There are many ways to create and use fonts in Windows applications Some font APIs enable your application’s text to resize dynamically in response to the change in DPI setting, while others not To avoid the inconsistent display of font sizes in your application, ensure that you create and use fonts in a DPI-independent way For more information about creating and using fonts, see the Scaling Text section Incorrect Layout Applications that are not DPI-aware can sometimes exhibit incorrect layout, which can result in a number of visual artifacts, as well as problems interacting with the application In the following screen shot, notice that the UI layout does not scale, which results in clipped UI elements, some of which may appear off screen Also notice that some of the text word-wraps despite the fact that there is adequate screen real estate available Incorrect layout is often caused by miscalculations of system metrics, such as screen size In some cases, system metrics are calculated correctly for certain UI elements, but not all UI elements Another common cause of incorrect layout is running at a low “effective resolution” The term “effective resolution” refers to the resulting resolution which takes into account both the physical resolution and the DPI setting of the display It is very important that you use the correct effective screen resolution when calculating layout For more information about effective resolution, see Handling Minimum Effective Resolution Blurred UI Elements When an entire application appears blurred on Windows Vista®, it is typically the result of DPI virtualization In the following screen shot, the pixels have been stretched, which results in the blurred effect © 2008 Microsoft Corporation All rights reserved Writing DPI-Aware Win32 Applications To override the effect of DPI virtualization, enable your application to be DPI-aware You should follow the guidance in the Assessing DPI Awareness section to get an understanding of the amount of work needed In addition, you should follow the testing guidelines to ensure that your application behaves as expected at the most common DPI configurations Pixelated Text In certain instances, text appears pixelated but the application exhibits no other visual artifacts Pixelated text is most noticeable in the diagonal strokes of characters In the following screen shot, the text “Name” is pixelated, while the text “Advanced Search” is not This type of visual artifact is most likely caused by your application using bitmapped fonts If you scale the text of a bitmapped font, the text is stretched rather than redrawn with a higher pointsize font Stretched text results in pixelation To avoid pixelated text, use TrueType fonts in your DPI-aware application TrueType fonts are vector based, and scale appropriately as larger font sizes in response to changes in DPI display settings For more information about fonts, see the MSDN Library topic, About Fonts For information about Win32® APIs for text and fonts, see the MSDN Library topic, Using the Font and Text Output Functions of GDI Drag and Drop and Other Input Issues One of the subtle side effects of DPI virtualization is that it can cause input issues For example, drag-and-drop operations may no longer work due to the misalignment of an application’s coordinate space when it is remapped to the system’s coordinate space during scaling The root of this problem is that when the Desktop Windows Manager scales the application to a larger size, the resulting transform changes the application’s coordinate space to be different from the rest of the system Translating drag-and-drop coordinates from one coordinate space to another does not work because there is no way of knowing how the application is going to use the offset system coordinates The DPI virtualization feature was introduced to ensure that users had a reasonably good experience with applications which were not DPI-aware However, DPI virtualization is not able to solve all application issues, such as changes in coordinate space Partial Rendering of a Full-Screen Application Another side effect of DPI virtualization which sometimes occurs is the partial rendering of a fullscreen application In most cases, this side effect is seen in full screen gaming applications, because they commonly programmatic screen resolution mode changes This issue affects only Windows Vista applications that not declare themselves as DPI-aware The problem is that the © 2008 Microsoft Corporation All rights reserved Writing DPI-Aware Win32 Applications application may not be taking into account the fact that some of the system metrics are virtualized Since full screen applications like games are natively resolution-independent, in most cases this means they are also natively DPI independent The recommended solution for this class of applications is to declare themselves DPI aware Note that some applications may have windowedmode installers and uninstallers so it is important to an application test pass according to the DPI testing guidelines to ensure that the whole application experience behaves properly at high DPI Incorrect Use of Effective Resolution Applications often require a minimum display resolution to run As an example, suppose an application has a minimum required resolution of 1024x768 At run time, the application may query the system to determine the current screen resolution If the application determines that the screen resolution is less than the required minimum, it prompts the user with a warning Because high DPI settings cause the system to use larger fonts and larger UI elements, it also means that applications take up more pixels when they draw The result is a lower effective resolution because more pixels are required to render the same UI The formula to calculate the effective resolution is: Effective Resolution = Real Resolution / (DPI/96) For example, suppose the user has a display of 1200x900 with 144 DPI, the effective resolution is 800x600, because 144/96 = 150%—this reduces the effective screen real-estate by 50% This means that the size of the UI and text at this setting is roughly the same as if the user were running at 96 DPI with an 800x600 screen resolution For more information about effective resolution, see Handling Minimum Effective Resolution Assessing DPI Compatibility Assessing DPI compatibility requires the following three steps: Familiarize yourself with the common high-DPI issues Test your application at the recommended high-DPI display settings and resolutions Address DPI issues by using the techniques described in the topic Addressing High DPI Issues High-DPI Issues Checklist The following table provides a list of the key DPI issues and their most common causes and solutions Issue Clipped UI elements or text Most common cause UI elements are not resizing based on the GetTextExtent function Solution to investigate Scaling text Incorrect font size Fonts are being created with hardcoded pixel sizes Scaling text Incorrect layout Main window is not resizing correctly based on DPI Scaling layout Blurred UI elements Application is not declared DPIaware, and DPI virtualization is enabled DPI virtualization Declaring DPI awareness Pixelated text Application is using bitmap based fonts Scaling text Misalignment of Application is not declared DPI- DPI virtualization © 2008 Microsoft Corporation All rights reserved Writing DPI-Aware Win32 Applications coordinate space affecting input aware, and DPI virtualization is enabled Declaring DPI awareness Partial rendering of a full-screen application Application is not declared DPIaware, and is using a mix of virtualized and non-virtualized metrics DPI virtualization Declaring DPI awareness Determine DPI scale factor Incorrect use of virtual resolution Application is not declared DPIaware and is using virtualized system metrics DPI virtualization Declaring DPI awareness Determine DPI scale factor Handling minimum resolution Testing DPI Compatibility To assess your application’s DPI compatibility, you should test your application at a variety of resolutions with different high-DPI settings Also, it is recommended that you test on Vista as there are DPI-related features on Vista which are not present on XP The following table provides a recommended set of DPI settings and minimum resolutions to consider when testing DPI setting 120 Minimum resolution 1024x768 Recommended resolution >= 1200x1000 144 (default settings) 1200x900 >= 1600x1200 144 (DPI virtualization disabled) 1200x900 >= 1600x1200 *192 (default settings) 1600x1200 >= 2500x1600 *192 (DPI virtualization disabled) 1600x1200 >= 2500x1600 *Note Testing at a 192 DPI display setting is optional, but it enables you to determine how “future proof” your application is For Windows Vista applications, we recommend that you resolve issues you find at least for configurations up to 144 DPI When you log these issues into your bug tracking system, it is often useful to include the following data points:  Screen shot of the visual artifact  DPI configuration, including whether DPI virtualization is enabled  Screen resolution used to reproduce the issue Having this information available to the developer helps identify the issues and to make the corresponding fixes more easily Step by Step Guide The following sets of steps show how to fix DPI compatibility issues and declare your application to be DPI aware Existing Win32 Applications To make your existing application DPI-aware, the following: © 2008 Microsoft Corporation All rights reserved Writing DPI-Aware Win32 Applications Icons Be sure that your icon (.ico) files have an additional 256x256 resolution version to make them look nice at high DPI settings in list views with large icons For more information on creating ICO files and the suggested sizes and scaling factors at high DPI settings see http://msdn.microsoft.com/en-us/library/aa511280.aspx Scaling Layout Many application windows and dialog boxes are created based on layout from a resource file, which specifies the layout in logical units that are independent of DPI These windows, in general, should require no special effort to make them DPI-aware However, there are scenarios where custom UI elements must be programmatically created and laid out In these cases, it is important to take DPI into account both when selecting the size of the overall window, and when positioning the layout of each UI element in the window In the following example, the application creates a main window and three buttons In the WM_PAINT message handler, the application also draws text to the screen BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { static TCHAR szButton1Text[] = TEXT("Button 1"); static TCHAR szButton2Text[] = TEXT("Button 2"); static TCHAR szButton3Text[] = TEXT("Button 3"); HWND hwndMainWindow; hInst = hInstance; // Store instance handle in our global variable hwndMainWindow = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 420, 200, NULL, NULL, hInstance, NULL); if (!hwndMainWindow) return FALSE; if (!CreateMyButton(10, 55, 60, 26, szButton1Text, hwndMainWindow, hInstance)) return FALSE; if (!CreateMyButton(85, 55, 60, 26, szButton2Text, hwndMainWindow, hInstance)) return FALSE; if (!CreateMyButton(160, 55, 60, 26, szButton3Text, hwndMainWindow, hInstance)) return FALSE; ShowWindow(hwndMainWindow, nCmdShow); UpdateWindow(hwndMainWindow); © 2008 Microsoft Corporation All rights reserved 18 Writing DPI-Aware Win32 Applications return TRUE; } // Helper function to create a button HWND CreateMyButton(int x, int y, int nWidth, int nHeight, LPCTSTR szButtonText, HWND hWndParent, HINSTANCE hInstance) { DWORD dwFlags = WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON; HWND hwndButton = CreateWindow(L"BUTTON",szButtonText, dwFlags, x, y, nWidth, nHeight,hWndParent,NULL, hInstance, NULL); return hwndButton ; } // Now here is a snippet from the WM_PAINT handler case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc,8,8,szText,lstrlen(szText)); EndPaint(hWnd, &ps); break; The following screen shot represents the application in the previous code example being displayed at a DPI display setting of 96 In this example, the application’s UI displays no visual artifacts This is because the layout coordinates are calculated to display correctly at 96 DPI All of the UI elements are constructed using coordinates relative to the upper left corner of the application client area But what happens when an application lays out content relative to other content? For example, Button is x number of pixels to the right of Button When you run this example at a 144 DPI display setting with DPI virtualization disabled (which simulates the application being declared DPI aware), a number of visual artifacts appear, as shown in the following screen shot © 2008 Microsoft Corporation All rights reserved 19 Writing DPI-Aware Win32 Applications The preceding screen shot shows several UI issues:  The window frame is not re-sized, because the application did not scale to the current DPI setting  The text is scaled correctly, but gets clipped by the un-scaled frame  The text on the buttons is scaled correctly, but the button size is not, which causes clipped text Each one of these issues reveals incorrect scaling of the application layout In this case, the overall window size and the padding between controls must be scaled Layout and DPI Virtualization Enabled The following screen shot shows the same example again, still running at 144 DPI, but this time with DPI virtualization enabled Notice that the overall size of the window has been scaled correctly, and the text is larger However, the resized text string in the window is clipped The buttons have been scaled, but the text inside the buttons is not scaled properly and is clipped The clipped text string is due to the fact that the TextOut function is not supported by DPI virtualization and so the text is essentially double scaled In fact, only a portion of the Win32® © 2008 Microsoft Corporation All rights reserved 20 Writing DPI-Aware Win32 Applications APIs support DPI virtualization in Windows Vista This is why relying solely on the DPI virtualization feature to provide high-DPI support for your application is not a solution; it is merely a stopgap To make this example truly DPI-aware requires the following additional layout support:  Specifying a scaled size for the window when it is created  Specifying a scaled size and layout for the buttons when they are created  Using Visual Style APIs to render text and other UI elements based on the system supplied visual styles The following code example shows an update to the previous code example that provides additional scaling of the application’s layout // This is the scaling helper functions described earlier CDPI g_metrics; // This is the modified InitInstance code; changes are in bold type BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { static TCHAR szButton1Text[] = TEXT("Button 1"); static TCHAR szButton2Text[] = TEXT("Button 2"); static TCHAR szButton3Text[] = TEXT("Button 3"); HWND hwndMainWindow; hInst = hInstance; // Store instance handle in our global variable hwndMainWindow = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, g_metrics.ScaleX(420), g_metrics.ScaleY(200), NULL, NULL, hInstance, NULL); if (!hwndMainWindow) return FALSE; if (!CreateMyButton(10, 55, 60, 26, szButton1Text, hwndMainWindow, hInstance)) return FALSE; if (!CreateMyButton(85, 55, 60, 26, szButton2Text, hwndMainWindow, hInstance)) return FALSE; if (!CreateMyButton(160, 55, 60, 26, szButton3Text, hwndMainWindow, hInstance)) return FALSE; ShowWindow(hwndMainWindow, nCmdShow); © 2008 Microsoft Corporation All rights reserved 21 Writing DPI-Aware Win32 Applications UpdateWindow(hwndMainWindow); return TRUE; } HWND CreateMyButton(int x, int y, int nWidth, int nHeight, LPCTSTR szButtonText, HWND hWndParent, HINSTANCE hInstance) { HWND hwndButton = NULL; DWORD dwFlags = WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON; hwndButton = CreateWindow(L"BUTTON",szButtonText,dwFlags, g_metrics.ScaleX(x), g_metrics.ScaleY(y), g_metrics.ScaleX(nWidth), g_metrics.ScaleY(nHeight) ,hWndParent,NULL, hInstance, NULL); return hwndButton ; } #include #include #pragma comment(lib, "uxtheme.lib") … case WM_PAINT: { hdc = BeginPaint(hWnd, &ps); if (hdc) { RECT rcText; GetClientRect(hWnd, &rcText); OffsetRect(&rcText, g_metrics.ScaleX(8), g_metrics.ScaleY(8)); HTHEME hTheme = OpenThemeData(hWnd, VSCLASS_TEXTSTYLE); if (hTheme) { DrawThemeText(hTheme, hdc, TEXT_BODYTEXT, 0, szText, -1, DT_SINGLELINE, 0, &rcText); CloseThemeData(hTheme); } else © 2008 Microsoft Corporation All rights reserved 22 Writing DPI-Aware Win32 Applications { // Visual styles are not enabled DrawText(hdc, szText, -1, &rcText, DT_SINGLELINE); } EndPaint(hWnd, &ps); } } break; Now when we run the application at 144 DPI, we can see that the buttons and the text are displayed correctly based on scaling the layout from the original application values Keep in mind that if you are running with DPI virtualization enabled, and if you have not yet added the manifest entry declaring your application to be DPI-aware, you see a different result because your application will be using virtualized system metrics The following screen shot shows everything displayed correctly Tip It is useful to test your application initially with DPI virtualization disabled The easiest way to this is to either add the tag to the application manifest, or disable DPI virtualization from Control Panel Handling Minimum Effective Resolution Some applications require a specific minimum resolution, such as 800x600 or 1024x768 At a high DPI settings text and UI elements are rendered by using more pixels This has the effect of lowering the screen real estate available to the application Therefore, applications should detect the effective resolution instead of the physical resolution For example, an application that is running at 120 DPI at a physical screen resolution of 1280x1024 has an effective resolution of 1024x819 In this case, the effective resolution is 20% smaller than the physical resolution © 2008 Microsoft Corporation All rights reserved 23 Writing DPI-Aware Win32 Applications When displaying warning or error messages, your application should mention both screen resolution and DPI settings to the user as possible remedies to get more screen real estate The following code example shows how to detect the effective screen resolution at run time CDPI g_metrics; // Make sure the effective resolution is high enough before continuing if (!g_metrics.IsResolutionAtLeast(800, 600)) { if (MessageBox(NULL, L"Effective screen resolution must be at least 800x600 It is recommended that you either increase your screen resolution setting or reduce your DPI scaling setting Continue?", L"Warning", MB_YESNO | MB_ICONWARNING) == IDNO) { return FALSE; } } Conclusion Writing DPI-aware Win32® applications for Windows® XP and Windows Vista® is not that complex With the knowledge of DPI features, high DPI issues, and an appropriate DPI assessment strategy, a consistently visually appealing UI is within your reach For More Information  Creating a DPI-Aware Application (http://go.microsoft.com/fwlink/?LinkId=127736&clcid=0x409)  Pixel Density (http://go.microsoft.com/fwlink/?LinkId=127737&clcid=0x409)  How to Write High-DPI Applications (http://go.microsoft.com/fwlink/?LinkId=127738&clcid=0x409)  DPI-aware applications in Windows Vista (http://go.microsoft.com/fwlink/?LinkId=127739&clcid=0x409)  Windows Vista DPI scaling: my Vista is bigger than your Vista (http://go.microsoft.com/fwlink/?LinkId=127740&clcid=0x409)  What are SYSTEM_FONT and DEFAULT_GUI_FONT?  Windows Vista User Experience Guidelines (http://go.microsoft.com/fwlink/?LinkId=128247&clcid=0x409) (http://go.microsoft.com/fwlink/?LinkId=128246&clcid=0x409) © 2008 Microsoft Corporation All rights reserved 24 Writing DPI-Aware Win32 Applications Appendix A: Setting High DPI in Windows The following topics explain how to change DPI settings in Windows® XP and Windows Vista® Setting High DPI in Windows XP To change the DPI Setting in Windows® XP Right-click the Windows desktop, and then click Properties Click the Settings tab and then click Advanced On the General tab, in the DPI settings drop down list, choose Large size (120 DPI) To see the changes, close all of your programs, and then restart Windows © 2008 Microsoft Corporation All rights reserved 25 Writing DPI-Aware Win32 Applications To set a custom DPI setting in Windows XP Right-click the Windows desktop, and then click Properties Click the Settings tab and then click Advanced On the General tab, in the DPI settings drop down list, choose Custom settings In the Custom DPI Setting dialog box, in the Scale to this percentage of normal size list, enter the percentage you want, and then click OK To see the changes, close all of your programs, and then restart Windows © 2008 Microsoft Corporation All rights reserved 26 Writing DPI-Aware Win32 Applications Setting High DPI in Windows Vista The following describes how to change the DPI setting and how to customize the DPI setting in Windows Vista® To change the DPI setting in Windows Vista On the Start menu, click Control Panel, click Appearance and Personalization, and then click Personalization The Personalization screen appears, as shown in the following screen shot In the left pane, click Adjust font size (DPI) If you are prompted for an administrator password or confirmation, type the password or provide confirmation In the DPI Scaling dialog box as shown in the following screen shot, one of the following:  To increase the size of text and other items on the screen, click Larger scale (120 DPI)– make text more readable, and then click OK  To decrease the size of text and other items on the screen, click Default scale (96 DPI)– fit more information, and then click OK © 2008 Microsoft Corporation All rights reserved 27 Writing DPI-Aware Win32 Applications To see the changes, close all of your programs, and then restart Windows © 2008 Microsoft Corporation All rights reserved 28 Writing DPI-Aware Win32 Applications To set a custom DPI setting in Windows Vista On the Start menu, click Control Panel, click Appearance and Personalization, and then click Personalization The Personalization window appears In the left pane, click Adjust font size (DPI) If you are prompted for an administrator password or confirmation, type the password or provide confirmation In the DPI Scaling dialog box, click Custom DPI…., and the Custom DPI Setting dialog box appears, as shown in the following screen shot In the Scale to this percentage of normal size list, enter the percentage you want, and click OK In this case, the percentage value of 150% of the default value of 96 DPI is equal to 144 DPI Notice the checkbox Use Windows XP Style DPI Scaling Selecting this checkbox will disable DPI virtualization To see the changes, close all of your programs, and then restart Windows © 2008 Microsoft Corporation All rights reserved 29 Writing DPI-Aware Win32 Applications Appendix B: DPI Sample Code The following code example contains a C++ class named CDPI It provides some common high DPI functionalities, such as determining the system DPI setting, scaling logical pixel values to map to physical pixel sizes, and determining the effective screen resolution // Definition: relative pixel = pixel at 96 DPI and scaled based on actual DPI class CDPI { public: CDPI() : _fInitialized(false), _dpiX(96), _dpiY(96) { } // Get screen DPI int GetDPIX() { _Init(); return _dpiX; } int GetDPIY() { _Init(); return _dpiY; } // Convert between raw pixels and relative pixels int ScaleX(int x) { _Init(); return MulDiv(x, _dpiX, 96); } int ScaleY(int y) { _Init(); return MulDiv(y, _dpiY, 96); } int UnscaleX(int x) { _Init(); return MulDiv(x, 96, _dpiX); } int UnscaleY(int y) { _Init(); return MulDiv(y, 96, _dpiY); } // Determine the screen dimensions in relative pixels int ScaledScreenWidth() { return _ScaledSystemMetricX(SM_CXSCREEN); } int ScaledScreenHeight() { return _ScaledSystemMetricY(SM_CYSCREEN); } // Scale rectangle from raw pixels to relative pixels void ScaleRect( inout RECT *pRect) { pRect->left = ScaleX(pRect->left); pRect->right = ScaleX(pRect->right); pRect->top = ScaleY(pRect->top); pRect->bottom = ScaleY(pRect->bottom); } // Determine if screen resolution meets minimum requirements in relative // pixels bool IsResolutionAtLeast(int cxMin, int cyMin) { return (ScaledScreenWidth() >= cxMin) && (ScaledScreenHeight() >= cyMin); } © 2008 Microsoft Corporation All rights reserved 30 Writing DPI-Aware Win32 Applications // Convert a point size (1/72 of an inch) to raw pixels int PointsToPixels(int pt) { return MulDiv(pt, _dpiY, 72); } // Invalidate any cached metrics void Invalidate() { _fInitialized = false; } private: void _Init() { if (!_fInitialized) { HDC hdc = GetDC(NULL); if (hdc) { _dpiX = GetDeviceCaps(hdc, LOGPIXELSX); _dpiY = GetDeviceCaps(hdc, LOGPIXELSY); ReleaseDC(NULL, hdc); } _fInitialized = true; } } int _ScaledSystemMetricX(int nIndex) { _Init(); return MulDiv(GetSystemMetrics(nIndex), 96, _dpiX); } int _ScaledSystemMetricY(int nIndex) { _Init(); return MulDiv(GetSystemMetrics(nIndex), 96, _dpiY); } private: bool _fInitialized; int _dpiX; int _dpiY; }; © 2008 Microsoft Corporation All rights reserved 31 Writing DPI-Aware Win32 Applications Appendix C: Optimal DPI Configuration Examples The following table lists the DPI features for several common displays The panel DPI indicates the native pixel density of the panel, while OS DPI indicates the closest match OS DPI to calibrate the display to a standard setting Description Vertical (pixels) 900 Width (inches) 17 Panel DPI OS DPI 17” WXGA+ Horizontal (pixels) 1440 100 96 Scale level 100% 15.4” WXGA+ 1440 900 15.4 110 96 100% 15.4” WXGA 1280 768 15.4 97 96 100% 14.1” WXGA 1280 768 14.1 106 96 100% 13.3” WXGA 1280 768 13.3 112 96 100% 17” WUXGA 1920 1200 17 133 120 125% 17” WSXGA+ 1680 1050 17 117 120 125% 15.4” WSXGA+ 1680 1050 15.4 129 120 125% 14.1” WXGA+ 1440 900 14.1 120 120 125% 13.3” WXGA+ 1440 900 13.3 127 120 125% 12.1” WXGA+ 1280 768 12.1 123 120 125% 15.4” WUXGA 1920 1200 15.4 147 144 150% The following table shows the pixel fidelity percentage gain that users can get when using correct high DPI settings The configuration in the “Optimal setting” column should enable well behaving applications to render at approximately the same physical size as the configuration in the “Current user setting” column Native resolution of display 1200x1000 Current user setting 1024x768 Optimal setting 1200x1000 @ 120 DPI Increased pixel fidelity gain 52% 1600x1200 1024x768 1600x1200 @ 144 DPI 144% 1600x1200 1200x1000 1600x1200 @ 120 DPI 60% © 2008 Microsoft Corporation All rights reserved 32 [...]... Declaring DPI Awareness When an application declares itself to be DPI- aware, it is a statement specifying that the application behaves well at DPI settings up to 200 DPI In Windows® XP, DPI awareness has no impact on the application or the operating system It is only on Windows Vista® that DPI awareness has meaning In Windows Vista, when DPI virtualization is enabled, applications that are not DPI- aware. .. vertical DPI for the current display setting // From CDPI::_Init() HDC hdc = GetDC(NULL); if (hdc) { _dpiX = GetDeviceCaps(hdc, LOGPIXELSX); _dpiY = GetDeviceCaps(hdc, LOGPIXELSY); ReleaseDC(NULL, hdc); } // Using CDPI example class © 2008 Microsoft Corporation All rights reserved 11 Writing DPI- Aware Win32 Applications CDPI g_metrics; int dpiX = g_metrics.GetDPIX(); int dpiY = g_metrics.GetDPIY();... caches DPI settings during initialization, invoking SetProcessDPIAware in your application might generate a possible race condition For this reason, we recommend that an application enable DPI © 2008 Microsoft Corporation All rights reserved 10 Writing DPI- Aware Win32 Applications awareness by using the application’s assembly manifest rather than by calling SetProcessDPIAware By adding element... application by running it at 144 DPI with DPI virtualization enabled If you have successfully declared your application as DPI- aware, you should not see the blurring of your application UI due to scaling via DPI virtualization SetProcessDPIAware Function The SetProcessDPIAware function in Windows Vista sets the current process as DPI- aware However, the use of the SetProcessDPIAware function is discouraged... application as being DPI aware The user32.dll module, which provides Windows user interface functionality, checks the application’s DPI awareness setting If an application is determined to be DPI aware, the user32.dll module calls SetProcessDPIAware on behalf of the application Note A DLL component should respect the DPI- aware setting of an application and not call SetProcessDPIAware The most common... Microsoft Corporation All rights reserved 8 Writing DPI- Aware Win32 Applications Function In general, using an application manifest is the recommend process for declaring an application to be DPI- aware Using an Application Manifest To declare your application to be DPI- aware, add to the application manifest Here is an example of how to use the element in an application manifest... high DPI functionalities, such as determining the system DPI setting, scaling logical pixel values to map to physical pixel sizes, and determining the effective screen resolution // Definition: relative pixel = 1 pixel at 96 DPI and scaled based on actual DPI class CDPI { public: CDPI() : _fInitialized(false), _dpiX(96), _dpiY(96) { } // Get screen DPI int GetDPIX() { _Init(); return _dpiX; } int GetDPIY()... MulDiv(GetSystemMetrics(nIndex), 96, _dpiX); } int _ScaledSystemMetricY(int nIndex) { _Init(); return MulDiv(GetSystemMetrics(nIndex), 96, _dpiY); } private: bool _fInitialized; int _dpiX; int _dpiY; }; © 2008 Microsoft Corporation All rights reserved 31 Writing DPI- Aware Win32 Applications Appendix C: Optimal DPI Configuration Examples The following table lists the DPI features for several common displays The panel DPI indicates... your DPI scaling setting Continue?", L"Warning", MB_YESNO | MB_ICONWARNING) == IDNO) { return FALSE; } } Conclusion Writing DPI- aware Win32® applications for Windows® XP and Windows Vista® is not that complex With the knowledge of DPI features, high DPI issues, and an appropriate DPI assessment strategy, a consistently visually appealing UI is within your reach For More Information  Creating a DPI- Aware. .. value of 96 DPI is equal to 144 DPI Notice the checkbox Use Windows XP Style DPI Scaling Selecting this checkbox will disable DPI virtualization 5 To see the changes, close all of your programs, and then restart Windows © 2008 Microsoft Corporation All rights reserved 29 Writing DPI- Aware Win32 Applications Appendix B: DPI Sample Code The following code example contains a C++ class named CDPI It provides ... Using CDPI example class © 2008 Microsoft Corporation All rights reserved 11 Writing DPI- Aware Win32 Applications CDPI g_metrics; int dpiX = g_metrics.GetDPIX(); int dpiY = g_metrics.GetDPIY();... on actual DPI class CDPI { public: CDPI() : _fInitialized(false), _dpiX(96), _dpiY(96) { } // Get screen DPI int GetDPIX() { _Init(); return _dpiX; } int GetDPIY() { _Init(); return _dpiY; } //... 32 Writing DPI- Aware Win32 Applications Introduction This white paper is a practical guide to adding DPI awareness to existing or new Win32® applications Writing a DPI- aware application

Ngày đăng: 30/10/2015, 17:53

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan