user1175743
user1175743

Reputation:

How to remove the dotted focus line from a TCustomListBox?

I have a TCustomListBox derived control where I override the DrawItem procedure to give it a better look and feel.

One thing I have noticed, and it seems to affect the standard TListBox as well is that when the control is focused and there are no items it still draws the dotted focus line.


Here is a standard, unchanged TListBox with no items:

enter image description here

The dotted line is drawn when the control is focused (ie, clicked)


Now with my custom control the dotted lines still appear, only differently:

enter image description here


If my custom listbox contains items however, then no dotted lines are drawn:

enter image description here


Here is the main code for the custom listbox:

type
  TMyListBox = class(TCustomListBox)
  private
    FFillColor: TColor;
    FFrameColor: TColor;
  protected
    procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

{ TMyListBox }

constructor TMyListBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FFillColor  := GetShadowColor(clMenuHighlight, 60);
  FFrameColor := GetShadowColor(clMenuHighlight, -20);

  Style := lbOwnerDrawVariable;
end;

destructor TMyListBox.Destroy;
begin
  inherited Destroy;
end;

procedure TMyListBox.DrawItem(Index: Integer; Rect: TRect;
  State: TOwnerDrawState);
var
  Offset: Integer;
begin
  inherited;

  with (Self as TMyListBox) do
  begin
    Canvas.FillRect(Rect);

    if (odSelected in State) then
    begin
      Canvas.Pen.Color := FFrameColor;
      Canvas.Brush.Color := FFillColor;
      Canvas.Rectangle(Rect);
    end
    else
    begin
      Canvas.Pen.Color := Color;
      Canvas.Brush.Color := Color;
      Canvas.Rectangle(Rect);
    end;

    Offset := (Rect.Bottom - Rect.Top - Canvas.TextHeight(Items[Index])) div 2;
    Canvas.Brush.Style := bsClear;
    Canvas.Font.Color := Font.Color;
    Canvas.TextOut(Rect.Left + Offset + 2, Rect.Top + Offset, Items[Index]);
  end;
end;

What else do I need to do in order to remove the dotted focus line from the control?

Upvotes: 1

Views: 1342

Answers (1)

Sertac Akyuz
Sertac Akyuz

Reputation: 54822

You can add a handler for WM_SETFOCUS to prevent processing when there are no items:

procedure TMyListBox.WMSetFocus(var Message: TWMSetFocus);
begin
  Message.Result := 0;
  if Count <> 0 then
    inherited;
end;

Upvotes: 2

Related Questions