How to best fix wrong text height in Lazarus with High DPI?

91 Views Asked by At

I have a bunch of TListBox components some of which define the OnDrawItem event in order to use colors (they also have Style=lbOwnerDrawVariable). My application is per-monitor DPI-aware (<DpiAware Value="True/PM_V2"/>). All my list boxes look fine unless I move my form to a monitor with a different DPI. Regular ListBoxes change their row height to accommodate a different font size, but ListBoxes with the OnDrawItem event fail to do so, resulting in text clipping if the DPI has increased, or a needlessly large row spacing if the DPI has decreased. For instance, here's what happens when going form 96 DPI to 120 DPI:

enter image description here

The bug persists until the content of a ListBox changes, new content is drawn with the correct row height.

My OnDrawItem handler for this list box looks like this:

procedure TForm1.ListDrawItem(Control: TWinControl; Index: Integer;
  ARect: TRect; State: TOwnerDrawState);
var
  ListBox: TListBox absolute Control;
  customColor: TColor;
begin
  customColor := clBlack;
  if Index = 1 then customColor := clBlue;

  ListBox.Canvas.FillRect(ARect);
  ListBox.Canvas.TextRect(ARect, ARect.Left, ARect.Top, ListBox.Items[Index]);
end;  

I found a workaround which consists in manually updating the line height of my colorized ListBoxes:

procedure TForm1.FormResize(Sender: TObject);
var
  ListHeight: Integer;
begin
  ListHeight := Canvas.GetTextHeight('|');
  ListBox1.ItemHeight := ListHeight;
  ListBox2.ItemHeight := ListHeight;
  //etc.
end; 

However, this requires me to keep track of colorized ListBoxes, and in general it looks like a hack. Is there a way to fix this issue in Lazarus 2.2.6 without adding code for each new ListBox?

0

There are 0 best solutions below