Windows 11 introduced a new option that allows to customize the screen scale:
When a custom scaling is applied reading and writing form width and height behaves bad.
In particular, in my Delphi application, every time a form is closed I store in an INI file the form width and height, to restore them the next time the form is shown.
// store to file code
IniFile.WriteInteger('FORM','Width',AForm.Width);
IniFile.WriteInteger('FORM','Top',AForm.Top);
// restore from file code
StoredHeight:= IniFile.readInteger('FORM','Height',AForm.Height);
StoredWidth := IniFile.readInteger('FORM','Width',AForm.Width);
if StoredWidth >= Screen.Width then
AForm.Width := Screen.Width
else
begin
AForm.Width := StoredWidth;
if StoredLeft < 0 then
AForm.left := 0
else
AForm.left := StoredLeft;
end;
if StoredHeight >= Screen.Height then
AForm.Height := Screen.Height
else
begin
AForm.Height := StoredHeight;
if StoredTop < 0 then
AForm.Top := 0
else
AForm.Top := StoredTop;
end;
The problem is that when TForm.Height and TForm.Width are stored to file they are increased by the custom scaling percentage (or at least to a number close to it), while when the values are set they are correctly applied. As a consequence every time the form is shown it is bigger and bigger.
Is it normal that I must deal with scaling and I must compensate it (by dividing the values by the scale factor)? I would expect this is transparent to me.
Moreover does anyone know how to retrieve the custom scaling setting from the windows API? I googled unsuccessfully.
Thanks!

There is an improvement in Delphi 11.0 Alexandria. The IDE now fully supports high DPI scaling on high-resolution screens. This high DPI support includes support in the code editor, and when designing forms, both VCL and FMX. There is a setting to control the scaling in the VCL form designer and so you can set it to unscaled by default.
You have to compile your application to support high DPI (‘DPI aware’). If an application is ‘DPI unaware’, Windows will scale it up, but upscaling adds blurriness. It is much better if an app is ‘DPI aware’ so the scaling applied to its window(s) are crisply.
You can scale the VCL form designer to any DPI (any scale). This is done using the same scaling tech that the VCL uses when scaling itself at runtime. This setting is in Tools > Options > User Interface > Form Designer > High DPI. When you change it, you’ll need to close and reopen the form designer to have an effect.
By default, when you open a form, the form is designed at 96 DPI – that is, at 100%. One key bit of knowledge is that when a form is scaled, the Left, Height etc properties are changed. This is exactly the same as when you run an app and it is scaled; those values are multiplied by the screen scale.
Windows (and so the VCL) uses integer coordinates for its sizes and locations. This means that any scaling may not always be exactly precise. In practice, it’s fine when scaling once (such as when an app is run, and it scales up from the low-res coordinates with which it was designed.) It’s also fine scaling a few times, such as moving from one monitor to another after launching. It matters more when scaling many times. So it is fine to design at high DPI at any scale, and run even at a lower scale – the VCL will scale your app correctly – but it is important to avoid scaling over and over again, which will happen if every time you open a form in the designer it’s opened at a different DPI.
You can read more about the DPI Scaling, in the following embarcadero blog: https://blogs.embarcadero.com/new-in-rad-studio-11-high-dpi-ide-and-form-designing/
First thing to try, is to disable the Scaled property of each Form of your application (you can find this property on object inspector of the Form), and then test if the width and heigth values are written correctly. If this doesn't fix your problem, then I am suggesting some workarounds.
Here is a workaround, until embarcadero fixes this issue.
You can save the width and height values when closing the form, after you normalize them (using MulDiv function) depending of the dpi the end user has set.
The code would be something like this:
Although, you could try using
Monitor.PixelsPerInchinstead ofScreen.PixelsPerInch. That way it will work for cases when different custom scaling is applied in different monitors.Another workaroung, would be to read the custom scaling property from the registry, and save width and height values after normalizing them. The custom scaling property, is saved in the following registry entry:
HKEY_CURRENT_USER\Control Panel\Desktopin theLogPixelskey. This registry key controls the DPI scaling level in Windows 10 and 11.So the workaround is to read this registry key, and scale down (or up) the width and the height you are going to write to the ini file.
The code would be something like this:
I hope this workaround will help you, until embarcadero fixes this issue.