Recent

Author Topic: Strange behaviour of TCheckBox and Windows Menu settings  (Read 5335 times)

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #15 on: September 25, 2021, 10:52:31 am »
LCL scaling and DPI are disabled in my application. All the components keeps their size and positions, only checkboxes changes.

It's not a matter of improving elegibity or not. Lazarus checkboxes have issue with ease of access. I can't develop applications and just say the users "hey, don't use ease of access because you can screw the UI layout" :D

I've checked my old lazarus applications, starting from 2016 and all of them have the same issues with checkboxes.
My older Delphi applications works without issue, so it's something related to Lazarus only.



wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #16 on: September 25, 2021, 11:01:55 am »
LCL scaling and DPI are disabled in my application. All the components keeps their size and positions, only checkboxes changes.
You're warned that your users with super-high-res retina displays of 300% or more will complain that they cannot hit the tiny 16x16 icons any more.

I've checked my old lazarus applications, starting from 2016 and all of them have the same issues with checkboxes.
My older Delphi applications works without issue, so it's something related to Lazarus only.
Just checked with Delphi XE 10.3: Delphi ignores the "ease-of-access" setting completely. The font does not change between 100% and 200% ease-of-access. Neither does the height of a checkbox change.

Well, Delphi has hard-coded fonts and font sizes. I tried to simulate that with Lazarus: I put a TLabel, a TCombobox, a TRadioButton and a TCheckbox on a form and set their Font.Size to 9 (rather than the default 0). When I now change the "Ease of access" font size the fonts in all these controls remain the same, but the height occupied by the Checkbox and RadioButton increases. This is strange and should not occur. Is this your issue?

« Last Edit: September 25, 2021, 11:23:33 am by wp »

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #17 on: September 25, 2021, 11:56:41 am »
Quote
I tried to simulate that with Lazarus: I put a TLabel, a TCombobox, a TRadioButton and a TCheckbox on a form and set their Font.Size to 9 (rather than the default 0). When I now change the "Ease of access" font size the fonts in all these controls remain the same, but the height occupied by the Checkbox and RadioButton increases. This is strange and should not occur. Is this your issue?

Yes, exactly.
I've tryed with font size 0 or a set value, but the result is the same. Not matter what i do, the height of the checkbox is always dictacted by the Ease of access.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #18 on: September 25, 2021, 12:48:41 pm »
Of course, you can turn off the checkbox AutoSize since you always have the same font size. Delphi, BTW, does not have this property at all and thus works always with AutoSize off.

Just tested: when Checkbox.AutoSize is false, and Checkbox.Font.Size = (some non-zero value), then the checkbox bounds and its font do not change at all when the ease-of-access setting is modified.

Nevertheless, the dependence of the auto-sized TCheckbox.Height with non-zero Font.Size on ease-of-access setting is in error and should be addressed since under these conditions nothing changes in the checkbox with ease-of-access; it looks as if the checkbox uses the default font (Font.Size=0) as reference.

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #19 on: September 25, 2021, 01:01:58 pm »
Just tested and yes, this workaround works. Having autosize off and manually setting the font size make the height of the checkbox stable.
This is not optimal, because manually set the font size disable the parent font property, but i can dodge around it.

Thank you for the tip and your patience !

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #20 on: September 25, 2021, 01:18:21 pm »
The procedure GetPreferredSize is responsible for determining the size of an auto-sized control. In case of the Checkbox, this is implemented in the widgetset (unit lcl/interface/win32/win32wsstdctrls) and consists of two parts: determination of the text height and determination of the checkbox symbol height - the larger one determines the overall autosize height.

Code: Pascal  [Select][+][-]
  1. class procedure TWin32WSCustomCheckBox.GetPreferredSize(const AWinControl: TWinControl;
  2.   var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);
  3. var
  4.   iconHeight: integer;
  5. begin
  6.   if MeasureText(AWinControl, AWinControl.Caption, PreferredWidth, PreferredHeight) then
  7.   begin
  8.     Inc(PreferredWidth, GetSystemMetrics(SM_CXMENUCHECK));
  9.     // pixels spacing between checkbox and text
  10.     if ThemeServices.ThemesEnabled then
  11.       Inc(PreferredWidth, 4)
  12.     else
  13.       Inc(PreferredWidth, 6);
  14.     iconHeight := GetSystemMetrics(SM_CYMENUCHECK);
  15.     if iconHeight > PreferredHeight then
  16.       PreferredHeight := iconHeight;
  17.     if WithThemeSpace then
  18.     begin
  19.       Inc(PreferredWidth, 1);
  20.       Inc(PreferredHeight, 4);
  21.     end;
  22.   end;
  23. end;      

Debugged into this procedure I found that the text height (MeasureText(... preferredHeight)) remains constant when the font of the checkbox is nonzero and when ease-of-access changes. The iconHeight, however, does increase with the ease-of-access percentage, although it is painted always at the same height. Therefore the issue is in the call to GetSystemMetrics(SM_CYMENUCHECK) in which windows reports a value dependent on the system font. I think replacing this by a ThemeServices call could fix the issue.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #21 on: September 25, 2021, 07:28:57 pm »
Wrote a bug report so that the issue is not forgotten.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #22 on: September 25, 2021, 10:18:46 pm »
I was able to fix the issue based on the analysis that I gave above and committed the fix to main. If you don't use Lazarus main you can patch it easily yourself:
  • Load file lcl/interfaces/win32/win32wsstdctrls.pp into Lazarus
  • Find the class procedure TWin32WSCustomCheckbox.GetPreferredSize and replace it by the following code. Afterwards recompile the IDE and test if it works as expected now
Code: Pascal  [Select][+][-]
  1. class procedure TWin32WSCustomCheckBox.GetPreferredSize(const AWinControl: TWinControl;
  2.   var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);
  3. var
  4.   dx: Integer;  // pixel spacing between checkbox and text
  5.   iconHeight: integer;
  6.   iconWidth: Integer;
  7.   details: TThemedElementDetails;
  8. begin
  9.   if MeasureText(AWinControl, AWinControl.Caption, PreferredWidth, PreferredHeight) then
  10.   begin
  11.     if ThemeServices.ThemesEnabled then
  12.     begin
  13.       dx := 4;
  14.       if AWinControl is TRadioButton then
  15.         details := ThemeServices.GetElementDetails(tbRadioButtonCheckedNormal)
  16.       else
  17.         details := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal);
  18.       with ThemeServices.GetDetailSize(details) do
  19.       begin
  20.         iconWidth := CX;
  21.         iconHeight := CY;
  22.       end;
  23.     end else
  24.     begin
  25.       dx := 6;
  26.       iconWidth := GetSystemMetrics(SM_CXMENUCHECK);
  27.       iconHeight := GetSystemMetrics(SM_CYMENUCHECK);
  28.     end;
  29.     Inc(PreferredWidth, iconWidth + dx);
  30.     if iconHeight > PreferredHeight then
  31.       PreferredHeight := iconHeight;
  32.     if WithThemeSpace then
  33.     begin
  34.       Inc(PreferredWidth, 1);
  35.       Inc(PreferredHeight, 4);
  36.     end;
  37.   end;
  38. end;

This code fixes also the issue that the autosized width of the checkbox was too large when the ease-of-access factor is greater than 100%. And it fixes the same issues that could be observed for TRadioButton and TToggleBox (the latter is not yet perfect because it takes a checkbox width into account in width calculation - but since fixing this would break existing code I did not touch it).

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #23 on: September 25, 2021, 11:46:07 pm »
Thank you very much for your help.

For my actual software i've already implemented the workaround, but i will use the fix for my future projects.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #24 on: September 26, 2021, 12:14:42 am »
But I would like you to test the fix. There were some misunderstandings initially, and I really don't know whether it fixes your issue. I need confirmation before I dare to backport the changed code to the fixes_2_2 branch.

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Strange behaviour of TCheckBox and Windows Menu settings
« Reply #25 on: September 26, 2021, 09:32:57 am »
I've tested the fix. Yes, it fixes the issue.

Now the checkboxes remain stable both in the IDE and in the compiled executable regardless of the Ease of Access setting without having to do the workaround.
« Last Edit: September 26, 2021, 11:09:06 am by Tharon »

 

TinyPortal © 2005-2018