I've developed a WinJs app for the Surface pro 4. The app Runs in fullscreen and is layoutet with the screen resolution of 2736x1824 (surface resolution).
Now when i start the App on the surface the DPI scaling comes into play and messes up my Layout.
Is there a way to disable the scaling for the app?
I've tried:
Windows.UI.ViewManagement.ApplicationViewScaling.trySetDisableLayoutScaling(true);
but that doesn't seem to work.
Actually, making your app layout only for one resolution, especially for such a big resolution is not really great idea since the app can run on device with, for example 1920x1080 resolution where even with DPI scaling disabled your layout will be messed up.
So I recommend making the app layout responsive so it will look right on every resolution.
Not sure if you're still looking at this issue but I've found that the code that you see all over the place is actually XBox only (Link To Docs)
And the Microsoft Devs have been saying for a while that it's a user based setting and they don't plan on allowing you to ds(Forum Link)
You can detect the scaling value though with ResolutionScale (docsLink)
Windows.Graphics.Display.DisplayInformation.getForCurrentView().resolutionScale
Here's a link to a sample that detects it and adjusts.
So what you can do (and what I did) was where needed I used css scale to adjust the system to fit. Most of my app is responsive so it didn't matter, but if you use an iFrame and set it to be 1000px wide with this scale factor it will actually be 1400px or even 1800px wide and totally cut off..
I have listeners setup for the resize events and just adjust as needed.
Hope that helps!
-Dennis
Windows 8.1 introduced the ability to have different DPI settings for different monitors. This feature is known as "per-monitor high-DPI support." It persists and has been further refined in Windows 10.
If an application does not opt in (i.e., is either DPI-unaware or high-DPI aware), it will be automatically scaled up by DWM to the proper DPI. Most applications fall into one of these two categories, including most of the utilities bundled with Windows (e.g., Notepad). On my test system, the high-DPI monitor is set to 150% scale (144 DPI), while the normal monitor is set to the system DPI (100% scale, 96 DPI). Therefore, when you open one of these applications on the high-DPI screen (or drag it over there), virtualization kicks in, magnifying everything, but also making it incredibly blurry.
On the other hand, if an application explicitly indicates that it supports per-monitor high-DPI, then no virtualization is performed and the developer is responsible for scaling. Microsoft has a fairly comprehensive explanation here*, but for the benefit of a self-contained question, I'll summarize. First, you indicate support by setting <dpiAware>True/PM</dpiAware> in the manifest. This opts you into receiving WM_DPICHANGED messages, which tells you both the new DPI setting as well as a suggested new size and position for your window. It also allows you to call the GetDpiForMonitor function and obtain the actual DPI, without being lied to for compatibility reasons. Kenny Kerr has also written up a comprehensive tutorial.
I've gotten all of this going successfully in a little C++ test app. It's a lot of boilerplate and mostly project settings, so I don't see much point in posting a full example here. If you want to test it out, either follow Kenny's instructions, this tutorial on MSDN, or download the official SDK sample. Now, the text in the client area looks good (because of my handling of WM_DPICHANGED), but because virtualization is no longer performed, there is no scaling of the non-client area. The result is that the title/caption bar and the menu bar are the wrong size—they do not get larger on the high-DPI screen:
So the question is, how do I get the non-client area of the window to scale to the new DPI?
It doesn't matter whether you create your own window class or use a dialog—they have identical behavior in this respect.
It has been suggested that there is no answer—that your only choice is to custom draw the entire window, including the non-client area. While this is certainly possible, and indeed what UWP apps (those previously known as Metro) do, like the Windows 10 Calculator, it is not a workable option for desktop applications that use many non-client widgets and hope to look native.
Aside from that, it is demonstrably false. Custom-drawn title bars cannot be the only way of getting the correct behavior, since the Windows shell team has done it. The humble Run dialog behaves exactly as expected, properly resizing both the client and non-client areas as you drag it between monitors with different DPIs:
Investigation with Spy++ confirms this is just a bog-standard Win32 dialog—nothing fancy. All of the controls are standard Win32 SDK controls. It is not a UWP app, nor have they custom-drawn the title bar—it still has the WS_CAPTION style. It is launched by the explorer.exe process, which is marked as per-monitor high-DPI aware (verified with Process Explorer and GetProcessDpiAwareness). This blog post confirms that both the Run dialog and the Command Prompt have been rewritten in Windows 10 to scale correctly (see "Command shells et al."). What is the Run dialog doing to resize its title bar?
The Common Item Dialog API, responsible for new-style Open and Save dialogs, also scales correctly when launched from a process that is per-monitor high-DPI aware, as you can see when clicking the "Browse" button from the Run dialog. Same thing for the Task Dialog API, creating the odd situation where an app launches a dialog box with a different-size title bar. (The legacy MessageBox API has not been updated, however, and exhibits the same behavior as my test app.)
If the shell team is doing it, it has to be possible. I just cannot imagine that the team responsible for designing/implementing per-monitor DPI support neglected to provide a reasonable way for developers to produce compatible applications. Features like this require developer support, or they are broken out-of-the-box. Even WPF applications are broken—Microsoft's Per-Monitor Aware WPF Sample project fails to scale the non-client area, resulting in a title bar that is the wrong size. I'm not much for conspiracy theories, but this smells of a marketing move to discourage desktop app development. If so, and there is no official way, I'll accept answers that rely on undocumented behavior.
Speaking of undocumented behavior, logging window messages when the Run dialog is dragged between monitors with different DPI settings shows that it receives an undocumented message, 0x02E1. This is somewhat interesting because this message ID is exactly one greater than the documented WM_DPICHANGED message (0x02E0). My test app never gets this message, though, regardless of its DPI-awareness settings. (Curiously, close inspection does reveal that Windows slightly increases the size of the minimize/maximize/close glyphs on the title bar as the window moves onto the high-DPI monitor. They're still not as big as they are when they are virtualized, but they're slightly bigger than the glyphs that it uses for unscaled system-DPI applications.)
So far, my best idea has been to handle the WM_NCCALCSIZE message to adjust the size of the non-client area. By using the SWP_FRAMECHANGED flag with the SetWindowPos function, I can force the window to resize and redraw its non-client area in response to WM_DPICHANGED. This works fine to reduce the height of the title bar, or even remove it altogether, but it will never make it any taller. The caption seems to peak out at the height determined by the system DPI. Even if it worked, this wouldn't be the ideal solution, because it wouldn't help with the system-drawn menu bar or scroll bars…but at least it would be a start. Other ideas?
* I know that this article says "Note that the non-client area of a per monitor–DPI aware application is not scaled by Windows, and will appear proportionately smaller on a high DPI display." See above for why that is (1) wrong and (2) unsatisfactory. I'm looking for a workaround other than custom-drawing the non-client area.
In any up-to-date Windows Insider builds (build >= 14342, SDK version# >= 14332) there is an EnableNonClientDpiScaling API (which takes an HWND as its argument) that will enable non-client DPI scaling for top-level HWNDs. This functionality requires that the top-level window be running in per-monitor DPI-awareness mode. This API should be called from the WM_NCCREATE handler for the window. When this API is called on a top-level window, its caption bar, top-level scrollbars, system menu and menubar will DPI scale when the application’s DPI changes (this can happen when the app is moved to a display with a different display scaling value or when the DPI changes for other reasons such as the user making a settings change or when an RDP connection changes the scale factor).
This API does not support scaling non-client area for child windows, such as scroll bars in a child window.
To my knowledge there is no way to have non-client area DPI scale automatically without this API.
Note that this API has not yet been finalized, and it may change prior to being released in the Windows 10 Anniversary update. Keep your eye on MSDN for official documentation when it becomes final.
With Per Monitor V2 DPI awareness in Windows 10 Creators Update (build 15063) you can resolve this easily without the EnableNonClientDpiScaling.
To enable Per Monitor V2 DPI awareness, while still supporting old Per Monitor DPI awareness on older Windows 10 builds and Windows 8.1 and DPI awareness on yet older versions of Windows, make your application manifest like this:
<assembly ...>
<!-- ... --->
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
References:
High DPI Improvements for Desktop App Developers in the Windows 10 Creators Update – video (archived)
Application Manifests – reference
High DPI Desktop Application Development on Windows – documentation
Note that in WinForms targeting .NET 4.7 and later, you can achieve the same by adding
<add key="DpiAwareness" value="PerMonitorV2" />
to <System.Windows.Forms.ApplicationConfigurationSection> tag in app.config. I assume that in the end, this change modifies the manifest in the target binary as described above.
How can I change the resolution of the phone representing the code when in xaml view in a project?
The phone serves as a drag and drop for the controls, does it have a setting somewhere to set it's resolution. Windows Phone 8 currently have three resolutions; 800x480, 1280x720 and 1280x768.
I'm aware the emulator can be started up with different resolution, but my situation is that my CPU does not support this, im debugging straight on my Lumia 920 (1280x768).
I've got no clue on how the application looks like in 800x480.
But it is a simple application, a preview would be good enough.
You need to open the Device Window: Design -> Device Window
There under the display section you can select the display size (3 available).
Additionally you can test any other resolution by disabling the 'Chrome' option in the device window and setting d:DesignHeight and d:DesignWidth of your page to the desired resolution.
I had the problem and after much time searching google and stackoverflow, I don't think that it is possible to change the resolution of the designer window. However, maybe this link can help you, it helped me back a while ago when I had that problem:
WP8 Emulator screen size
It refers to the emulator, but explains how the app UI will be scaled to match different device resolutions. Hope it helps!
We are having a problem with one of our existing Win32 MFC based applications. It does not render correctly on displays that use high dpi settings. More specifically in Windows XP with 120 dpi selected, there are several places in the app where the text scales up but not their containers (text overflowing the bounds of it's button, etc). This also occurs in Windows 7 (and Vista) when >96 dpi is selected and "use XP style dpi scaling" is selected. If xp style scaling is not selected then I understand Win7 uses DPI virtualization instead. Everything looks fine when using DPI virtualization (Ok things are blurry but at least they're correct). By default in Win7 120 dpi uses xp style scaling and the next setting (144 dpi) does not. So our app looks correct at 144 dpi but wrong at 120 dpi.
If I edit the applications manifest to declare the app as "DPI aware" then this turns of DPI virtualization (but not XP style dpi scaling) and this gets me no where. Things still look really bad (no change for 120 dpi, 144 dpi now broken).
I need to fix this problem and I've tried reading up on DPI/scaling issues in general and it has been a learning experience. So far I have not found a suitable solution. At the moment I currently have no intention of doing a thorough and correct fix (the app correctly scales all elements according to the dpi). That would involve a LOT of rewriting. I think there are really two possible solutions. One is turn off any sort of DPI scaling all together. That would mean that if a users Win7 system was set to 120 dpi then everything on their system would look good/big but our app would look correct but would be small compared to everything else in other apps. The second solution would be to some how force our app to use DPI virtualization but to never use XP style dpi scaling. I want this to be an application side change and not rely on end users to have to make Windows configuration changes.
So far I have not found a way to accomplish either solution.
Can someone more knowledgeable on this subject please respond and point me in the right way?
Thanks
You cannot force DPI Virtualization on 120 DPI settings. I have investigated this for a product myself because having the fuzzy look in high DPI seemed a good tradeoff.
We ended up making a full rewrite of the UI positioning and scaling to have it scale properly with the font scaling in high DPI settings. The client is now fully DPI aware and scales properly in any DPI setting.
The work to do this properly took one guy ~3 months in our case for a pretty complex client.
We had a secondary plan that we never tried but it might work for you:
At start-up read the DPI scaling factor of the OS. Then reduce all font instances you have by this factor so that when Windows scales the fonts up again they are back at the size where the UI can fit them. Of course users with high DPI settings will not get bigger fonts in your application but it will at least be usable.
Assume a GUI application is opened on three machines running Windows XP, Windows Vista and Windows7. In all the three machines, the screen resolution and the DPI settings are set to be the same value. Will there be a difference in the way the application is displayed on the screen in terms of number of pixels used and their position on the screen?
The reason for asking this question is:
I am using position based record-and-play method for GUI automation. Any change in the position of a control can impact the playback of the GUI recording. I want to be sure that a recording captured on Windowx XP platform works on Vista and Windows7 platforms.
Yes. The OS chrome (starting with window borders and titles) have different styles (e.g. Vista and Win7 will likely have Aero on and thus translucent title).
And that's before considering any OS dependent code in the application.
The menu bars will probably all be different sizes, so you'll probably need to record separately on all three machines.
Bearing in mind, that each user could have any number of accessibility settings on/off, any DPI setting, and also that features such as button sizes and window border sizes are different on each of these OS's...
No one here could possibly guarantee you'll be fine - the only way is to test.
A side note: there MUST be a better way than position based playback? I've used tools previously that can read screen text and base the automated navigation on that, which seems far more sensible, but still horribly flawed.