查看文章 |
This article explains how to optimize your application for high-DPI modes popularized by Windows Vista. Find out, which problems you would likely encounter during the process and how to solve them. DPI mode in Vista and XPMicrosoft has supported high DPI modes in previous versions of Windows, but until now they were used only seldom. There were good reasons to avoid them, but most of the reasons do not apply anymore in Windows Vista. In Vista, selecting DPI mode is easy, the OS itself is optimized for these modes and delivers a superior user experience. Vista can deal with legacy applications that ignore DPI setting. The advances in computer hardware (LCDs, faster graphics adapters, larger memory chips) made it feasible to create DPI-independent applications and it is only logical that Vista encourages their development. Selecting DPI in Vista
Selecting DPI in XP
DPI-aware and legacy applicationsDepending on the application and on user settings, there are 3 possible ways how would Vista handle an application: DPI aware applicationsIf an application declares itself DPI-aware, Vista will make no attempt to interfere with the application behavior and the application must scale itself properly. Default fonts and GUI elements are using scaled values. Not DPI aware - Vista modeThis mode is the default one when resolution is set to more than 120 DPI. The operating system pretends that the application is running in 96 DPI. All fonts and metrics are using 96 DPI values. When displaying the application window, the graphics is zoomed to fit the actual resolution. As a result, the graphics will not be as sharp as it could be on the current display. Not DPI aware - XP modeThis mode is the default one when resolution is set to 120 DPI or less. Default fonts and GUI elements are using scaled value. If the application ignores the values and uses hardcoded values instead, the user experience will suffer. But since 96 DPI and 120 DPI are not that far away and many legacy applications work correctly in 120 DPI, Microsoft decided to use this mode instead of the Vista mode for not-so-high DPI. Note: it is ultimately the user's decision whether they will use XP or Vista scaling for not DPI-aware apps. Making your application DPI awareDeclaring an application DPI-aware is easy - just call the SetProcessDPIAware API function. But this is only the first step. The real work is to update your application to properly use scaled font and images. The following paragraphs will address the most common issues related to correct scaling. Calling SetProcessDPIAwareThis is a new API in Vista's user32.dll. If you want your applications to be compatible with previous systems, you cannot link to is statically. Instead you may use for example the following code:
SetProcessDPIAware must be called as soon as possible and it may be a problem in MFC application that execute their own code before InitInstance is called. Using manifest to declare DPI awarenessUsing manifests is the preferred way to mark applications DPI aware, because it is simpler and safer. The following manifest fragment demonstrates how to use the dpiAware element.
You may save the above code in a file called for example "DPIaware.manifest", add it to your projects and use the MT.exe tool to merge it with your other manifest fragments. If you are using Visual Studio 2005, go to your application settings, switch to Manifest Tool, then Input and Output and add "$(ProjectDir)DPIaware.manifest" to the Additional Manifest Files field.
DialogsDialogs use "dialog units" instead of pixels to measure size of controls and are therefore DPI independent...to certain level (do not use dialog with custom fonts!). Still, it pays off to test all your dialogs in higher DPI. Expect problems with static text controls (labels). If you are using Visual Studio to design dialog resources, you have probably noticed that it is able to automatically size your labels according to the typed text. Sadly, the minimum size that works in 96 DPI is not good in higher resolution. Sometimes the last word would not fit by a few pixels and will wrap on next (clipped) line resulting in missing words. The solution is to increase the width of all your static controls by ~ 3-4 dialog units (to be on the safe side). Another possible problem related to dialogs is the size of images or icons. You should preferably use higher resolution or at least up-scaled images. Fortunately, the image control can be set to scale your images automatically. Custom controlsIf you are using you own controls, you should scale graphical elements and fonts according to current resolution. Consider for example a control that displays points as tiny filled circles and draws lines. Both the diameter of points and the thickness of lines should scale with resolution. You can detect the current resolution and set you scale level using the following code. (You can cache this value, because resolution switch requires restart.)
Well, in theory, X and Y resolutions can be different, but I doubt this will ever be true for a screen.
Application configurationStore setting related to window size in DPI-independent manner. Consider an application that splits its window into 2 parts (for example Internet Explorer with Favorites pane visible). The width of the pane should be stored in an DPI independent way. Or at the very least, your default value for the pane width should be DPI independent. If you do not take DPI into account, the default configuration will look awkward and you'll probably lose the trust of your users, because of the bad first impression of the application. Menu and toolbarsThe font used in menus and toolbars should not be hardcoded. Use either the system font for menus and toolbars or factor in the scale factor if you are using custom fonts. Images in toolbars (and in menu if you are using them) should be scaled as well. The problem with toolbar and menu images is similar to the one with window caption icons (read below). What size to use and how to avoid quality loss due to scaling? Our solution was to design toolbar and menu graphics in three sizes and pick the closest one based on resolution:
Application iconVista Explorer is keen on high-resolution icons and can rescale them quite nicely. Your application should have its main icon available in 256x256 format. But...that's not the whole story. The small versions of your icon used in start menu or window captions are important too. For optimal look and feel under 96, 120, and 144 DPI consider creating your main icon in these sizes: 16, 20, 22, 24, 26, 32, 48, and 256. Why so many? ...read the following section on window captions. Icon in windows' captionsSize of icons used in window captions must be equal to the value returned by
If you choose the last solution (as did I), you may find this function useful. Given an icon, it creates another icon suitable for use in window caption. The original icon is destroyed (or returned if it already has the correct size or if the original icon has not 32-bit color depth). You can then set caption icons using this code:
The resultThe following screenshot shows an application running in 96, 120 and 144 DPI. Note the scaled toolbar and menu graphics, caption icons and fonts.
SummaryModifying applications for high DPI modes is a time consuming job, but the result is worth the effort. If you plan to make the next version of your software compatible with high DPI modes, be ready to allocate enough resources to testing, graphic design and programming. Resources
|






