Search code examples
windowsdelphiwindows-7

How do I make my GUI behave well when Windows font scaling is greater than 100%


When choosing large font sizes in the Windows control panel (like 125%, or 150%) then there are problems in a VCL application, every time something has been set pixelwise.

Take the TStatusBar.Panel. I have set its width so that it contains exactly one label, now with big fonts the label "overflows". Same problem with other components.

Some new laptops from Dell ship already with 125% as default setting, so while in the past this problem was quite rare now it is really important.

What can be done to overcome this problem?


Solution

  • Note: Please see the other answers as they contain very valuable techniques. My answer here only provides caveats and cautions against assuming DPI-awareness is easy.

    I generally avoid DPI-aware scaling with TForm.Scaled = True. DPI awareness is only important to me when it becomes important to customers who call me and are willing to pay for it. The technical reason behind that point of view is that DPI-awareness or not, you are opening a window into a world of hurt. Many standard and third party VCL controls do not work well in High DPI. The notable exception that the VCL parts that wrap Windows Common Controls work remarkably well at high DPI. A huge number of third party and built-in Delphi VCL custom controls do not work well, or at all, at high DPI. If you plan to turn on TForm.Scaled be sure to test at 96, 125, and 150 DPI for every single form in your project, and every single third party and built in control that you use.

    Delphi itself is written in Delphi. It has the High DPI awareness flag turned on, for most forms, although even as recently as in Delphi XE2, the IDE authors themselves decided NOT to turn that High DPI Awareness manifest flag on. Note that in Delphi XE4 and later, the HIGH DPI awareness flag is turned on, and the IDE looks good.

    I suggest that you do not use TForm.Scaled=true (which is a default in Delphi so unless you've modified it, most of your forms have Scaled=true) with the High DPI Aware flags (as shown in David's answers) with VCL applications that are built using the built-in delphi form designer.

    I have tried in the past to make a minimal sample of the kind of breakage you can expect to see when TForm.Scaled is true, and when Delphi form scaling has a glitch. These glitches are not always and only triggered by a DPI value other than 96. I have been unable to determine a complete list of other things, that includes Windows XP font size changes. But since most of these glitches appear only in my own applications, in fairly complex situations, I have decided to show you some evidence you can verify yourselves.

    Delphi XE looks like this when you set the DPI Scaling to "Fonts @ 200%" in Windows 7, and Delphi XE2 is similarly broken on Windows 7 and 8, but these glitches appear to be fixed as of Delphi XE4:

    enter image description here

    enter image description here

    These are mostly Standard VCL controls that are misbehaving at high DPI. Note that most things have not been scaled at all, so the Delphi IDE developers have decided to ignore the DPI awareness, as well as turning off the DPI virtualization. Such an interesting choice.

    Turn off DPI virtualization only if want this new additional source of pain, and difficult choices. I suggest you leave it alone. Note that Windows common controls mostly seem to work fine. Note that the Delphi data-explorer control is a C# WinForms wrapper around a standard Windows Tree common control. That's a pure microsoft glitch, and fixing it might either require Embarcadero to rewrite a pure native .Net tree control for their data explorer, or to write some DPI-check-and-modify-properties code to change item heights in the control. Not even microsoft WinForms can handle high DPI cleanly, automatically and without custom kludge code.

    Update: Interesting factoid: While the delphi IDE appears not to be "virtualized", it is not using the manifest content shown by David to achieve "non-DPI-virtualization". Perhaps it is using some API function at runtime.

    Update 2: In response to how I would support 100%/125% DPI, I would come up with a two-phase plan. Phase 1 is to inventory my code for custom controls that need to be fixed for high DPI, and then make a plan to fix them or phase them out. Phase 2 would be to take some areas of my code which are designed as forms without layout management and change them over to forms that use some kind of layout management so that DPI or font height changes can work without clipping. I suspect that this "inter-control" layout work would be far more complex in most applications than the "intra-control" work.

    Update: In 2016, the latest Delphi 10.1 Berlin is working well on my 150 dpi workstation.