Export (0) Print
Expand All
25 out of 32 rated this helpful - Rate this topic

Writing High-DPI Win32 Applications

This practical guide offers you insight into writing DPI-aware Win32 applications. Writing a DPI-aware application is the key to making a UI look consistently good across a wide variety of high-DPI display settings. An application that is not DPI-aware 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 guide explores DPI features and examines high-DPI issues in Windows XP, Windows Vista, and later versions of operating systems. 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.

It contains the following sections:

High-DPI Features in Windows

This section provides an overview of the high-DPI features supported in Windows XP, Windows Vista, and Windows 7. The following table shows a list of features related to high DPI that are supported by each platform.

FeatureWindows XPWindows VistaWindows 7
Control Panel setting of DPIYesYesYes
Custom DPI settingsYesYesYes
DPI virtualizationNoYesYes
API to declare DPI awarenessNoYesYes
APIs to retrieve system metrics and DPIYesYesYes
Reboot/log off to apply changes to DPI settingRebootRebootLog off
Per user DPI settingNoNoYes
DPI auto-configuration out of the boxNoNoYes

 

When you install Windows 7 onto a computer that supports extended display identification data (EDID), Windows 7 automatically configures the computer with an optimal high-DPI setting to make best use of the display’s physical DPI, except in the cases where the display's effective resolution is less than 1024 x 768.

To change the user DPI setting, follow the instructions in the section Setting High DPI in Windows 7.

Setting DPI by Using Control Panel

Windows XP, Windows Vista, and later versions support the ability to change high-DPI display settings. For information about setting high DPI on Windows XP, Windows Vista, and later versions, 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 that are not DPI-aware. Without this feature, the size of the text and UI elements of applications that are not DPI-aware 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 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 percent, 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 screen shot shows the type of visual artifact caused by stretched pixels due to DPI virtualization.

Screen shot showing 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 applications that are not DPI-aware. In some cases, however, virtualization infrastructure can cause significant compatibility problems. If your application has issues on Windows Vista or later versions 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 check box 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 Greg Schechter's blog at High DPI Support in Windows Vista Aero. For more information on compatibility settings for Windows, 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.

Common High-DPI Issues

Applications that do not check the system DPI setting and do 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 effective resolution

In the Assessing DPI Compatibility 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 lower edge by the button.

Screen shot showing the text "Print this page" is clipped off at the lower edge 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 fails 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 because of 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.

Screen shot showing the inconsistent font sizes in the UI of the application.

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 do not. To prevent 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 the screen. Also notice that some of the text wraps despite the fact that there is adequate screen real estate available.

Screen shot showing incorrect layout with clipped UI elements, and some of the text wraps.

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 of them.

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 or later versions, it is typically the result of DPI virtualization. In the following screen shot, the pixels have been stretched, which results in the blurred effect.

Screen shot showing blurred UI elements caused by stretched pixels due to DPI virtualization.

To override the effect of DPI virtualization, enable your application to be DPI-aware. You should follow the guidance in the Assessing DPI Compatibility section to get an understanding of the amount of work needed. In addition, you should follow the testing guidelines in that section 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.

Screen shot showing pixelated text.

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 point size font. Stretched text results in pixelation. To avoid pixelated text, use TrueType or OpenType fonts in your DPI-aware application. Both TrueType and OpenType 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 because of the misalignment of an application's coordinate space when it is remapped to the system's coordinate space during scaling. Touch-enabled applications that are not high DPI–aware may encounter input issues due to the misalignment of an application's coordinate space.

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 that 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 that sometimes occurs is the partial rendering of a full-screen application. In most cases, this side effect is seen in full-screen gaming applications, because they commonly do programmatic screen resolution mode changes. This issue affects only Windows Vista or later applications that do not declare themselves as DPI-aware. The problem is that the application may not be taking into account the fact that some of the system metrics are virtualized. Because full-screen applications such as games are natively resolution-independent, this usually 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 windowed-mode installers and uninstallers, so it is important to do 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 1024 × 768. 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 = Physical Resolution / (DPI/96).

For example, if the user has a display of 1200 x 900 with 144 DPI, the effective resolution is 800 x 600, because 144/96 = 150 percent; this reduces the effective screen real estate by 50 percent. 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 800 x 600 screen resolution. For more information about effective resolution, see Handling Minimum Effective Resolution.

Assessing DPI Compatibility

Assessing DPI compatibility requires the following three steps:

  1. Familiarize yourself with the common high-DPI issues.
  2. Test your application at the recommended high-DPI display settings and resolutions.
  3. 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.

IssueMost common causeSolution to investigate
Clipped UI elements or textUI elements are not resizing based on the GetTextExtent function.

Scaling text

Incorrect font sizeFonts are being created with hard-coded pixel sizes.

Scaling text

Incorrect layoutMain window is not resizing correctly based on DPI.

Scaling layout

Blurred UI elementsApplication is not declared DPI-aware, and DPI virtualization is enabled.

DPI virtualization

Declaring DPI awareness

Pixelated textApplication is using bitmap-based fonts.

Scaling text

Misalignment of coordinate space affecting input Application is not declared DPI-aware, and DPI virtualization is enabled.

DPI virtualization

Declaring DPI awareness

Partial rendering of a full-screen applicationApplication is not declared DPI-aware, and is using a mix of virtualized and non-virtualized metrics.

DPI virtualization

Declaring DPI awareness

Determining the DPI scale factor

Incorrect use of effective resolutionApplication is not declared DPI-aware and is using virtualized system metrics.

DPI virtualization

Declaring DPI awareness

Determining the DPI scale factor

Handling Minimum Effective 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 Windows Vista or later versions as there are DPI-related features on Windows Vista and later versions that are not present on Windows XP.

The following table provides a recommended set of DPI settings and minimum resolutions to consider when testing.

DPI setting on Windows Vista and later versionsMinimum resolutionRecommended resolution
120 (125%)1024 × 768>= 1280 × 960
144 (150%, default settings) 1200 × 900>= 1600 × 1200
144 (150%, DPI virtualization disabled)1200 × 900>= 1600 × 1200
192 (200%, default settings)1600 × 1200>= 2500 × 1600
192 (200%, DPI virtualization disabled)1600 × 1200>= 2500 × 1600

 

Note   Testing at a 192-DPI display setting is optional, but it enables you to determine how "future proof" your application is. For applications developed for Windows Vista and later versions, 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 makes the corresponding fixes easier to code.

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, do the following:

  1. Test your application at high DPI and write down all issues found.
  2. Search the source code for common DPI coding issues.
  3. Do an analysis on the cost of making the application fully DPI-aware.
  4. List all required high-DPI assets, such as toolbars, buttons, and icons.
  5. Fix issues found in step 1 by using the corresponding solution to the issue.
  6. Declare your application DPI-aware.
  7. Verify that all issues have been fixed. If not, repeat the preceding steps.

New Win32 Applications

To make your new application DPI-aware, do the following:

  1. Declare your application DPI-aware.
  2. Familiarize yourself with the coding techniques.
  3. List all required high-DPI assets, such as toolbars, buttons, and icons.
  4. Write your application.
  5. Integrate the new assets from step 3.
  6. Test your application for DPI compatibility.
  7. Verify that all DPI issues have been resolved. If not, repeat the preceding steps.

Addressing High-DPI Issues

There are several techniques you can use to resolve high-DPI issues in your application. These techniques include:

  • Declaring DPI awareness
  • Using system metrics to calculate layout
  • Determining the DPI scale factor
  • Scaling text
  • Scaling graphics
  • Scaling layout
  • Handling minimum effective resolution

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 percent DPI. In Windows XP, DPI awareness has no impact on the application or the operating system, but it has meaning on both Windows Vista and later versions. In Windows Vista and later versions, when DPI virtualization is enabled, applications that are not DPI-aware are scaled, and applications receive virtualized data from the system APIs, such as the GetSystemMetric function.

Note  By default, the DPI virtualization feature is enabled only when the DPI display setting is greater than 120 (125 percent).

Although the Win32 API provides a function declaring an application as DPI-aware, its use is discouraged, except in very specific circumstances. For more information, see the SetProcessDPIAware function. In general, using an application manifest is the recommended process for declaring an application to be DPI-aware.

Using an Application Manifest

To declare your application to be DPI-aware, add <dpiAware> to the application manifest. Here is an example of how to use the <dpiAware> element in an application manifest.


<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>
		

Note   If the <dpiAware> element appears in the assembly manifest of a DLL component, the setting is ignored. Only the assembly manifest for the application can enable DPI awareness.

To merge with the existing assembly manifest for your application, you can use Mt.exe, which is available in the latest Windows SDK, or use Visual Studio.

Merge using Mt.exe

  1. Save the manifest information in the preceding example to a file named DeclareDPIAware.manifest.
  2. Download the latest Windows SDK.
  3. Merge with the existing manifest "DeclareDPIAware.manifest" by running the following commands:
    • mt.exe -inputresource:application_name.exe;#1 -out:extracted.manifest
    • mt.exe -manifest extracted.manifest DeclareDPIAware.manifest -out:merged.manifest
    • mt.exe -outputresource:application_name.exe;#1 -manifest merged.manifest

Merge using Visual Studio

  1. Save the manifest information in the preceding example to a file named DeclareDPIAware.manifest.
  2. Open your application solution. On the Project menu, click Property. The Property Pages dialog box appears.
  3. In the left pane, expand Configuration Properties, expand Manifest Tool, and then click Input and Output.
  4. In the Additional Manifest Files text box, type DeclareDPIAware.manifest, and then click OK, as shown in the following screen shot from Microsoft Visual Studio 2008.

Screen shot showing how to add a DeclareDPIAware.manifest file to your Visual Studio project manifest file.

For more information about the use of manifests, see the MSDN Library topic, Manifest Generation in Visual Studio. For more information about using assembly manifests, see the MSDN Library topic, Manifests [Side-by-Side Assemblies].

Note  You might receive the warning: manifest authoring warning 81010002: Unrecognized Element "application" in namespace "urn chemas-microsoft-com:asm.v3". This is due to a known bug in the manifest compiler and you can safely ignore it.

Note  To avoid the above warning, install Windows 7 SDK or Visual Studio 2010.

After you have added the manifest to your application, you can test your 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 because of DPI virtualization.

SetProcessDPIAware Function

The SetProcessDPIAware function in Windows Vista and later versions sets the current process as DPI-aware. However, the use of the SetProcessDPIAware function is discouraged. For example, if a DLL 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 awareness by using the application's assembly manifest rather than by calling SetProcessDPIAware.

By adding the <dpiAware> element to your application's assembly manifest, you mark your 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 case for requiring the SetProcessDPIAware function is generic hosts that load a DLL and execute from a specified entry point. Three examples of generic hosts are the command-line utility program Rundll32, the DllHost process, and the Microsoft Management Console (MMC).

When a DLL is loaded from a generic host, it is essentially the entry point of the application. Any DLLs implicitly linked to by your DLL will be initialized before the application. Therefore, SetProcessDPIAware should always be called before any initialization to prevent any of those DLLs from caching DPI-sensitive metrics.

However, you should avoid generic hosts whenever possible when writing new code. Instead, you should write a small executable containing the proper manifest entries. Many Control Panel applets in Windows Vista and later versions use this technique.

Getting System Information

The following Win32 API functions are useful for retrieving information about the current display setting:

  • GetDeviceCaps Retrieves device-specific information for the specified device.
  • GetSystemMetrics Retrieves the specified metric or system configuration setting.
  • SystemParametersInfo Retrieves or sets the value of one of the system-wide parameters.

GetDeviceCaps Function

The GetDeviceCaps function enables you to retrieve the number of pixels per logical inch along the screen width and height. In a system with multiple display monitors, this value is the same for all monitors. The following code example shows how to retrieve the horizontal and 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
CDPI g_metrics;

int dpiX = g_metrics.GetDPIX();
int dpiY = g_metrics.GetDPIY();
		

GetSystemMetrics Function

The GetSystemMetrics function enables you to retrieve the specified system metric or system configuration setting. Note that all dimensions retrieved by GetSystemMetrics are in pixels. The following code example shows how to retrieve the horizontal and vertical resolution for the current display setting.



// Retrieve the horizontal and vertical resolution of the current display setting.
int cxScreen = GetSystemMetrics(SM_CXSCREEN);
int cyScreen = GetSystemMetrics(SM_CYSCREEN);
		

The CDPI example class listed in Appendix B (and shown here) offers methods to get the screen dimensions scaled based on DPI (known as relative pixels).



CDPI g_metrics;
int cxScreen = g_metrics.ScaledScreenWidth();
int cyScreen = g_metrics.ScaledScreenHeight();	
		

SystemParametersInfo Function

The SystemParametersInfo function enables you to retrieve or set the value of one of the system-wide parameters. This function can also update the user profile while setting a parameter. The following code example shows how to retrieve the number of lines to scroll when the vertical mouse wheel is moved.



int g_ucScrollLines;

// Retrieves the number of lines to scroll when the vertical mouse wheel is moved.
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &g_ucScrollLines, 0);
		

Determining the DPI Scale Factor

If you define your application as a DPI-aware application, you will need to scale your application appropriately at high-DPI settings. To scale correctly, you must determine the relative DPI scale factor. The DPI scale factor uses 96 DPI as the baseline setting for determining the value. The following code example shows how to determine the DPI scale factor.



int ScaleX(int x) { _Init(); return MulDiv(x, _dpiX, 96); }
int ScaleY(int y) { _Init(); return MulDiv(y, _dpiY, 96); }

// Example using CDPI class.
int cxScaledWidth = g_metrics.ScaleX(100);
	

After you have determined the relative DPI scale factor, you should apply that scale factor when selecting fonts, loading images, and laying out UI elements in your application.

Scaling Text

Scaling text is critical to making your application DPI-aware. To ensure properly scaled text, here are a few recommendations:

  • Do not use the default Windows or DC fonts, because these are bitmap fonts and do not scale well. Instead, use a TrueType or OpenType font.
  • Custom fonts based on pixel size should apply the DPI scale factor.
  • Verify that UI layout and text will scale well at various high-DPI settings.

Note  If you are not sure whether your application uses a TrueType or OpenType font (both with suffix .ttf), look at the font definition file in Control Panel. Right-click the file, and check whether it is a .ttf file.

CreateFont Functions

To create a font, use either the CreateFont, CreateFontIndirect, or CreatFontIndirectEx function. You should apply the DPI scale factor when defining the characteristics of the font. The following example shows how to apply the DPI scale factor to the lfHeight member of the LOGFONT structure when using the CreateFontIndirect function.



// From CDPI: convert a point size (1/72 of an inch) to raw pixels.
int PointsToPixels(int pt) { return MulDiv(pt, _dpiY, 72); }

LOGFONT lf;
lf.lfHeight = -g_metrics.PointsToPixels(12);
// Fill in the rest of the structure.
HFONT hfont = CreateFontIndirect(&lf);
		

GetTextExtent Functions

To determine the pixel dimensions of your scaled text string, use the GetTextExtent family of functions, because the physical pixel size of the font is different depending on the DPI display setting. The following code example shows how to determine the width and height of the specified text string by using the GetTextExtentPoint32 function before drawing a rectangle around the string.



static const TCHAR szString[] = TEXT("TEST");

// Retrieve width and height extents of specified string.
SIZE size;
GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);

// Calculate scaled rect.
RECT rcText;
SetRect(&rcText, 10, 10, 10 + size.cx, 10 + size.cy);
g_metrics.ScaleRect(&rcText);

// Calculate border based on text rect.
RECT rcBorder = rcText;
InflateRect(&rcBorder, g_metrics.ScaleX(4), g_metrics.ScaleY(4));

// Draw rectangle (adjusted for DPI scaling factor) around string.
Rectangle(hdc, rcBorder.left, rcBorder.top, rcBorder.right, rcBorder.bottom);

// Draw string inside rectangle.
TextOut(hdc, rcText.left, rcText.top, szString, lstrlen(szString));
		

Selecting Fonts

The ChooseFont function enables you to display a Fonts dialog box so that a user can choose the attributes of a font. If you use this function, ensure that you specify TrueType or OpenType fonts as part of the Flags member of the CHOOSEFONT structure. The following example shows how to initialize the ChooseFont function so that only TrueType or OpenType fonts are enumerated in the Fonts dialog box.



#include "commdlg.h"

CHOOSEFONT data = { sizeof(data) };
data.hwndOwner = hWnd;
// List only TrueType or OpenType screen fonts in the Fonts dialog box.
data.Flags = CF_TTONLY | CF_SCREENFONTS;
ChooseFont(&data);
		

The Windows User Experience Interaction Guidelines recommend that applications use standard visual styles where possible and that applications use a scalable TrueType or OpenType font instead of a DC font.

The following code example uses the TEXT_BODYTEXT style for the main text. Note that you need to provide alternate rendering code if visual styles are not enabled, that is, if you use the Windows Classic theme.



HTHEME hTheme = OpenThemeData(hWnd, VSCLASS_TEXTSTYLE);
if (hTheme)
{
    DrawThemeText(hTheme, hdc, TEXT_BODYTEXT, 0, szText, -1, DT_SINGLELINE,0,&rcText);
    CloseThemeData(hTheme);
}
else
{
    // Visual styles are not enabled. 
    DrawText(hdc, szText, -1, &rcText, DT_SINGLELINE);
}
		

Scaling Graphics

Applications whose graphics scale poorly are less visually appealing to users. For a better UI experience at high-DPI display settings, consider providing custom scaling for all key graphics content, such as images, bitmaps, icons, and toolbars. Although there are many techniques for scaling graphics in applications, there are two primary techniques that work well for scaling graphics across a range of high-DPI display settings. These two techniques are multiple resolution support and the closest fit technique.

Multiple Resolution Support

The multiple resolution support technique requires that you provide your graphics at multiple resolutions so that you have a version that renders well for each targeted DPI setting, such as 96, 120, 144, and 192. In this case, these values are equivalent to 100 percent, 125 percent, 150 percent, and 200 percent of the baseline DPI setting of 96. At run time, your application's logic first determines the correct DPI scaling factor, and then uses it to determine which resolution of the graphics to use.

Closest Fit

This technique is a refinement of multiple resolution support. In addition to providing multiple versions of graphics that render well at various targeted DPI display settings, it also enables you to target your graphics for any specific custom DPI display setting. The key to this technique is to load the "closest fit" graphic (the one that's slightly larger) among the targeted DPI versions, and then scale the graphic down to the current DPI display setting.

For example, if the current custom DPI setting is 132 and you have provided multiple resolution graphics for 96, 120, and 144 DPI, you would first load the graphic that has slightly greater resolution to the current DPI. In this case, you would first load the 144 DPI version of the graphic. You would then scale it down to render well at 132 DPI. The following example shows how to use the closest fit technique to provide support for any custom DPI display setting.



int destRectHeight = 20;
int destRectWidth = 20; 
int xStart = 40;
int yStart = 85; 
// In this example there are 4 versions of the bitmap: 96, 120, 144, and 192.
// The sizes of these are 20x20, 25x25, 30x30, and 40x40.
// These correspond to 96DPI, 120Dpi, etc.

// Assume there is a global gDPI already set via GetDeviceCaps(hDC, LOGPIXELSX).
// The first thing we do is figure out which source image to load.
int iSourceImageDPIToUse = 96; // We will assume 96 by default.

if (gDPI > 144) 
iSourceImageDPIToUse = 192;
else if (gDPI > 120) 
iSourceImageDPIToUse = 144;
else if (gDPI > 96) 
iSourceImageDPIToUse = 120;

LPCTSTR pBitmapResourceName = NULL;

// Now select the right resource to load.
switch(iSourceImageDPIToUse)
{
    case 120: 
        pBitmapResourceName = MAKEINTRESOURCE(MY_RESOURCE_120DPI);
        break;
    case 144: 
        pBitmapResourceName = MAKEINTRESOURCE(MY_RESOURCE_144DPI);
        break;
    case 192: 
        pBitmapResourceName = MAKEINTRESOURCE(MY_RESOURCE_192DPI);
        break;						
    default: // default to 96 DPI
        pBitmapResourceName = MAKEINTRESOURCE(MY_RESOURCE_96DPI);
        break;
}// Now load the right resource.
HBITMAP hbmImage = (HBITMAP)LoadImage(hinst,
pBitmapResourceName, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
		
// Now set the stretch mode.  Assume hdcDest is the DC handle to the destination.
SetStretchBltMode(hdcDest, HALFTONE);

// It is assumed that hdcTargetWindow is your destination window for the bitmap.
HDC hdcBitmap = CreateCompatibleDC(hDCDest);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBitmap, hbmImage);
		
BITMAP bitmap;
GetObject(hbmImage, sizeof(bitmap), &bitmap);

// StretchBlt the image scaled up or down to match the scaled destination size.
// You may want to adjust x & y if you need to change the layout based on DPI.
// The destRectWidth & destRectHeight are the 96-dpi (default) sizes of the layout.
// NOTE: For better quality use GDI+ or WIC with a high quality scale filter.
	
StretchBlt(hdcDest, g_metrics.ScaleX(xStart), g_metrics.ScaleY(yStart), g_metrics.ScaleX(destRectWidth), g_metrics.ScaleY(destRectHeight), hdcBitmap, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);	

	

// Don't forget to delete the handles when you are finished with them.
SelectObject(hdcBitmap, hbmOld);
DeleteDC(hdcBitmap);
DeleteObject(hbmImage);
		

In the previous example, we use GDI to load the bitmap. If your application currently loads images using GDI+, you should use the SetInterpolationMode function with the interpolationMode parameter set to InterpolationModeHighQualityBicubic. If you are using Windows Imaging Component (WIC) objects, you should set the interpolation mode to WICBitmapInterpolationModeFant.

One of the convenient features of WIC is its native support for DPI -- images can be tagged with DPI attributes, which can be retrieved using the WICBitmapSource::GetResolution method. This enables designers to include multiple DPI versions of the source graphic in the image file. The image file can be retrieved programmatically by specifying the DPI attribute, rather than having to resort to resource-naming conventions.

For more information on GDI, GDI+, and WIC image scaling see:

Icons

Be sure that your icon (.ico) files have an additional 256 x 256 resolution version to make them look attractive 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 Design Concept Guidelines for Icons.

Scaling Layout

Many application windows and dialog boxes are created based on a 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);

   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 Windows Vista.

Screen shot showing the application being displayed at 96 DPI setting. In this case, all UI elements scaled correctly.

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 2 is x number of pixels to the right of Button 1. 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.

Screen shot showing the application being displayed at 144 DPI setting with DPI virtualization disabled. In this case, a number of UI elements fail to scale.

The preceding screen shot shows several UI issues:

  • The window frame is not resized, because the application did not scale to the current DPI setting.
  • The text is scaled correctly, but gets clipped by the unscaled 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 in Windows Vista.

Screen shot showing the application being displayed at 144 DPI setting with DPI virtualization enabled. In this case, the resized text string in the window is clipped, and the text inside the buttons is not scaled properly and is clipped.

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 occurs because in Windows Vista 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 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.

The following screen shot shows the same example again, still running at 144 DPI, but this time with DPI virtualization enabled in Windows 7.

Screen shot showing the application being displayed at 144 DPI setting in Windows 7.

Notice that the overall size of the window has been scaled correctly, and the text is larger. The buttons have been scaled, and the text inside the buttons is scaled properly. This is the result of the extended Win32 API support for DPI virtualization in Windows 7.

Regardless of the different visual results from Windows Vista and Windows 7, you declare an application DPI-aware in the same way.

To make this example truly DPI-aware, you must have the following additional layout support:

  • Specify a scaled size for the window when it is created.
  • Specify a scaled size and layout for the buttons when they are created.
  • Use 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.


	
// These are 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);
   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 <uxtheme.h>
#include <vsstyle.h>
#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
            {
                // 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.

Screen shot showing the application scaled correctly at 144 DPI. In this case, the application declares itself DPI-aware, and uses the scaling helper functions to scale relevant UI elements.

Tip It is useful to test your application initially with DPI virtualization disabled. The easiest way to do 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 800 × 600 or 1024 × 768. At 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 1280 × 1024 has an effective resolution of 1024 × 819. In this case, the effective resolution is 20 percent smaller than the physical resolution.

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, Windows Vista, and later versions is not very complex. With the knowledge of DPI features, high-DPI issues, and an appropriate DPI-assessment strategy, a consistently visually appealing UI can be achieved.

For More Information

Appendix A: Setting High DPI in Windows

The following topics explain how to change DPI settings in Windows XP, Windows Vista, and Windows 7.

Setting High DPI in Windows XP

To change the DPI setting in Windows XP

  1. Right-click the Windows desktop, and then click Properties.
  2. Click the Settings tab, and then click Advanced.
  3. On the General tab, in the DPI settings drop-down list, click Large size (120 DPI).
  4. To see the changes, close all of your programs, and then restart Windows.

Screen shot showing how to change DPI settings in Windows XP.

To set a custom DPI setting in Windows XP

  1. Right-click the Windows desktop, and then click Properties.
  2. Click the Settings tab, and then click Advanced.
  3. On the General tab, in the DPI settings drop-down list, click Custom settings.
  4. 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.
  5. To see the changes, close all of your programs, and then restart Windows.

Screen shot showing how to set a custom DPI setting in Windows XP.

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

  1. On the Start menu, click Control Panel, click Appearance and Personalization, and then click Personalization. The Personalization window appears, as shown in the following screen shot.

    Screen shot showing how to change the DPI setting in Windows Vista.

  2. 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.
  3. In the DPI Scaling dialog box as shown in the following screen shot, do 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.

    Screen shot showing how to change DPI scaling in Windows Vista.

  4. To see the changes, close all of your programs, and then restart Windows.

To set a custom DPI setting in Windows Vista

  1. On the Start menu, click Control Panel, click Appearance and Personalization, and then click Personalization. The Personalization window appears.
  2. 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.
  3. In the DPI Scaling dialog box, click Custom DPI. The Custom DPI Setting dialog box appears, as shown in the following screen shot.

    Screen shot showing how to set a custom DPI setting in Windows Vista.

  4. 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 percent of the default value of 96 DPI is equal to 144 DPI. Notice the check box Use Windows XP Style DPI Scaling. Selecting this check box will disable DPI virtualization.
  5. To see the changes, close all of your programs, and then restart Windows.

Setting High DPI in Windows 7

The following describes how to change the DPI setting and how to customize the DPI setting in Windows 7.

To change the DPI setting in Windows 7

  1. On the Start menu, click Control Panel, click Appearance and Personalization, and then click Display. The Display screen appears, as shown in the following screen shot.

    Screen shot showing how to change the DPI setting in Windows 7.

  2. In the Display screen, do one of the following:

    To increase the size of text and other items on the screen, click Medium - 125% or Larger - 150% to make text more readable, and then click OK.

    To decrease the size of text and other items on the screen, click Smaller - 100% (default) to fit more information, and then click OK.

  3. To see the changes, close all of your programs, and then log off.

To set a custom DPI setting in Windows 7

  1. In the Display screen, click Set Custom text size (DPI). The Custom DPI Setting dialog box appears, as shown in the following screen shot.

    Screen shot showing how to set a custom DPI setting in Windows 7.

  2. In the Scale to this percentage of normal size list, enter the percentage you want, and then click OK. In this case, the percentage value of 150 percent of the default value (96 DPI) is equal to 144 DPI. Notice the check box Use Windows XP Style DPI Scaling. Selecting this check box will disable DPI virtualization.
  3. To see the changes, close all of your programs, log off, and then log on.

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 = 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() { _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); 
    }

    // Convert a point size (1/72 of an inch) to raw pixels.
    int PointsToPixels(int pt) { _Init(); 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;
};


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.

DescriptionHorizontal (pixels)Vertical (pixels)Width (inches)Panel DPI OS DPIScale level
17" WXGA+14409001710096100%
15.4" WXGA+1440 900 15.4 110 96 100%
15.4" WXGA1280 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 120017 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 displayCurrent user settingOptimal settingPixel fidelity gain
1280 x 10241024 x 7681200 x 1000 @ 120 DPI 52%
1600 x 1200 1024 x 768 1600 x 1200 @ 144 DPI 144%
1600 x 1200 1200 x 1000 1600 x 1200 @ 120 DPI 60%

 

 

 

Send comments about this topic to Microsoft

Build date: 10/13/2013

Community Additions

Show:
© 2014 Microsoft. All rights reserved.