PiedSoftware 5 Posted 5 hours ago (edited) Hi I want to be able to expand a small modal dialog that offers the user just a combo box to the minimum size able to show all values in the dropdown list of a TComboBox. I wrote the following code to calculate the size required by the combobox: function MaxTextWidth(canvas: TCanvas; list: TStrings): integer; var s: string; begin result := 0; for s in list do result := Max(result, canvas.TextWidth(s)); end; procedure SetComboWidth(Combo: TComboBox); var width: integer; begin width := MaxTextWidth(Combo.Canvas, Combo.Items) + 26; // Include arrow button if Combo.Style = csDropDown then inc(width, 8); Combo.Width := width; end{ SetComboWidth}; It had the desired effect on my machine, a NUC box still on good ole' Windows 10. The users however on Windows 11 find that the calculated with is not enough. The longest values were clipped. I don't know if the OS is the problem. My machine doesn't let me update. Does this problem look familiar to anyone? -- Mark Edited 5 hours ago by PiedSoftware Share this post Link to post
PeaShooter_OMO 39 Posted 4 hours ago It is always a good idea to not hard code any widths related to the visual apsects of controls. They might change when the OS changes version. You have to get the width of the non-client area of a ComboBox so that you can add it your calculated MaxTextWidth to get a proper control width. But... ComboBox does not play nicely and getting its ClientWidth is not possible with functions like GetClientRect thus ComboBox does not have a properly calculated ClientWidth for it so you will have to make another plan to get it. There is a Win32 function called GetComboBoxInfo. It returns a record with details about the combobox like size of the control, the size and position of the button and size of position of the edit control in it. You will use the width of the edit control and deduct that from the width of the ComboBox and there you have the non-client area width. Just add that to the MaxTextWidth and you have the size the ComboBox should be. Remember to do these calculations and setting of the ComboBox size again when the Windows theme or settings change or the font changes. Share this post Link to post
MarkShark 27 Posted 2 hours ago Another possible issue is that when you use a control's canvas outside the paint event, the font of that canvas may not be set properly. It's good practice to set it explicitly with something like: Combo.Canvas.Font := Combo.Font; before calling TextWidth. Also note that you may have to scale any hard coded pixel values based on dpi. Share this post Link to post