Graphics Performance and High DPI
- 5 minutes to read
This article explains how to develop DevExpress-based applications that can be viewed on high DPI devices without loss of quality. For more information about what DPI is and how different Windows versions scale your applications on high resolution displays, refer to the following links.
- DPI and Device-Independent Pixels - an in-depth article that explains DPI concepts.
- Tutorial: Writing High-DPI Win32 Applications - a tutorial by Microsoft that makes you familiar with key concepts of high DPI desktop applications.
- Writing DPI-Aware Desktop and Win32 Applications - a complete Microsoft guide on writing DPI-aware applications.
- DPI Scaling Level for Displays - an article that describes three different ways to change system display DPI settings in Windows 10.
DPI Awareness Mode
The DPI Awareness Mode specifies the way an application is displayed when shown on a high resolution screen.
Unaware. This mode works on all Windows versions prior to Windows Vista. In this mode, applications assume that all displays have the default 96 DPI (100%) scaling. When shown on a High-DPI device, every element of an application is rendered with its original size and then bitmap-stretched to match the screen DPI. This keeps the application layout intact at the cost of quality - blurry images, fuzzy captions, thick separator lines and borders, etc. Any WinForms application you create is initially DPI-unaware.
System. This mode was introduced in Windows Vista. In this mode, applications are rendered according to the DPI of a display, which was the primary display when the user session started. When shown on displays with different DPI values, Windows bitmap-scales such applications. This means that applications remain sharp with one DPI factor only, and become blurry on devices with different DPI factors.
Per-Monitor and Per-Monitor V2. These modes allow applications to dynamically adapt to displays with different DPIs. As a result, an app looks crisp on any display. In Per-Monitor modes, Windows bitmap-scales only images and non-client areas. The rest of the application is rendered by the app itself - as a developer, you need to track system WM_DPICHANGED messages, obtain a current display DPI, and resize\re-align controls depending on this value. First Per-Monitor mode was introduced in Windows 8.1, with the V2 iteration replacing it in Windows 10 Creators Update (build 1703). Microsoft recommends that you always use Per-Monitor V2.
How to Enable DPI Awareness in DevExpress Applications
To make your WinForms DevExpress-based application DPI-aware, open the Project Settings Page and choose the required awareness mode.
Alternatively, call the following methods on application startup:
- WindowsFormsSettings.SetDPIAware() - enables System DPI awareness mode.
- WindowsFormsSettings.SetPerMonitorDpiAware() - enables Per-Monitor V2 DPI awareness mode if an app runs on Windows 1703 or newer. On older Windows versions the application works in System awareness mode.
Do not use application manifest file to enable DPI awareness as it may lead to a number of issues (for example, incompatibility with ClickOnce). Call the
WindowsFormsSettings.ForcePaintApiDiagnostics method to ensure a required DPI awareness mode is activated correctly. See the following section for more information: Troubleshooting.
How to Build HDPI-Ready Applications
Common Recommendation and Settings
Avoid creating and customizing controls in code, opt for Visual Studio's design time.
Visual Studio should run on a standard 96 DPI screen. If you must create your application at resolution greater than 96 DPI, see the following KB article for additional guidance: How to improve the VisualStudio WinForms Designer experience on HighDPI.
Set forms' AutoScaleMode properties to either
Control Sizes and Layout
Since your app needs to resize according to display DPI values, keep the layout flexible. If possible, use LayoutControl, TablePanel and StackPanel containers that auto-adjust the layout of controls when the parent container size changes.
If you prefer raster item icons, use the DPIAwareImageCollection storage: it stores independent image packs for each DPI value, and dynamically switches between them depending on the display.
Many DevExpress controls provide
CustomDraw events that allow you to re-draw control elements. For instance, the CustomDrawFooter demo module illustrates how to redraw the Data Grid footer and cells.
Before the DPI Awareness was supported, these events provided the
e.Graphics property that returned the
System.Drawing.Graphics object. You could call this object's methods to draw custom shapes and text strings.
Now all CustomDraw events provide the
e.Cache property that returns the GraphicsCache object - a DevExpress counterpart for Graphics. GraphicsCache exposes same API as the standard Graphics class, and is optimized for High-DPI and DirectX-rendered applications. You should always use paint methods available from the
Individual Control Settings
BarManagerProperties.ScaleIcons and RibbonProperties.ScaleIcons - two more BarAndDockingController properties. When set to true, Bar and Ribbon icons are automatically increased when on higher DPI values.
To trace all APIs that are not recommended for use with DirectX-rendered and Per-Monitor DPI-aware applications, call the static WindowsFormsSettings.ForcePaintApiDiagnostics method and set the security level as the first parameter:
- Throw - unsupported APIs result in exceptions;
- Trace - unsupported APIs show results in warnings displayed in Visual Studio's "Output" window;
- Disable - ignores unsupported API;
- Default - acts as "Trace" if DirectX and\or Per-Monitor HiDPI support is enabled; otherwise, as "Disable".