Drawing empty items in a TListBox. lazarus / 39-Graphics ---------------------------------------------------------------------- Bazzao · 2019-07-24 22:08 Searching around for a means of alternating background colour in a TListBox gave me lots of examples, and I ended up with this modification ... 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 procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;  ARect: TRect; State: TOwnerDrawState);begin  with (Control as TListBox).Canvas do begin    Brush.Style:=bsSolid;    if odSelected in State then      begin        Brush.Color:=clBlue;        Font.Color:=clWhite;      end    else    if Index=0 then      begin      Brush.Color:=clRed;        Font.Color:=clYellow;        Font.Style:=[fsbold,fsItalic];      end    else    if Index mod 2=1 then      begin        Brush.Color:=clSkyBlue;      end    else      begin        Brush.Color:=clMoneyGreen;      end;    FillRect(ARect);    Brush.Style:=bsClear;    TextOut(ARect.Left, ARect.Top, (Control as TListBox).Items[Index]);  end;end; But the above only draws active items. The problem is that my ListBox starts off empty and gradually fills from the top down, hence the Red background for item 0. How do I draw empty items, taking into account that the bottom display item may not be fully visible (ie cut off half height). Also I need to take into account that the list box will have a scroll bar and the last few items may only be visible. ---------------------------------------------------------------------- winni · 2019-07-24 22:52 There is no other way then to do a little swindle: Fill your listbox.items with spaces. If you got the next item for the box, than replace the space row with the new item. DrawItem takes only the existing items in account, so the loop goes from 0 to items.count - 1. So theres is no other way - I think -  than this. Winni ---------------------------------------------------------------------- Bazzao · 2019-07-24 23:16 Yes, I actually thought something similar as a possible solution. I do like your term "swindle"  My thoughts were along the line of: 1) An initial fill of spaced items; 2) On FormShow, drawing then clearing the ListBox. ... But was thinking that any future redraw would undo what I have done. Your last paragraph has given me much information. Might give it a go. ---------------------------------------------------------------------- Bazzao · 2019-07-24 23:26 Nope  I tried adding 100 spaced items in FormShow, then * Clearing; * Deleting item 0, 100 times. After each, the listbox went blank. However retaining the 100 spaced items worked. My next step is to determine how many items are in view and any spaced items out of view are deleted. ---------------------------------------------------------------------- Bazzao · 2019-07-25 00:04 I am getting a division by zero error: 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 procedure TForm1.FormShow(Sender: TObject);var I,J:integer;begin  for I:=1 to 99 do    ListBox1.Items.Add(' ');  ListBox1.Items.Add('GgIiJjKkLlMPpQqTtWYy');  ListBox1.Repaint;  J:=ListBox1.Height div ListBox1.ItemHeight;  for I:=J+1 to 100 do    ListBox1.Items.Delete(J);end;  The last item added 'GgIiJjKkLlMPpQqTtWYy' should give me a height including descenders. ---------------------------------------------------------------------- Bazzao · 2019-07-25 01:30 I found the cause of ItemHeight being 0. It is not set when Style is lbOwnerDrawFixed. So here is the solution. 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 procedure TForm1.FormShow(Sender: TObject);var I,J:integer;begin  ListBox1.Style:=lbStandard;  ListBox1.Items.Add('GgIiJjKkLlMPpQqTtWYy');  ListBox1.Repaint;  gItemHeight:=ListBox1.ItemHeight;  if gItemHeight=0 then    gItemHeight:=15; // Just in case.  ListBox1.Style:=lbOwnerDrawFixed;  ListBox1.Clear;  for I:=1 to 100 do    ListBox1.Items.Add(' ');  ListBox1.Repaint;  J:=ListBox1.Height div gItemHeight;  for I:=J+1 to 100 do    ListBox1.Items.Delete(J);  ListBox1.Repaint;end; gItemHeight is a global variable, in case I need to use the ItemHeight elsewhere. ---------------------------------------------------------------------- kronos · 2019-12-28 14:48 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 procedure TForm1.ListadoDrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState);var  fondo: TColor;begin  if (Index mod 2 = 0) then fondo:=$00FE8000 else fondo:=$00EFCF89;   //2 RGB colors   Listado.Canvas.Brush.Color:=fondo; Listado.Canvas.FillRect(ARect);   //item Rect          Listado.Canvas.Font.Bold:=True; Listado.Canvas.Font.Color:=clWhite;    //item Text  Listado.Canvas.TextRect(ARect, 5, ARect.Top+2, Listado.Items[Index]);   ARect.Top:=ARect.Top+ARect.Height; ARect.Height:=Listado.Height-ARect.Top;  //fill down  Listado.Canvas.Brush.Color:=clGray;  Listado.Canvas.FillRect(ARect);end;