I am using ListBox.Style := lbOwnerDrawFixed
with OnDrawItem
:
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
begin
with ListBox1.Canvas do begin
Brush.Color := clWhite;
Pen.Color := clWhite;
FillRect(ARect);
end;
end;
It should give an empty space to draw anything I want, but it doesn't. When the item is focued I still can see a dotted rectangle around it.
How to remove the rectangle?
The focus rectangle is drawn by the VCL (*) in TCustomListBox.CNDrawItem
after the OnDrawItem
event handler returns.
procedure TCustomListBox.CNDrawItem(var Message: TWMDrawItem);
...
..
if Integer(itemID) >= 0 then
DrawItem(itemID, rcItem, State) //-> calls message handler
else
FCanvas.FillRect(rcItem);
if (odFocused in State) and not TStyleManager.IsCustomStyleActive then
DrawFocusRect(hDC, rcItem); //-> draws focus rectangle
..
..
Whatever you draw in the event handler will later get focused by the VCL.
But notice that VCL use DrawFocusRect
to draw the focus rectangle:
Because DrawFocusRect is an XOR function, calling it a second time with the same rectangle removes the rectangle from the screen.
So just call DrawFocusRect
yourself and let VCL's call erase it:
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
begin
with ListBox1.Canvas do begin
Brush.Color := clWhite;
Pen.Color := clWhite;
FillRect(ARect);
if odFocused in State then // also check for styles if there's a possibility of using ..
DrawFocusRect(ARect);
end;
end;
WM_DRAWITEM
message. But the default window procedure is not called for a list box in VCL's handling of the message.