Search code examples
user-interfacedelphihighdpi

How to correctly design a Delphi application UI that is High DPI aware (4k ready)?


For the fist time I have some problems creating a "complex" UI with delphi. I use a 4K monitor for development & testing and I have some scaling issues.

My app use a 2 column design, think of a diff view under a source control where you have a left pane and a right pane that mirror themselves component wise but the content (text) of these components are different.

To give you an idea I do this on the form resize:

edtFixExifLeftFile.Width := Floor((pnlFixExifTop.ClientWidth - (bbpFixExifBrowseLeft.Width * 2 + 42)) / 2);
bbpFixExifBrowseLeft.Left := edtFixExifLeftFile.Left + edtFixExifLeftFile.Width + 5;

edtFixExifRightFile.Left := bbpFixExifBrowseLeft.Left + bbpFixExifBrowseLeft.Width + 16;
edtFixExifRightFile.Width := edtFixExifLeftFile.Width;
bbpFixExifBrowseRight.Left := edtFixExifRightFile.Left + edtFixExifRightFile.Width + 5;

This way both columns take 50% of the space. This is pixel perfect when used in a HD environment (1080p) but in a 4K environment the scaling (my TForm.Scaled = True) completely "eats" one of the margins (I use 8px margins and the scaling take about 9px more than expected). This make the look wrong in 4K (the right TEdit overflow the TForm a bit).

How can I create a pixel perfect UI in HD and 4K environments? What is the right way to code my component resize?

I use the latest version of Delphi (10.3) and I don't use fancy components (only "stock" VCL).


Solution

  • After reading a good tutorial by Žarko Gajić I ended doing this:

    Pad := MulDiv(8, Monitor.PixelsPerInch, 96);
    grdpnlCover.Left := pnlCoverImage.Left + pnlCoverImage.Width + Pad;
    

    Where 8 is the unscaled value and 96 is the DPI the form was designed under.