Author: Tomas Rutkauskas
I have a TListBox with style lbOwnerDrawVariable. I want to draw some text indented
10 pixels from the left (this is no problem). However, I also want it so the
highlighting color and focus rectangle are indented as well (so the 10 pixel margin
is completely blank, no matter what items are selected). I can't seem to do this
... the focus rectangle always seems to extend all the way to the left. How do I
get around this?
Answer:
The problem is that the control as coded draws the focus rectangle after your owner
drawing code has completed. To override that you have to make a new control
descending from TListbox (or TCustomlistbox) and give it a handler for the
CN_DRAWITEM message. Here you need to duplicate what the TCustomlistbox.CNDrawItem
method does:
1 2 procedure TMyListBox.CNDrawItem(varmessage: TWMDrawItem);
3 var4 State: TOwnerDrawState;
5 begin6 withmessage.DrawItemStruct^ do7 begin8 State := TOwnerDrawState(LongRec(itemState).Lo);
9 Canvas.Handle := hDC;
10 Canvas.Font := Font;
11 Canvas.Brush := Brush;
12 if (Integer(itemID) >= 0) and (odSelected in State) then13 begin14 Canvas.Brush.Color := clHighlight;
15 Canvas.Font.Color := clHighlightText
16 end;
17 if Integer(itemID) >= 0 then18 DrawItem(itemID, rcItem, State)
19 else20 Canvas.FillRect(rcItem);
21 if odFocused in State then22 begin23 Inc(rcItem.left, 10); {this is the change}24 DrawFocusRect(hDC, rcItem);
25 end;
26 Canvas.Handle := 0;
27 end;
28 end;