Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

tElMainMenu scaling problems

Hello LMD team,

I find that tElMainmenu does not scale its top-level items properly when the font size is changed in code (I'm trying to support DPI-awareness).  The problem is easy to reproduce: 

procedure TMyForm.FormCreate(Sender: TObject);

I would be grateful for a fix or workaround.

Kind regards,
Arthur Hoornweg


  • 8 Comments sorted by Votes Date Added
  • edited October 2017 Posts: 0Vote Up0Vote Down

    Did you set SystemFont property to False?
  • Yes!  

    The font size is changed but the top-level menu items are cut off, the space isn't calculated correctly. 
  • After some research I found that the height of a menu bar cannot be changed at all. Microsoft suggests to use system menu font, and, actually, system font setting should be DPI aware.
  • Hi Eugene,

    the height is more or less OK, it is the *width* that is the problem. The text is much wider than the container.

    I'm trying to attach an example (test case) here.

  • Ok. I'll look. In my tests, the height was a problem.
  • Items width measuring is fixed. Items height - impossible as already noted.
  • Super!

    Thanks for your efforts - I have renewed my suscription today. 

    Kind regards,

  • The mainmenu item height scales perfectly fine for me (i use a trick for that).  See attached screenshots (one is at 96 dpi, the other at 175% under Windows 10).  

    I develop under Delphi XE and I use a few tricks to make my applications per-monitor DPI-Aware since Delphi's own method is fundamentally broken. The trick is to disable Delphi's scaling by forcibly creating all forms at 96 dpi and then re-scale them manually before they become visible and also whenever Windows sends a WM_Dpichanged message.

    - My applications have a per-monitor DPI-aware manifest.

    - My forms respond to the WM_NCCREATE message and call EnableNonClientDPIScaling() in the message handler, this tells Windows 10 to scale the non-client area which also fixes the menu height problem ...

    - My forms forcibly set screen.dpi to 96 in their overridden Constructor, then call the inherited Constructor, then restore screen.dpi to its original value.

    - In an overridden AfterConstruction I find out what the real DPI number of the form's monitor is, and if it is unequal to 96, I calculate the optimal new size for the form and do a "Perform( WM_Dpichanged,...).

    - The form needs a WM_Dpichanged message handler. In there, I temporarily set screen.dpi to 96, move and re-scale the form according to the parameters of the message, then I set form.PixelsPerinch to the new value and restore "screen.dpi" to its original value.   

    This works brilliantly.  Some details need attention. It's optically pleasing to maintain resources in a higher resolution and to scale these down (Lanczos3) to the desired resolution on the fly.  The only items that don't scale at all are toolbuttons and speedbuttons, I'm still working on that. Maybe maintaining separate image lists for various resolutions is an idea. 

Sign In or Register to comment.