I have been looking into High DPI support for Windows Forms, as per the following link.
https://learn.microsoft.com/en-us/dotnet/desktop/winforms/high-dpi-support-in-windows-forms
However, I'm not sure exactly what the High DPI support actually accomplishes, does the High DPI support simply mean that controls and fonts will be rendered smoothly on High DPI displays?
I have tried enabling High DPI via an Application Manifest File in my Windows Forms project, but this didn't seem to have any visible effect on the application. Everything still appears to be the same size within the application.
--
I've also been looking at the following link regarding automatic form scaling.
https://learn.microsoft.com/en-us/dotnet/desktop/winforms/forms/autoscale
However, again I'm not sure what this is saying, will the auto-scaling actually make controls and fonts look bigger on a high DPI display?
--
Now for my actual problem.
I am designing a form which is 405x720 pixels in size on a 24 inch 1920x1080 display # 96 DPI. I want the controls and fonts on the form to have the same physical dimensions when displayed fullscreen on a 6 inch 720x1280 screen which is around 244 DPI.
There is a potential solution for this at the following link.
Scale windows forms window
Is an approach similar to the one in the above StackOverflow link above still the only way to achieve what I am looking for regardless of the High DPI improvements in the latest versions of .NET, or am I potentially missing something with the High DPI and automatic scaling?
Related
I have an old-school ordinary WinForms app in VS2019, for which the tabs on a tab control are vertically squished on a high-DPI monitor. In fact, if the app is opened on a high-DPI monitor and dragged to a regular monitor, the tabs remain squished. I want the app to automatically scale the controls properly. As a user, I can make that happen post-installation by adjusting Compatibility Settings on the executable: [Properties->Compatibility->Change high DPI settings->High DPI scaling Override->Override high DPI scaling behavior. Scaling performed by System (Enhanced)]. I don't want the user to have to do that -- I'd rather fix it in the source code.
I've read dozens and dozens of articles on this subject and it seems they are all outdated, as the 'recommended method' has changed several times over the past few years (and none of them seem to work). The bottom line is that it seems likeI need to do the opposite of what most of them advise -- specifying that the app is DPI-aware (i.e. turning 'DPI-awareness' 'on'). It is NOT DPI-aware, but the 'System (Enhanced)' scaling (seemingly intended precisely for non-DPI-aware apps) works great. But maybe I misunderstand what 'DPI-awareness' means.
What is currently the best practice for specifying programmatically (or via the manifest) that 'this app does not have any provisions for scaling itself or being aware of how many pixels per inch your monitor has, but allowing "System (Enhanced)" scaling from Windows 10 works great. Please do that.'?
My WPF application works well on Hi-DPI display (e.g. My Yoga Pro 2 laptop, with 192 DPI display (13 inch, 3200x1800).
All vector-defined GUI elements are crisp and sharp - without any explicit programming for that. Seems then WPF can pick the proper rendering DPI matching DPI of the display and automatically all is fine. As far as the program is running locally.
However, when the same application is run on remote desktop, (connection to local Virtual machine with "enhanced" desktop mode) - the application is rendered # 96 DPI, and scaled-up twice to have proper size. The problem is that this scaling is bitmap-scaling which naturally produces blurry/pixelated appearance.
I believe that this should be plain-easy to declare something to make the app rendered "natively" with the High DPI on the RDP, without the need to scale it afterwards (by the system anyway) to make it expected size.
I tried to set in app.manifest
true
but, it did not solve the problem...
Any ideas ?
Btw - other applications (e.g. Windows Explorer can render on RDP at proper DPI, without later being scaled up to match natural size (note: on high DPI everything looks small if not rendered natively with high dpi).
I've isolated the problem to a blank WPF application with a mere TextBlock to display. This app, when run on RDP (Windows 10 Creators version or later) can easily be used to reproduce the problem (The text is proper size, but is bitmap-scaled (as part of the whole application scaled up)).
Thanks,
Michael
I built an application on a computer with normal DPI size. It is a WinForms application with many forms and custom controls. When I open the project on my Lenovo Yoga 900 with high DPI it looks good in Visual Studio 2013 but when I run the application some parts are off screen.
Even worse is when I open the application after a change on my "normal DPI computer". Most of the controls are scaled up, margins and paddings are scaled too.
With other words my forms are messed up. I've read about the AutoScaleMode which is set to Font. Even I change that property there are not realy noticable changes.
Any suggestions how I can handle that problem? Or does someone have similar experiences/issues?
I have created a WinForm desktop application.
I have installed it on 2 different client PCs.
On 1 PC the captions fit with their controls.
On the other the label does not resize properly.
I went to check the resolution on each Client PC expecting differences but on the resolution 1920x1080 it did not fit and on the resolution 1680x1050 it did fit.
To make things more weird on my development PC the resolution is 1920x1080 and yes the labels do fit.
AutoSize on Form and label is 'true'.
What am I missing?
On the other the label does not resize properly
No, it is the exact opposite. It did resize properly, leaving enough space for the text. Problem is, the text is too wide.
There is more than one problem going on here. Starting point is that the other machine is operating at a different DPI setting. Dots-per-inch, it determines how a font size of, say, 10 points is mapped to pixels on the screen. You have a nice monitor, a high resolution one at 1920 x 1080 pixels. To keep text readable, you wanted 10 points to take more pixels. So you increased the DPI setting. Very easy to do on later Windows versions, you probably moved to slider to 125%. Effective DPI is 120 dots per inch.
Your program however is running on an older machine, one that still has the legacy setting (100% = 96 dpi). This tends to cause accidents, you avoided the most common ones given that the form properly rescaled itself. It shrunk itself to match the lower DPI setting. The layout is still correct, the labels and textboxes have the correct size and location.
But you can see a mishap with the bitmap, it is now too big too fit the space. Not the most obnoxious side-effect here. Otherwise not that easy to fix, to see the entire bitmap it has to be shrunk as well and that causes it to get fuzzy and lose detail. The only perfectly clean fix is to have two bitmaps, each drawn to match the dpi of the target machine. Unfun and often skipped.
Moving to the problem you are complaining about, text rendering at different dpi setting can be a problem as well. At issue is that the height of text scales quite well, but the width does not. The technical term for that is that text rendering is not resolution independent. The chief issue is pixel-grid fitting, a technique used to make text more readable at low monitor resolutions. Aided by TrueType hinting, the shape of a letter is stretched so that stems of a character fall exactly on a monitor pixel. Which greatly improves readability, but of course the side effect is that text will be wider on such low resolution monitors.
But your text is off so much that another explanation is needed. The most likely mishap here is that you used a font that is not available on the old machine. The operating system now must fallback to a substitute font and it has a very different pitch from your original font. I can't see your code but I'd roughly guess at a mapping from Segoe to Microsoft Sans Serif.
There are no simple solutions to these kind of problems, it is just something you need to be aware of. A basic guideline is that it is almost never a problem to scale up, scaling down is a lot more troublesome. So running your dev machine at 96 dpi is in general a good idea, other than the inconvenience of course. Testing on older operating systems, or putting your foot down with a strongly stated prerequisite (like XP not supported), is required. Demanding a higher resolution than 96 dpi is however still unreasonable, lots of machines are still at that legacy setting. Not in the least because changing it causes so many programs to misbehave. 96 dpi has been the default setting for way too long, those days are however over and done with.
How can I force a winforms app to use the fonts/fontsizes I specify on every machine?
I have a c# app where the font seem to change in size on a different machine, and it's not a resolution thig. This is on windows 7 with a c# app. Is there a way to force the font size I want or do the user os fonts always overrule?
Font sizes are specified in points. One point is 1/72 inches. The problem is that this needs to jive with the rest of Windows Forms where almost anything is specified in pixels. The issue is how many pixels make a point. That depends on your video adapter's dots-per-inch setting.
The traditional setting is 96 dots per inch. So if you ask for a 9 point font, you'll get one that's 9 / 72 * 96 = 12 pixels high. As long as the client area of a control is at least 12 pixels high, the text displayed inside of it won't be clipped.
The video adapter's DPI setting can be changed however. They made it kinda difficult in XP, you had to go into the Display applet's Advanced setting to do so. It got a lot easier in Vista, there's a direct link to it with a nice ruler and whatnot.
The next common setting is 120 DPI, 125% more dots per inch. That 9 point font now needs 9 / 72 * 120 = 15 pixels. If the original control that displays that text is still at 12 pixels, the text is going to get clipped. Basically, the descenders are sheared off.
So to fix that, the Control.Size property of the controls in the form need to change. They need to be scaled to accommodate the larger DPI setting. Windows Forms readily supports that. It is the Form.AutoScaleMode, available since .NET 2.0. When you set it to something else than None then automatic code inside Windows Forms kicks in that compensates for the difference between the machine that designed the form and the machine that displays the form. In the 120 DPI case, it will make the form and the controls bigger. So that they can display text without it getting clipped.
But, there's a complication. Changing the DPI setting is great for fonts. TrueType is awesome technology, capable of rendering good looking type at any size. But rescaling doesn't work very well for images that contain line art. They get stray extra pixels or get fuzzy when you rescale them.
Back to fonts: clearly if you change the DPI setting of the monitor, the user would expect the fonts to follow suit. That certainly worked that way back in the XP days. If you change the video adapter's DPI setting, you get a prompt to reboot the operating system. That was important back then because there were lots of program that used device fonts, not TrueType fonts. Non-scalable fonts. New fonts got activated that match the DPI setting. A larger value for video DPI is thus matched with a larger system base font size.
Around the same time, some kind of genius at Microsoft, since assassinated, came up with a Really Good Idea. People that live in East Asia have a writing system based on characters. Intricate glyphs that need lots of pixels to show the details. 12 pixels at 96 DPI does not leave a lot of room to make a good looking Chinese or Korean glyph. Increasing the DPI obviously improves that, but at the cost of having fuzzy images. The Idea: increase the system base font size but don't change the video DPI.
Now there's a new problem however: how to auto-scale the UI. You can see this back in the values you can assign to the AutoScaleMode property, either Font or DPI. Which one is correct for the target machine is not easily guessable. Font is normally the better choice since you want to make sure that text isn't clipped. However, if you want to make sure that images display at the right size, then you want DPI. When you want both then you are stuck between a rock and a hard place, one you can't get out of unless the system base font size matches the video DPI setting.
You cannot do more than specify the font size you prefer. If the user chooses to use great font sizes (125% / 150%) or the magnifier, your font size will increase.