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.
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.'?
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?
This is more out of curiosity. I was studying that WPF applications are resolution independent. Does this means that we need not bother about the monitor resolution size? because being a windows application developer I have faced several challenges making the application compatible to different resolutions.
My question here is how WPF manages the resolution independent property? Do we need to provide ratios in which controls would appear? And how would the quality of the image will be effected if used as background (will it distort in high resolutions or maintain its clarity)?
Please help. This can be a deciding factor for a project.
As far as I know, WPF uses vector graphics for Buttons isntead of Bitmaps like the older WinForms. Due to this, resizizing and adapting to different screen resolutions is easy for WPF.
I have no direct experience with Background images etc. but if they are pixel-based I would provide them in a higher resolution than needed in 96 DPI, maybe twice as high? That should guarantee, that they are not looking poor in higher resolutions.
As a practical note: WPF applications are always readable and are looking good on all monitors I have tried so far. But if you use far smaller resolutions to display a program which was developed for bigger resolutions you can run into problems with fixed objects. E.g. defining text boxes to a certain minimal size, which than eats too much of the available screen. So it seems best for me to define as few constraints as possible and test the applications on other monitors before you ship the product simply because it will always be readable but you might find a few problems with usabillity.
The key thing about WPF and resolution independance is that it uses device independent units and uses this to work correctly with the system dpi setting ( 'Large Fonts' etc); so for example if you are working on a system set to the default 96 dpi, and draw a textbox 96 units wide, WPF knows that this is one logical inch. If you then change the resolution to 144 dpi, WPF will draw the textbox using 144 physical pixels. All the GUI elements scale flawlessly like this. If you try the same thing with a Winforms GUI you will see that it does not scale properly - you end up with big fonts in small textboxes etc
ETA
Another way to put this is to clarify what you mean by resolution - I guess 1024 x 768 is really 'screen size in pixels' and the 96dpi is more accurately the actual resolution, and it's changes to this that WPF handles correctly whilst other platforms don't; both Winforms etc and WPF will display correctly if you simply change from 800 x 600 to 1024 x 768.
WPF is vector based and contains a lot of powerful layout features to ensure scaling works nicely on any device (the simple but powerful Grid control is one of my faves here). It basically uses a measurement and arrangement system that ensures that child controls know how much space they have to work with and therefore can size themselves accordingly
Having said that, it is up to the UI designer to ensure that the application layout is scalable, since it is still very possible to create hard-coded fixed, non-fluid layouts by setting explicit sizes etc
If this does happen, it's possible to scale the entire UI (by using a transforms and other methods) which would have the effect of a zoom in/zoom out depending on if the app is targeting a larger or smaller resolution. This has the disadvantage of making any non-vector content such as bitmaps look blocky or distorted if they are not designed for this scaling
In conclusion, WPF doesn't manage any resolution independence directly so to speak, but by using a few simple layout concepts it's possible to make a resolution independent UI without resorting to scaling (similar to using anchoring in WinForms...but much better)
A small example:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100">
<ColumnDefinition Width="auto">
<ColumnDefinition Width="*">
<ColumnDefinition Width="2*">
</Grid.ColumnDefinitions>
</Grid>
This would create a two column grid layout in which the first column is a fixed width at 100 units, the second column takes up only enough space to fit its child controls and the fourth column takes up proportionately two times the space of the third column. These columns would stretch to completely fill their parent container, be that a small area of the screen or a full window.
This works by measuring how much available space there is to play with, making the 1st column a fixed 100 units, making the second column the size of the child controls that are in it and then working out what space is remaining and dividing it amongst the other columns based on their ratios. (the number before the asterisk * is the proportion of space each dynamically sized column should take. * on it's own is equivalent to 1*)
This with the standard Margin and alignment properties allows for almost any layout imaginable...and this is just a single control!
Edit:
I'd probably add that whilst most people don't use silly resolutions it is surprising how many people are still running 1024x768 or running widescreen mid resolution monitors that have a vertical resolution of less than 800 pixels, so the only way to be sure is to test!
Question 1: My question here is how WPF manages the resolution independent property?
from MSDN:
Resolution-independent and device-independent graphics. The basic unit of measurement in the WPF graphics system is the device independent pixel, which is 1/96th of an inch, regardless of actual screen resolution, and provides the foundation for resolution-independent and device-independent rendering. Each device-independent pixel automatically scales to match the dots-per-inch (dpi) setting of the system it renders on.
Question 2: how would the quality of the image will be effected if used as background (will it distort in high resolutions or maintain its clarity)?
I guess this would mostly depend on the quality of the given picture. a high quality image wont loose of it clarity while being scaled.
I would recommend reading the following articles:
Introduction to WPF you will learn that there is more to wpf than resolution in dependency (DataBinding, layouts, styles, templates, 2D, 3D, animation....)
Imaging Overview WPF Graphics Rendering Overview
I have a form that I have sized to what I wanted, it has a few panels, some buttons and some labels on it but when I open it on a different computer, it is resized and it is larger. I am using visual studio 2008. I know this is very little detail but I thought maybe someone knows of a known issue or some troubleshooting steps that I can take.
Possible reasons for this are different screen resolution and different DPI.
Several possible reasons. First and foremost is the form's AutoScaleMode property. The default, Font, ensures that both the font and the controls get resized to leave enough room for any displayed text. Text size is measured in points, 1/72 of an inch. If you run your program on a machine with a larger dots-per-inch setting for the video adapter, the fonts grow accordingly and need more pixels. That needs the controls to be bigger as well to prevent clipping the text.
Another reason is user preferences for border width (Aero) and caption bar height. A form is sized based on its designed ClientSize, the actual Size at runtime will be determined by adding those preferences to the design size. That's very rarely a problem.
May be the computers have different screen resolution and that's why it appears small in one and large on the other computer
Diffeent resolutions, different browsers, different versions. If you want o keep this from happening, you must specify their width and height.
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.