Strange behaviour of TCheckBox and Windows Menu settings lazarus / 31-LCL ---------------------------------------------------------------------- Tharon · 2021-09-22 16:02 Hello, i've encountered a strange issue with check boxes and the font size setting of Windows. I have recentely purchased a 1440p monitor, so i've changed various font size of windows to be more readable. To my suprise, if i change the font size for the menu setting the check boxe are affected too, changing their height and making them collide with vertically adjacent components. There is a way to prevent this to happen ? ---------------------------------------------------------------------- Tharon · 2021-09-22 16:50 This is an example, from a tool i made some time ago. In the left is when the tool is launched with the standard menu font size (9) and on the right is when the tool is launcher with the menu font size incresed (12). Higher font size make the checkboxes go even lower, even making them disappear from the form. ---------------------------------------------------------------------- dseligo · 2021-09-23 05:55 In Project options check if you selected 'Use LCL scaling (High-DPI)' and 'DPI awareness' on. ---------------------------------------------------------------------- Tharon · 2021-09-23 08:47 Both are off. Anyway isn't related to DPI, the DPI of my sistem is set a 100%. ---------------------------------------------------------------------- Tharon · 2021-09-24 18:51 After some test it seems the height of the Tcheckbox is fixed and depends on the system theme. Apparently can't be changed in Lazarus, both in design or runtime. Don't know if this is a bug or it's caused by Windows. ---------------------------------------------------------------------- wp · 2021-09-24 20:15 I don't understand these screenshots. You say the left one is with font size 9, and the right one is with font size 12. But the texts in both images have the same size. Please post unmanipulated screenshots. Do you work with auto-sizing and anchors? You must if you change fonts. What looks correct with one font will be awfully off with another font otherwise. It seems to me that the radiogroup is not auto-sized. Usually AutoFill=true and AutoSize=true are the correct settings for a radiogroup. ---------------------------------------------------------------------- Tharon · 2021-09-24 21:36 The screenshots are not manipulated, i've only put them one near each other. The font size i was refering isn't the one of the text, but the size of the "menu" font in windows. As i've said in my first post, i've changed the menu font size from the Windows theme settings to have more readable menu text in Windows. After doing this the check boxes of all my lazarus programs changed size too, even at design time, even already compiled one. No DPI have been changed in my system, and i'm not changing font in the software. The setting i'm talking about is the one in the screenshot. The two screenshot shows the same program (not two different version, it's the same executable) running with the two windows menu settings. The issue isn't the radiogroup not autosized... the individuals checkboxes height of the checkboxed changed accordly to the Windows menu text size. It happens on every checkbox, not only the ones inside a radiogroup. ---------------------------------------------------------------------- wp · 2021-09-24 21:39 OK, I understand now. Which Windows version is this? I've not seen a possibility to change the menu font for a long time (or it's buried deeply in Windows 10). Does the RadioGroup have AutoFill=true and AutoSize=true? ---------------------------------------------------------------------- Tharon · 2021-09-24 21:53 Windows 7, but happen in Windows 10 too if the system font is enlarged in the "ease of access" settings. ---------------------------------------------------------------------- Tharon · 2021-09-24 22:12 Here. This is Lazarus with the program launched first with the default Windows menu text size, and then with increased Windows menu text size. I didn't change anything, only launched lazarus and loaded the project file. The size of the checkbox height automatically changed from 19 to 25 and can't be manually resized. This happen on the compiled executable too. It doesn't matter if i compiled it when the height is 19, if i change the Windows menu text size the checkbox height changes too. ---------------------------------------------------------------------- wp · 2021-09-24 22:43 The height of the checkbox is not the problem when you make sure that the position of the items in the groupbox adjusts automatically when the font size changes. In the attached demo I am using a Groupbox and placed some checkboxes into it. The checkboxes were not positioned with the mouse but by means of the ChildSizing property of the Groupbox - look at the settings in the Object Inspector. This way the checkboxes change their position with font size. The Groupbox itself has its AutoSize property set to true and thus can adjust its size to changes in text length and item count. Another way to achieve this is by using the AnchorEditor. I copied the same groupbox twice and changed the font size from 0 (default), to 12 and 16. Since the layout is auto-adjusting there is no overlap. PS. I also tried a TCheckGroup which uses ChildSizing internally as well. But this does not work very well - TCheckgroup is quite buggy... ---------------------------------------------------------------------- Tharon · 2021-09-25 00:04 This is the look of your example if i set the windows menu text size at 24. I didn't changed the font size with lazarus, i've only compiled it and then changed the windows theme settings. The height of each Checkbox grow and go outside the form. ---------------------------------------------------------------------- wp · 2021-09-25 08:00 I did not want to confuse you with the AnchorEditor and thus did not auto-size the form. You must set the form's AutoSize to true. In order to avoid all controls jumping to the upper-left corner you must anchor them so that they cannot be moved with the mouse any more: * Open the Anchor Editor. * Select the left groupbox. Anchor its left side to the left side of the form, and its top side to the top side of the form. Adjust the distance to the form by specifying appropriate BorderSpacing values. * Select the center groupbox. Anchor its left side to the right side of the left groupbox, anchor its top side to the top of the form. * Select the right groupbox. Anchor its left side to the right side of the center groupbox, anchor its top side to the top of the form. * Set the form's AutoSize to true. * You wont see a difference, but at runtime the size of the form is adjusted such that it always encloses the three groupboxes. I am attaching the project in this state, as well as two screenshots taken with "Ease-of-access" setting to 100% and 225%, respectively. In case that all this is not working for you: what is your Lazarus/FPC version? What are the DPI-settings on your two systems? ---------------------------------------------------------------------- Tharon · 2021-09-25 08:14 In your second screenshot the checkbox height changed. This is exactly what i want to avoid. Checkboxes should not change at all if the ease of access is modified, or the component is not reliable. The program UI should remain the same on every system, regardless of the Windows settings. Is not a matter of keep the boxes inside the form or the radiogroup, but keep them in their exact place. ---------------------------------------------------------------------- wp · 2021-09-25 08:25 Quote from: Tharon on September 24, 2021, 11:53:18 pm happen in Windows 10 too if the system font is enlarged in the "ease of access" settings. Be careful with this method of improving legibility of your applications. It is a system-wide settings and most programs cannot handle this correctly, not even the Windows explorer - see screenshot taken from the Explorer at 255% setting. It is better to change the dpi of the monitor. In older Windows, the correspondig settings were named "normal fonts", "large fonts" or similar, in Win 10 it is on the "Display" page, "Change the size of apps and text" (or similar, translated from German). It is a system- wide setting, too, but handled by many programs correctly. Lazarus takes care of it by means of LCLScaling (which - as you wrote - is turned off in your application. Why? No good idea...). ---------------------------------------------------------------------- Tharon · 2021-09-25 08:52 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" 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 · 2021-09-25 09:01 Quote from: Tharon on September 25, 2021, 10:52:31 amLCL 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. Quote from: Tharon on September 25, 2021, 10:52:31 amI'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? ---------------------------------------------------------------------- Tharon · 2021-09-25 09:56 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 · 2021-09-25 10:48 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 · 2021-09-25 11:01 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 · 2021-09-25 11:18 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i class procedure TWin32WSCustomCheckBox.GetPreferredSize(const AWinControl: TWinControl;  var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);var  iconHeight: integer;begin  if MeasureText(AWinControl, AWinControl.Caption, PreferredWidth, PreferredHeight) then  begin    Inc(PreferredWidth, GetSystemMetrics(SM_CXMENUCHECK));    // pixels spacing between checkbox and text    if ThemeServices.ThemesEnabled then      Inc(PreferredWidth, 4)    else      Inc(PreferredWidth, 6);    iconHeight := GetSystemMetrics(SM_CYMENUCHECK);    if iconHeight > PreferredHeight then      PreferredHeight := iconHeight;    if WithThemeSpace then    begin      Inc(PreferredWidth, 1);      Inc(PreferredHeight, 4);    end;  end;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 · 2021-09-25 17:28 Wrote a bug report so that the issue is not forgotten. ---------------------------------------------------------------------- wp · 2021-09-25 20:18 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 LazarusFind the class procedure TWin32WSCustomCheckbox.GetPreferredSize and replace it by the following code. Afterwards recompile the IDE and test if it works as expected nowCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i class procedure TWin32WSCustomCheckBox.GetPreferredSize(const AWinControl: TWinControl;  var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);var  dx: Integer;  // pixel spacing between checkbox and text  iconHeight: integer;  iconWidth: Integer;  details: TThemedElementDetails;begin  if MeasureText(AWinControl, AWinControl.Caption, PreferredWidth, PreferredHeight) then  begin    if ThemeServices.ThemesEnabled then    begin      dx := 4;      if AWinControl is TRadioButton then        details := ThemeServices.GetElementDetails(tbRadioButtonCheckedNormal)      else        details := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal);      with ThemeServices.GetDetailSize(details) do      begin        iconWidth := CX;        iconHeight := CY;      end;    end else    begin      dx := 6;      iconWidth := GetSystemMetrics(SM_CXMENUCHECK);      iconHeight := GetSystemMetrics(SM_CYMENUCHECK);    end;    Inc(PreferredWidth, iconWidth + dx);    if iconHeight > PreferredHeight then      PreferredHeight := iconHeight;    if WithThemeSpace then    begin    Inc(PreferredWidth, 1);      Inc(PreferredHeight, 4);    end;  end;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 · 2021-09-25 21:46 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 · 2021-09-25 22:14 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 · 2021-09-26 07:32 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.