Tag Archives: desktop apps

How to distribute your existing Desktop Applications via Windows Store to Windows 10 PCs – including the new Windows 10 S configuration


Windows 10 S is a specific configuration of Windows 10 Pro that offers a familiar, productive Windows experience that’s streamlined for security and performance. By exclusively using apps in the Windows Store and ensuring that you browse safely with Microsoft Edge, Windows 10 S keeps you running fast and secure day in and day out. Windows 10 S was inspired by students and teachers and it’s the best Windows ever for schools. It’s also a great choice for any Windows customer looking for consistent performance and advanced security. By limiting apps to those in the Windows Store, Windows 10 S is ideal for people who have everything they need in the Windows Store and prefer the peace of mind that comes with removing the risk of downloading apps from other places.

What do I do with my existing non-Store app? Desktop Bridge is the answer

With the Desktop Bridge you can easily package your current desktop application or game as an .appx, distribute through the Windows Store and target all Windows Desktop devices including Windows 10 S to increase your user reach and easier monetization.

You can package any desktop application such as: WPF, WinForms, MFC, VB6, etc.

Once completed, your users will enjoy from smooth installation and update experiences: Clean, simple and fast install/uninstall updates via differential packages, streaming and many more.

Now you can also modernize your app with the Universal Windows Platform (UWP) to increase user engagement and reach all Windows devices.

We have a lot of customers that already went through the process such as: Kodi, Slack, Evernote, Adobe Photoshop Elements 15 and many others.

Here are few customers that shared their stories:

  1. MusiXmatch is the world’s largest lyrics platform with millions of lyrics available online and more than 50 million users on various platforms
  2. Tale of Wuxia (侠客风云传) is a traditional desktop Win32 role-playing game (RPG) that was created by Heluo Studio
  3. CLIP STUDIO PAINT is the leading paint tool software that supports creation of animation and manga

A quote from Evernote:

“The Desktop Bridge vastly simplifies our [Evernote] installer and uninstaller. It also opens up UWP APIs including Live Tiles and notifications. And having the full-featured Evernote app in the Windows Store means future improvements will reach users faster.”

—Seth Hitchings, VP Engineering, Evernote

What should I do next?

  1. Register as an app developer in the Windows Dev Center
  2. Prepare to package your application
  3. Sign up and get started using the Desktop Bridge
  4. Package your current desktop application as an .appx
  5. Test your Windows app for Windows 10 S, you can also check out this blog post for more details
  6. Submit your app to the Windows Store


Did you find this post helpful? Please let us know in the comments below—and also let us know if there’s anything else you’d like us to dig into for you about this topic.


Improving the high-DPI experience in GDI based Desktop Apps

In recent years, High-DPI displays have become common. Having a lot more pixels to display your application on seems like a simple recipe for crisper graphics but, counterintuitively, the opposite is often the case. Many applications were written without taking the DPI of displays into account and are not able to natively render their contents on High-DPI displays.  The visual elements (e.g., text, images, icons) of these applications will appear blurry.

GDI was for many years the de facto win32 2D API and is behind many of these older pre-high-DPI applications. GDI is used by applications to render graphics and formatted text on displays and printers. Beginning with the Creators Update for Windows, we have added a new feature, called GDI Scaling, that allows GDI to natively scale visual content on behalf of DPI unaware applications. Visual elements, especially text, can appear much sharper for these applications when this feature is enabled. This will give Desktop users and IT Pros a way to improve existing applications that are difficult or unpleasant to use because of blurry text and graphics.

In this article, we will describe the challenge presented by high DPI displays, show you several ways to configure GDI Scaling, discuss how GDI Scaling works and give instructions to developers on updating their apps to run with GDI Scaling. While consumers and IT professionals may find this discussion informative, the primary target for this article are developers wanting to understand how best to make legacy GDI apps look right on high DPI monitors.

Higher DPI, yet Lower Quality

There is a jarring difference between the physical and logical scale of computer displays.  As an example, this is the layout of my displays and high DPI Laptop on my desk.

The displays I use for my desktop work use larger physical screens and are oriented to facilitate the tasks I regularly do. Of the three displays, my laptop has the highest quality display but it’s physically smaller than the other displays. This is in stark contrast to how Windows and the software on my PC see my displays.

You can see here that Windows thinks my laptop display is enormous. And it is. It’s configured to run at a recommended 200% scaling so that my apps don’t appear tiny displaying on all those pixels. This is a common scenario for mixing different DPI displays using a “docked high DPI Laptop.”

The reverse of this scenario occurs as well. Users could be docking laptops that look good at 100% Scaling with a high DPI display on their desk or, using Windows display settings, establish one of their normal DPI displays on their desk as their main display while using the high DPI display on their laptop as a secondary display.

The changes made to Windows to handle evolving DPI have been gradual and were based on the availability of hardware and the needs of software developers starting in Windows XP. Applications built prior to high DPI support from Windows assume that the density of pixels will be fixed at a specific scale. This scale is referred to as “100%” and is around 96 Dots per Inch (DPI). Applications written at 100% DPI simply don’t have enough graphical detail to look good on high DPI displays. Windows assures that each application takes up the right amount of space on the screen regardless of the DPI scale. This ensures that text and controls are roughly the right size regardless of the displays DPI. Because of this, apps that cannot handle different DPI scales will look “pixilated” as Windows stretches the application to take up the right amount of space on the screen.

It would be great if everything could just be updated, but many popular applications were written before there was graphics API support for high DPI screens, and they do not have any native support for handling changes to scale. GDI Scaling is an effort to address this problem by transparently scaling graphics for the app.

How will a GDI Scaled applications look?

GDI Scaling overwrites an application’s awareness of DPI. This can be good, bad or difficult to notice based on the applications original DPI capabilities. To understand the impact of using GDI Scaling, we need to take some time and discuss the different ways that applications can be built to handle display scaling.
Applications use one of the following modes for handling DPI:

  • DPI Unaware – These are apps that are always rendered assuming 100% Scaling (96 DPI). There is no effort made to compensate for the scale by the app itself.
  • System DPI Aware – These are apps that know the DPI of the main display at the time the user logged in to their computer (called the “System DPI”). These apps scale well on the main display but look blurry on a secondary display at a different DPI.
  • Per Monitor DPI Aware – These are apps that are rendering content at different DPIs and can change the DPI scaling on the fly as the applications are moved between monitors with different DPIs. If well made, these apps look good regardless of the monitor DPI.
  • Mixed Mode DPI Aware – These are apps where there may be multiple top level windows, each with its own DPI awareness, that can be shown on different displays. This is just a mix of the 3 DPI awareness listed above, each window will be impacted by GDI scaling as a single window app of the same DPI Awareness. We do not cover this anywhere else in the blog.

You can find out more about DPI Awareness on MSDN.

With GDI Scaling enabled, Text and Graphics are drawn using the GDI API at a much larger scale to take advantage of the High DPI screen. Not everything is improved though: some of the graphics and icons are bitmaps that can’t be rendered by GDI with more detail. Also, some text may be rendered by another Graphics API. That text will not be improved by GDI Scaling.

System DPI Awareness

Apps that are aware of the system DPI will render at the correct scale for a computer’s main display, though these apps will still have issues if they are displayed on a second display that is a different DPI. This is a very common scenario given the increasing availability of high-DPI laptops (like Microsoft’s Surface Book), and their use in business environments docked with larger displays or projectors with lower DPI.

When apps are shown on a display with a higher DPI than the system DPI, they will appear blurry like the DPI unaware apps:

With GDI Scaling enabled, that same app will have graphics and text rendered to the correct scale regardless of which display it is displayed on.

Additionally, there is an interesting limitation with System DPI aware apps. System DPI is set when the user logs into the computer. If a user should change their main display (to one with a different DPI) or change the DPI of their main display, the display will be updated but the system DPI value won’t. These apps will appear blurry or off until the user logs out and back on. GDI Scaling, on the other hand, re-renders the app with each display change and will not have this issue.

In the image above there is a ‘)’ that is “clipped.”  This and other kerning errors can occur with GDI Scaling. GDI Scaling scales up the objects (like text boxes) and fonts displayed in the app by the same ratio. For instance, if GDI Scaling is doubling the DPI of an app and the app was originally rendered with a 10pt font, it will display the scaled app with a 20pt font. In some cases, text doesn’t scale linearly and can be a few pixels off. The actual characters maybe too large to fit in an object that is proportionally scaled.

Per Monitor DPI Awareness

Apps that have been developed to be per monitor DPI aware should have graphics correctly scaled to all your computer’s displays. These should not only look good but they are likely to look better than GDI Scaled apps because static content like bitmaps will be loaded and rendered at the right DPI. This is a close-up detail of the Character Map app (which is per monitor DPI aware) with GDI Scaling turned off. It looks good.

This is a close-up view of the same app run with GDI Scaling turned on:

There are some innocuous differences such as the scale of the key map letters (both images look good though a little different.) You can also see that the check in the checkbox and the carat in the pull down boxes look much worse. That is because these are both static images that are a part of the control and must be scaled.

You can also see an issue with the kerning on a few of the labels. In this case the larger sized font version is not precisely an integer multiple of the smaller sized font. For example, a 20pt font is not exactly twice the size of a 10pt font.

As this example shows, users and IT pros should try to run the app both with and without GDI Scaling to determine which looks best before making a permanent change.

Configuration of GDI Scaling

Each application can be independently configured to run with GDI Scaling. This completely replaces the default scaling of the application. You should test to make sure the app looks improved before deploying these changes.

Configuring a local app to run with enhanced system scaling

The simplest way to enable GDI Scaling for an application is use the application compatibility tab UI.

To do this, you can:

  • Right click on the application icon and click “Properties.”
  • Go over to the Compatibility tab, enable “Override High DPI scaling behavior” and set the Scaling Behavior to “System (Enhanced).”
  • Restart the app and move it between your different displays to see if there is an improvement.

Note: all the examples in this document are created using system applications (like Task Manager and Character Map). System applications do not have a compatibility tab so this setting cannot be adjusted.

Using Group Policy and MDM for configuring apps to run with GDI Scaling

For IT pros with access to policy management tools–such as Microsoft’s System Center Configuration Manager (SCCM) or Intune– applications can be configured to run with GDI Scaling with the “Turn on GdiDPIScaling” and “Turn off GdiDPIScaling” policies.

Enabling GDI Scaling

IT pros can enable GDI Scaling for a list of applications using the “Turn on GdiDPIScaling” policy. Here is a view of the SCCM GP definition of this policy:

You can find documentation for the MDM policy on MSDN at Display/TurnOnGdiDPIScalingForApps.

Disabling GDI Scaling

Because users and app developers can configure apps to run with GDI Scaling on their own (and this may not be the desired configuration) there is also a similar “Turn off GdiDPIScaling” policy. Setting this policy on users or devices will ensure an application will not run with GDI Scaling enabled, regardless of the user or application settings. In all cases, “Turn off GdiDPIScaling” has a higher priority than “Turn on GdiDPIScaling.”

Here is a view of the SCCM GP definition of this policy:

You can find documentation for the MDM policy on MSDN at Display/TurnOffGdiDPIScalingForApps.

Using Application Compatibility Toolkit to configure apps for GDI Scaling

We have also added support for using the Application Compatibility Toolkit (ACT), which manages your apps’ compatibility settings.  The behavior of ACT configuration policies is like the GP solution above:

GdiDPIScaling (same as “Turn on GdiDPIScaling”)

GdiDPIScalingForceDisable (Same as “Turn off GdiDPIScaling”)

You can find out more about using ACT to manage your devices here: https://technet.microsoft.com/en-us/library/dd837648(WS.10).aspx.

GDI Scaling for Developers

GDI apps that are not DPI aware can look bad for users and Enterprises that use high-DPI displays and docked laptops. Beginning with the Creators Update for Windows, GDI apps that were never implemented to be DPI aware can be updated or configured to be per monitor DPI aware, dramatically improving their usability and appearance. Here, we will provide a deep dive to developers wanting to update their apps to take advantage of GDI Scaling and provide some background on how it works.

How does GDI Scaling work?

Historically, GDI does not support scenarios where the apps are shown at anything other than 100% scaling (96 DPI). App developers have had the ability to get System or Display DPI information and update their apps to handle scaling on their own.

When an application is configured to be GDI scaled, a new DPI Scaling step is performed using built-in GDI scaling. Scaling will be done transparently to the application and will result in vector graphics and text content being rendered at higher resolution.

In many cases the DPI Scaling is performed in two steps:

  • Rendering of vector graphics and text at an integral scaling factor (x2, x3, x4, etc.) using GDI.
  • Scaling down of all graphics during Desktop Window Manager (DWM) composition.

When the application is running on a high-DPI display that happens to be multiple of 100% scaling (96 DPI), then no DWM scaling is used. Vector graphics and text will look crisp. Bitmaps and other static resources (icons, toolbars) will be stretched to match the display DPI.

When the application is running on a display that is not a multiple of 100% (96 DPI) then vector graphics and text will be rendered to the first integral multiple of 100% above the display scale factor. For instance, if the application is on a display that is at 225% scale, then vector graphics and bitmaps will be rendered at 300%. DWM will then scale down the rendered content to 225% scale. In this case, the application will have noticeable fuzziness because of the scaling down, but it will look better than just scaling up the 100% rendered content.

Limitations with our GDI Scaling Solution

There is some functionality where we know GDI Scaling is incomplete or non-functional: Device Independent Bitmap (DIB) and Compatible bitmaps.

Device independent Bitmap (DIB)

DIBs are bitmaps that are updated by the application and must be stored at 96 DPI. For the Creators update for Windows, DIBs are not supported by GDI Scaling. When the DIB is copied to the screen, it will be stretched based on the monitor’s DPI.

Compatible bitmaps

Compatible bitmaps are supported by GDI Scaling with a known limitation. When used in multi-monitor configuration, off-screen content will not be updated when the application window is moved between displays with different DPIs. The off-screen content will have the DPI that was most recently used and will stretch to meet the new display DPI. The image’s resolution will not be updated until the window is resized or the window is moved between displays.

Kerning and clipping with imprecisely scaled fonts

As we mentioned above, many fonts are not precisely scaled. For example, 20pt font is not exactly twice the height and width of 10pt fonts. The GDI Scaling is done using the size of the 100% scaled applications. Any difference in scale will impact how the characters look next to each other (too close or too far apart) or how they fit into the objects within the app.

GDI/D3D Interop

Some applications are rendered using both GDI and D3D/D2D (DirectX) APIs. GDI Scaling does not render the D3D/D2D content correctly. Portions of the screen rendered by GDI will look correct while the bits generated by D3D will be drawn at the original unscaled location and size.

Here is an example of an app rendered with D2D/D3D while GDI Scaling is enabled:

Updating your GDI app to use GDI Scaling

If you have a GDI-based app then you can update its manifest to run with GDI Scaling.

In the Creators Update for Windows release, we have added a “gdiScaling” element that, when set to “true,” enables GDI Scaling.

Here’s how the manifest for MMC enables GDI Scaling:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (c) Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"  xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0">
  <description>Microsoft Management Console</description>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2017/WindowsSettings">

Taking advantage of GDI Scaling

Use these recommendations if you want to update a GDI app to ensure the best scaling for high-DPI displays.

  • Use compatible bitmaps instead of DIBs. If your application doesn’t need access bitmap bits directly then compatible bitmaps will produce more scalable results.
  • Do not cache off-screen bitmaps between WM_PAINT calls. Instead recreate those bitmaps each time the app is rendering. Although not optimal, it will ensure that those bitmaps will be properly scaled to match the current hWnd display DPI. Vector graphics and text will be rendered at the proper DPI by the GDI transparently to the application.

Code Sample:

LRESULT WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    switch (uMsg)


    case WM_PAINT:
            PAINTSTRUCT ps;

            // Get a paint DC for current window.
            // Paint DC contains the right scaling to match
            // the monitor DPI where the window is located.
            HDC hdc = BeginPaint(hWnd, &ps);

            RECT rect;
            GetClientRect(hDlg, &rect);

            UINT cx = (rect.right - rect.left);
            UITN cy = (rect.bottom - rect.top);

            // Create a compatible bitmap using paint DC.
            // Compatible bitmap will be properly scaled in size internally and
            // transparently to the app to match current monitor DPI where
            // the window is located.
            HBITMAP memBitmap = CreateCompatibleBitmap(hdc, cx, cy);

            // Create a compatible DC, even without a bitmap selected,
            // compatible DC will inherit the paint DC GDI scaling
            // matching the window monitor DPI.
            HDC memDC = CreateCompatibleDC(hdc);

            // Selecting GDI scaled compatible bitmap in the
            // GDI scaled compatible DC.
            HBTIMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);

            // Setting some properties in the compatible GDI scaled DC.
            SetTextColor(memDC, GetSysColor(COLOR_INFOTEXT));
            SetBkMode(memDC, TRANSPARENT);
            SelectObject(memDC, g_hFont);

            // Drawing content on the compatible GDI scaled DC.
            // If the monitor DPI was 150% or 200%, text internally will
            // be draw at next integral scaling value, in current example
            // 200%.
            DrawText(memDC, ctx.balloonText, -1, &rect,

            // Copying the content back from compatible DC to paint DC.
            // Since both compatible DC and paint DC are GDI scaled,
            // content is copied without any stretching thus preserving
            // the quality of the rendering.
            BitBlt(hdc, 0, 0, cx, cy, memDC, 0, 0);

            // Cleanup.
            SelectObject(memDC, oldBitmap);

            // At this time the content is presented to the screen.
            // DWM (Desktop Window Manager) will scale down if required the
            // content to actual monitor DPI.
            // If the monitor DPI is already an integral one, for example 200%,
            // there would be no DWM down scaling.
            // If the monitor DPI is 150%, DWM will scale down rendered content
            // from 200% to 150%.
            // While not a perfect solution, it's better to scale-down content
            // instead of scaling-up since a lot of the details will be preserved
            // during scale-down.
            // The end result is that with GDI Scaling enabled, the content will
            // look less blurry on screen and in case of monitors with DPI setting
            // set to an integral value (200%, 300%) the vector based and text
            // content will be rendered natively at the monitor DPI looking crisp
            // on screen.

            EndPaint(hWnd, &ps);

To sum up

High DPI displays are a hit but computer users are being blocked from getting the value out of all that extra pixels for older apps. It turns that changing the scale of the display is a pretty big breaking change for older applications. To help, the GDI team at Microsoft has come up with a feature that lets some of these apps compensate for this change with minimum changes–GDI Scaling.

Whether you are configuring apps for your own computer or you are making changes on behalf of your organization, we have provided you with tools to enable and disable this new feature.

For App developers, you will be able to update GDI apps that were never designed for modern high-DPI displays to look better by knowing GDI Scaling’s limitations and following our tips on updating your apps.

High-DPI Scaling Improvements for Desktop Applications in the Windows 10 Creators Update

In the previous blog post about High-dots-per-inch (DPI) scaling improvements, we talk about how desktop applications can be blurry or sized incorrectly when run on high-DPI displays. This is especially noticeable when docking and undocking or when using remoting technologies such as Remote Desktop Protocol (RDP).

In the Windows 10 Anniversary Update we chipped away at this problem by introducing mixed-mode DPI scaling and other high-DPI-related APIs. These APIs made it less expensive for developers to update desktop applications to handle dynamic DPI situations (situations where desktop applications are expected to detect and respond to DPI changes at runtime). We’re still working on improving the high-DPI story for you and in this article we’ll go over some of the improvements coming in the Windows 10 Creators Update. Before we dive into that, here’s a quick recap of the issue:

The image above illustrates the types of issues you’ll see in Windows 10 when using multiple displays with different DPI values. In this case a low-DPI primary (“main”) display docked to a high-DPI external display. In this picture you can see:

  1. Some applications (Word) render blurry on the high-DPI display
  2. Some applications (PowerPoint and Skype for Business) are crisp but render at the wrong size
  3. Desktop icons are sized incorrectly on the high-DPI display
  4. Tooltips are sized incorrectly
  5. The desktop watermark is sized incorrectly

Note that these are just a few of the types of issues and that all the items that are too small in this picture could easily be too large if the display topology was reversed (high-DPI primary and low-DPI external display). Spoiler alert: many (but not all) of these issues have been fixed in the Creators Update.

Developer Improvements in the Creators Update

The high-DPI improvements in the Creators Update fall in two categories:

  • Improvements for desktop application developers
  • Improvements for end users

Let’s talk about the developer-focused improvements first. For Microsoft to be successful in reducing the number of blurry or incorrectly sized desktop applications that end-users see, updating desktop applications to handle dynamic DPI scaling properly needs to be as easy as possible for you. We are approaching this is by incrementally adding automatic per-monitor DPI scaling to desktop UI frameworks. Here are some of the improvements in the Creators Update:

Per-monitor DPI awareness V2

The Anniversary Update introduced the concept of mixed-mode DPI scaling which let you have different DPI-awareness contexts (modes) for each top-level window within a process, and these contexts could be different than the process-wide default. This enabled you to ease in to the world of per-monitor scaling by focusing on the parts of the UI that matter the most while letting Windows handle bitmap stretching other top-level windows. In the Creators Update we added a new awareness context, (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) which we refer to as per-monitor version 2 (PMv2).

PMv2 is technically a DPI_AWARENESS_CONTEXT and not one of the process-wide DPI awareness modes defined in the PROCESS_DPI_AWARENESS enumeration. PMv2 is designed to provide per-monitor scaling functionality that is missing from the original implementation of per-monitor awareness. This context enables the following:

Child window DPI change notifications

When a top-level window or process is running in per-monitor (V1) mode, only the top-level window is notified if the DPI changes. If you want to pass this notification to child windows that have their own window procedures, it’s up to you to pass along this notification. With PMv2 all child HWNDs in an HWND tree are notified in a bottoms-up, then tops-down manner via two new messages:



The WPARAM and LPARAM parameters are unused and zero for both of these messages. They are simply nudges to notify your child HWNDs that a DPI change is occurring and has occurred.

Scaling of non-client area

Prior to the Anniversary Update there was no way to have the Windows-drawn non-client area DPI scale (caption bar, system menus, top-level scroll bars, menu bars, etc.). This meant that if you created a per-monitor application you’d be left with incorrectly sized (too big or too small) non-client area after the DPI change without any recourse other than drawing all that stuff yourself. In the Anniversary Update we added an API that you could call to turn on non-client scaling, EnableNonClientDpiScaling but now with PMv2 you get this automatically.

Automatic DPI scaling for dialogs

Win32 dialogs (dialogs that are created from a dialog template via the CreateDialog* functions) did not DPI scale previous to the Creators Update. With PMv2 these dialogs will automatically DPI scale when the DPI changes. Be aware that Windows will only DPI scale the content that is defined in the dialog template. This means that additional content that is added or manipulated outside of the dialog template will not automatically scale.

Fine-grained control over dialog scaling

There are scenarios where you’ll want control over how Windows DPI scales dialogs or even children HWNDs of a dialog. When you want to opt a dialog or an HWND in a dialog out of automatic DPI scaling you can use SetDialogDpiChangeBehavior/SetDialogControlDpiChangeBehavior, respectively.

    DDC_DEFAULT                     = 0x0000,
    DDC_DISABLE_ALL                 = 0x0001,
    DDC_DISABLE_RESIZE              = 0x0002,

    DCDC_DEFAULT                     = 0x0000,
    DCDC_DISABLE_FONT_UPDATE         = 0x0001,
    DCDC_DISABLE_RELAYOUT            = 0x0002,


NOTE: SetDialogControlDpiChangeBehavior only affects first-level children of a PMv2 dialog. If you have a more complex dialog tree you’ll have to handle the HWND scaling of child windows yourself.

With these APIs you can opt a specific window in a dialog (or the entire dialog itself) out of DPI scaling functionality. When your dialog is DPI scaled by the system a new font is sent to all HWNDs in the dialog. You might, for example, want to opt out of having Windows send a DPI-scaled font to a specific HWND. You could use SetDialogControlDpiChangeBehavior in this case.

Use GetDialogDpiChangeBehavior and GetDialogControlDpiChangeBehavior to query the scaling behaviors applied to a dialog or to specific dialog HWNDs, respectively.

Windows Common Control improvements

When a DPI changed in per-monitor version 1 (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) you could resize and reposition your HWNDs, but if any of these HWNDs were Windows common controls (pushbuttons, checkboxes, etc.) Windows would not redraw the bitmaps (which we refer to as “theme drawn parts” or “theme parts” because they’re drawn by UXTheme) for these buttons. This meant that the bitmaps were either too large or too small, depending on your display topology. There wasn’t really anything that you could do about this, short of drawing the bitmaps yourself.

PMv2 helps draw these bitmaps at the correct DPI. Below we’re showing how the bitmaps in common controls in per-monitor version 1 wouldn’t DPI scale properly and how they do DPI scale if they’re in a PMv2 context:

Common Control theme parts rendering larger than expected when the window was moved from a high-DPI display (200% scaling) to a low-DPI display (100% scaling)
Common control theme parts rendering at the correct size after the window was moved from a high-DPI display (200% scaling) to a low-DPI display (100% scaling)

Specifying DPI awareness fallback behavior

It is recommended that you specify the DPI awareness of your process in the application manifest. In the Anniversary Update we introduced a new DPI awareness tag, <dpiAwareness>. With this tag you can specify a fallback behavior for the process-wide default DPI awareness mode or context. This is useful in that you can specify different DPI awareness modes for when your application is run on different version of Windows. For example, the following manifest settings:

&lt;dipAwareness&gt;PerMonitorV2, PerMonitor&lt;/dpiAwareness&gt;

This will result in the following process-wide default on different versions of Windows:

Windows Version Applied process-wide DPI awareness mode default Default DPI awareness context for new windows
Vista System N/A
Windows 7 System N/A
Windows 8 System N/A
Windows 8.1 Per Monitor V1 N/A
Windows 10 (1507) Per Monitor V1 N/A
November Update (1511) Per Monitor V1 N/A
Anniversary Update (1607) Per Monitor V1 Per Monitor V1
Creators Update (1703) Per Monitor V1 Per Monitor V2

Programmatically setting the process-wide default context

SetProcessDpiAwarenessContext(…) lets you specify the default DPI awareness context for your process programmatically. SetProcessDpiAwareness wouldn’t accept a DPI awareness context so there was no way to specify PMv2 as your process-wide default awareness context programmatically.

End-user DPI-scaling improvements

In addition to the work that we’re doing to make it easier for you, as a developer, to update your desktop applications to be per-monitor DPI aware, we’re also working to make your life as a Windows user better where it comes to using Windows in mixed-DPI environments. Here are some of the improvements that are part of the Creators Update:

DPI-scaling overrides

There are times when a Windows desktop application is defined to run in a certain DPI-awareness mode, such as System DPI awareness, but for various reasons you’d need it to run in a different mode. One scenario for this is when you’re running desktop applications that don’t render well on a high-DPI display (this can happen if the developer hasn’t tested and fixed up their applications for the DPI scale factors seen on the latest hardware). In situations like this you might want to force the application to run as a DPI-unaware process. Although this would result in the application being blurry it would at least be sized correctly. There are situations where this can make an unusable application usable, albeit blurry. You can enable this functionality in the .exe properties:

There are three settings that you can specify:

Setting Effect
Application This forces the process to run in per-monitor DPI awareness mode. This setting was previously referred to as “Disable display scaling on high-DPI settings.”

This setting effectively tells Windows not to bitmap stretch UI from the exe in question when the DPI changes

System This is Windows’ standard way of handling system-DPI aware processes. Windows will bitmap stretch the UI when the DPI changes
System (Enhanced) GDI Scaling (see below)

“System (enhanced)” DPI scaling

While we want to make it as easy as possible for you to update your applications to handle DPI scaling properly, we fully recognize that there are many applications that can never be updated, for various reasons. For this class of applications, we’re looking at ways that Windows can do a better job of automatically DPI scaling. In the Creators Update you’ll see the first version of this work.

There is new functionality in the Creators Update that results in text and primitives rendering crisply on high-DPI displays for GDI-based apps only. For applications that are GDI-based Windows can now DPI scale these on a per-monitor basis. This means that these applications will, magically, become per-monitor DPI aware. Now keep in mind that this solution is not a silver bullet. There are some limitations:

  • GDI+ content doesn’t DPI scale
  • DX content doesn’t DPI scale
  • Bitmap-based content won’t be crisp
  • It won’t be possible for end users to determine which apps will benefit from this feature without trying it out on an app-by-app basis.

Even with all of these limitations, when this GDI scaling works it’s quite impressive. So much so that we’ve turned it on by default for some in-box apps. The Microsoft Management Console (mmc.exe) will be GDI scaled, by default, in the Creators Update. This means that many in-box Windows snap ins, such as Device Manager, will benefit from this feature in the Creators Update. Here are some screenshots:

A DPI-unaware application running on a Surface Book High-DPI display (200% DPI scaling) The same application being GDI scaled (“System (Enhanced)” DPI scaling)

Notice how the text is crisp in the GDI-scaled version of the application (on the right) although the bitmaps are blurry (because they’re being bitmap stretched from a low-DPI to high)

What’s more, this functionality can be turned on for non-Windows application in the exe properties via the “System (Enhanced)” compatibility setting under “Override high-DPI scaling behavior. Scaling performed by:” (under the compatibility tab of the properties for an exe. See the screenshot earlier in this post). Note that this option isn’t available for Microsoft applications that ship in-box with Windows.

Internet Explorer

Per-Monitor DPI awareness support was first introduced in Windows 8.1 but many in-box Windows applications did not properly adopt this DPI scaling model. One of the most notable offenders was Internet Explorer. In the Creators Update IE has been updated to dynamically DPI scale.

Before the Creators Update, if you moved Internet Explorer to a display with a different DPI or otherwise changed the DPI of the display that it was on (docking/undocking/settings change/RDP/etc.) the content of the web page you were viewing would DPI scale but the app frame would not. In the image below we’re showing Internet Explorer and Edge, side by side, while being run on a secondary display with 100% display scaling. In this scenario, the primary display was using a high-DPI scale factor and then the app windows were moved to the low-DPI secondary display. You’ll see that the Edge UI scaled down but the Internet Explorer frame still rendered at the scale factor of the primary display.


  • The text in the navigation bar is huge
  • The navigation buttons are huge
  • The vertical scroll bar is huge
  • The minimize/maximize/close buttons are rendered at the correct size but are spaced out as if they were on the high-DPI display

Here is how things look in the Creators Update:

Desktop icons

One of the biggest complaints we’ve heard (and experienced ourselves) was that the desktop icons would not DPI scale if you were running in “extend” display mode with multiple displays containing different DPI/display scaling values. Updates in the Creators Update fix this issue. Here is what you’d see before the Creators Update:

And here is what you’ll see in the Creators Update:

Office sizing issues

Although this isn’t specifically tied to the Creators Update, Office 2016 with the latest updates no longer has issues with Skype for Business and PowerPoint being sized incorrectly in mixed-DPI configurations.

What we didn’t get to

Hopefully you’ll enjoy these improvements, both as a developer and as an end user. While we’ve done a ton of work and are hopefully moving the needle, so to speak, on how Windows handles dynamic DPI support there is still a lot of work ahead of us. Here are a few things that we still need to work on:

High-DPI developer documentation

As of writing this blog, the high-DPI documentation available on MSDN is horribly outdated. The guides for writing per-monitor DPI aware applications were written in the Windows 8.1 timeframe and haven’t seen any significant updates since then. Also, many Windows API have DPI sensitivities that are not documented. That is to say that some Windows API will behave differently if they’re being called from a system-DPI-aware context vs. a per-monitor DPI aware context. All of this will need to be cleaned up and well documented so that you’re not left guessing when trying to update your application. We’re working on it, so keep an eye out for some improvements here.

“Magic numbers”

There are things in Windows that when scaling to higher DPI, don’t get it quite right. The reason for this is lurking “magic numbers” in the code that assumes that the world is always running at 96 DPI. While, in the past, some of these “magic numbers” didn’t result in significant problems, as DPI increases these issues become more and more noticeable. We’ll need to scrub Windows for as many of these as we can find. A couple of places that you can see “magic numbers” in use are 1) the width of a Windows button border and 2) the padding in non-client menu bars (such as can be seen in Notepad). In the case of the menu bar, as you run Notepad on higher and higher DPI values, the space between each menu item decreases.

Child-window DPI scaling

In the Windows 10 Anniversary Update we introduced mixed-mode DPI scaling (sub-process DPI scaling) that enabled you to have different DPI scaling modes within each top-level window in an application. We do not, however, support child-window DPI scaling. There are many interesting scenarios where this could come in handy, such as when you’re hosting external HWND content that could be running in a different DPI awareness mode. If you don’t have the ability to control the code that generates that hosted content it would be nice to have Windows DPI scale it for you. Unfortunately, this is not supported today.


Although we’ve added per-monitor DPI scaling support to Win32, WPF and WinForms, MFC does not natively support this functionality.

Display settings page & mouse input

When you have multiple displays with different DPI/Display Scaling values, the Display Settings Page will show you a representation of your display topology. The displays are represented in terms of their resolution, whereas it might be more if they were represented per their physical/real-world dimensions.

Furthermore, when you have two displays that are nearly the same physical size but with different display scaling values (one 4K and one 1080p display, for example) and move the mouse between the displays you can hit “dead zones” where the mouse cannot move. Here it would be more intuitive to have the mouse movement reflect the physical size/dimensions of the displays, not the resolutions of the displays.

Dragging Windows

When you drag an application window from one display to a display with a different DPI, you’ll see an oddly shaped representation of the window. Part of the window will render at the wrong DPI for the display that it’s on, until you move enough of it to the new display. At that point the window snaps to the new DPI and looks odd on the display that it came from. It would be nice to have a smoother transition here.

The need to log out and back in

Most of all, the fact that you have to log out and back into Windows to get most applications to render correctly after a DPI change is a huge pain-point. We do not currently have a solution for this beyond having applications updated to support per-monitor DPI awareness.


Again, hopefully you’ll enjoy these improvements. We still have a long way to go but we are working on improving Windows 10 high-DPI functionality and support. Do you have any other ideas of things that you’d like to see in this space? If so, please leave a comment below or reach out @WindowsUI.

Desktop Bridge: Smooth User Transition and Data Migration


The Windows 10 Creators Update will help provide smooth user transition along with some best practices for app developers to follow. This feature is available on the current insider builds.

Users will be encouraged to download the store version of their desktop apps. If the user already has the previous desktop version of the app, the transition experience should be as seamless as possible.

User Transition: Taskbar Pins & Start Tiles

Many users typically pin their favorite or most used apps to the taskbar pin or the start menu. This enables them to access the apps much faster.

With the Creators Update, app developers can re-route the taskbar pins and the start tile shortcuts to point to the store version of the desktop app.

Here’s a sample AppXManifest.xml snippet which shows the declaration for this transition.

You must use the following namespace:



This extension must be under the <Application> element.

&lt;rescap3:Extension Category=&quot;windows.desktopAppMigration&quot;&gt;
&lt;rescap3:DesktopApp AumId=&quot;[your_app_aumid]&quot; /&gt;
&lt;rescap3:DesktopApp ShortcutPath=&quot;%USERPROFILE%Desktop[my_app].lnk&quot; /&gt;
      		&lt;rescap3:DesktopApp ShortcutPath=&quot;%APPDATA%MicrosoftWindowsStart MenuPrograms[my_app].lnk&quot; /&gt;
      		&lt;rescap3:DesktopApp ShortcutPath=&quot;%PROGRAMDATA%MicrosoftWindowsStart MenuPrograms[my_app_folder][my_app].lnk&quot;/&gt;

If you know your app’s Application User Model ID, then we recommend that you use it for the transition.

Otherwise, you can use the path to your app’s shortcut (.lnk) file. If you don’t know where your app installs the shortcut, the easiest way to find it is to right-click on the app’s name from the start menu and select “Open file location.

You have to make sure the path you use in the AppXManifest.xml uses the environment variables (one of %USERPROFILE%, %APPDATA%, or %PROGRAMDATA%). Most likely, the shortcut is under %PROGRAMDATA%.

User Transition: File type associations & protocol handlers

The user may choose their favorite app to be the default app for a given file type or protocol. With the Creators Update, the developers can also transition the favorite app to use the app’s store version.

Here’s the AppXManifest.xml snippet that shows how the Filetype Association is transitioned. The Protocol Handlers are transitioned in the same way.

As part of this transition, you need to provide the Programmatic Identifier.

You must use the following namespace:


&lt;uap:Extension Category=&quot;windows.fileTypeAssociation&quot;&gt;
&lt;uap3:FileTypeAssociation Name=“.foo”&gt;

Data Migration

As a best practice, we recommend that developers migrate previous user data from the desktop app upon first launch of the store version of the same app.

This will delight the users, so they can “pick up where they left off.”

Please refer to the code sample below to learn about the best practices on how to do this on first launch while recognizing which version of your desktop app you are running (store version vs. previous desktop version).

User Transition: Uninstall previous desktop app

As a best practice, we recommend that developers offer uninstallation of the previous desktop app upon first launch of the store version of the app. This will help avoid user confusion and potential user data corruption.

Keep in mind that the user can refuse the uninstallation of the previous desktop app, so the previous and store version of the app may end up running side-by-side. It is up to the app developer to decide whether or not to block the launch of the store version of the app until the previous desktop app is uninstalled.

//Please refer to this blogpost to learn how you can use this method            
if (IsRunningAsUwp())

                //Detect if there is previous user data
  //In this example, the previous user data was in the ApplicationData You should change this based on where the previous data was					
                String sourceDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + &quot;AppName&quot;;
                if(sourceDir != null)
                    String migrateMessage = &quot;Would you like to migrate your data from the previous version of this app?&quot;;
                    MessageBoxResult migrateResult = MessageBox.Show(migrateMessage, &quot;Data Migration&quot;, MessageBoxButton.YesNo);

                    if (migrateResult.Equals(MessageBoxResult.Yes))
                        //Migrate user data
                        String destinationDir = Windows.Storage.ApplicationData.Current.LocalFolder.Path + &quot;AppName&quot;;
   //If you are moving data from one of the redirected folders, you need to use robocopy.exe to bypass redirection. This is the only time you should bypass redirection 
//Otherwise, you should move files using System.IO
                        if (runProcess(&quot;robocopy.exe&quot;, &quot;%LOCALAPPDATA%AppName &quot; + destinationDir + &quot; /move&quot;) &gt; 1 )
                            //Migration was unsuccessful -- App Developer can choose to block/retry/other action

                //Detect if the previous version of the Desktop App is installed
		  //Typically your uninstall string lives under this
                String uninstallString = (String)Microsoft.Win32.Registry.GetValue(@&quot;HKEY_LOCAL_MACHINESOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall{7AD02FB8-B85E-44BC-8998-F4803BA5A0E3}&quot;, &quot;UninstallString&quot;, null);

                if (uninstallString != null)
                    String uninstallMessage = &quot;It is recommended that you uninstall the old version of this application in order to have a better experience. Would you like to uninstall the previous version of your app now?&quot;;
                    MessageBoxResult uninstallResult = MessageBox.Show(uninstallMessage, &quot;Uninstall the previous version&quot;, MessageBoxButton.YesNo);

                    if (uninstallResult.Equals(MessageBoxResult.Yes))
                        //Run the uninstaller by using Process (see private method below) 
                        string[] uninstallArgs = uninstallString.Split(' ');
                        if (runProcess(uninstallArgs[0], uninstallArgs[1]) != 0)
                            //Uninstallation was unsuccessful - App Developer can choose to block the app here

private int runProcess(string appName, string arguments)
            Process process = new Process();
            process.StartInfo.FileName = appName;
            process.StartInfo.Arguments = arguments;
            process.StartInfo.CreateNoWindow = true;

            return process.ExitCode;