1

I would like to be able to change item's background to red when they are double clikced and make them stay that color so I can do something with only the red ones on FormClose for instance.(ex: OnClose delete only the red items) Is that possible with standard component?

Gab
  • 681
  • 4
  • 14
  • 27

1 Answers1

2

You need to owner-draw the ListBox. Set its Style property to either lbOwnerDraw, lbOwnerDrawVariable, or lbVirtualOwnerDraw, and then use its OnDrawItem event to draw the items however you want (in the case of lbOwnerDrawVariable, you will also have to provide an OnMeasureItem event handler). You will have to keep track of which items have been double-clicked, and then you can draw those items differently than the other items. For example:

type
  MyItem = record
    Text: String;
    DblClicked: Boolean;
  end;

MyItems: array of MyItem;

var
  Item: MyItem;
begin
  SetLength(MyItems, ...);

  MyItems[0].Text := 'Item Text';
  MyItems[0].DblClicked := False;

  ...

  for Item in MyItems do
    ListBox1.Items.Add(Item.Text);
end;

procedure TForm1.ListBox1DblClick(Sender: TObject);
var
  Pos: DWORD;
  Pt: TPoint;
  Index: Integer;
begin
  Pos := GetMessagePos;
  Pt.X := Smallint(LOWORD(Pos));
  Pt.Y := Smallint(HIWORD(Pos));
  Index := ListBox1.ItemAtPos(ListBox1.ScreenToClient(Pt), True);
  if Index <> -1 then
  begin
    MyItems[Index].DblClicked := True;
    ListBox1.Invalidate;
  end;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  if MyItems[Index].DblClicked then
  begin
    ListBox1.Canvas.Brush.Color := clRed;
    ListBox1.Canvas.Font.Color := clWhite;
  end else
  begin
    ListBox1.Canvas.Brush.Color := ListBox1.Color;
    ListBox1.Canvas.Font.Color := ListBox1.Font.Color;
  end;
  ListBox1.Canvas.FillRect(Rect);
  ListBox1.Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 2, MyItems[Index].Text);
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • But I need it to be OnDblClick event. Could you provide an example please? – Gab Oct 14 '13 at 23:22
  • The `OnDblClick` event cannot change the colors directly, however it can be used to keep track of which items have been double-clicked, and it can`Invalidate()` the ListBox to trigger redraws, and then the `OnDrawItem` even can draw the currently tracked double-clicked items using different colors as needed. – Remy Lebeau Oct 14 '13 at 23:23
  • What would you suggest to keep track of them? – Gab Oct 14 '13 at 23:25
  • Setting `MultiSelect` property allows to use the `Selected[ix]` property. Select by shift click. You can define a `OnDblClick` event to emulate a selection. – LU RD Oct 14 '13 at 23:25
  • @LURD That's interesting. How would I change the background color then? – Gab Oct 14 '13 at 23:30
  • Like this, [`How do I draw the selected list-box item in a different color?`](http://stackoverflow.com/questions/8563508/how-do-i-draw-the-selected-list-box-item-in-a-different-color). – LU RD Oct 14 '13 at 23:31
  • Great. I'm trying to emulate the selection by using ListBox.Selected[ListBox.ItemIndex]:=TRUE but it's not working though – Gab Oct 14 '13 at 23:34
  • Seems as a single click selects/deselects. Maybe this is enough. – LU RD Oct 14 '13 at 23:44