Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8373789
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T14:46:03+00:00 2026-06-09T14:46:03+00:00

What would be the most simple and clean way to show a focused/selected listbox

  • 0

What would be the most simple and clean way to show a focused/selected listbox item with a Office XP style?

See this sample image to show the idea more clearer:

enter image description here

I think I need to set the Listbox Style to either lbOwnerDrawFixed or lbOwnerDrawVariable and then modify the OnDrawItem event?

This is where I am stuck, I am not really sure what code to write in there, so far I tried:

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  with (Control as TListBox).Canvas do
  begin
    if odSelected in State then
    begin
      Brush.Color := $00FCDDC0;
      Pen.Color   := $00FF9933;
      FillRect(Rect);
    end;

    TextOut(Rect.Left, Rect.Top, TListBox(Control).Items[Index]);
  end;
end;

I should of known that would not work, I get all kind of funky things going on:

enter image description here

What am I doing wrong, more importantly what do I need to change to make it work?

Thanks.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T14:46:05+00:00Added an answer on June 9, 2026 at 2:46 pm

    You forgot to paint the items for different states. You need to determine in what state the item currently is and according on that draw it.

    What you have on your picture you can get this way. However this doesn’t looks well if you have enabled multiselect and select more than one item:

    procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    var
      Offset: Integer;
    begin
      with (Control as TListBox) do
      begin
        Canvas.Font.Color := Font.Color;
        if (odSelected in State) then
        begin
          Canvas.Pen.Color := $00FF9932;
          Canvas.Brush.Color := $00FDDDC0;
        end
        else
        begin
          Canvas.Pen.Color := Color;
          Canvas.Brush.Color := Color;
        end;
        Canvas.Rectangle(Rect);
        Canvas.Brush.Style := bsClear;
        Offset := (Rect.Bottom - Rect.Top - Canvas.TextHeight(Items[Index])) div 2;
        Canvas.TextOut(Rect.Left + Offset + 2, Rect.Top + Offset, Items[Index]);
      end;
    end;
    

    And the result with ItemHeight set to 16:

    enter image description here

    Bonus – continuous selection:

    Here is a tricky solution implementing a continuous selection. The principle is to draw the item like before but then overdraw the item’s border top and bottom lines with the lines of a color depending on selection state of the previous and next item. Except that, must be rendered also outside of the current item, since the item selection doesn’t naturally invoke neighbour items to be repainted. Thus the horizontal lines are painted one pixel above and one pixel below the current item bounds (colors of these lines depends also on the relative selection states).

    Quite strange here is the use of item objects to store the selected state of each item. I did that, because when using a drag & drop item selection, the Selected property doesn’t return the real state until you release the mouse button. Fortunately, the OnDrawItem event of course fires with the real state, so as a workaround I’ve used storing of these states from the OnDrawItem event.

    Important:

    Notice, that I’m using the item objects to store the actual selection state, so be careful, and when you’re using item objects for something else, store this actual states e.g. into an array of Boolean.

    procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    const
      SelBackColor = $00FDDDC0;
      SelBorderColor = $00FF9932;
    var
      Offset: Integer;
      ItemSelected: Boolean;
    begin
      with (Control as TListBox) do
      begin
        Items.Objects[Index] := TObject((odSelected in State));    
    
        if (odSelected in State) then
        begin
          Canvas.Pen.Color := SelBorderColor;
          Canvas.Brush.Color := SelBackColor;
          Canvas.Rectangle(Rect);
        end
        else
        begin
          Canvas.Pen.Color := Color;
          Canvas.Brush.Color := Color;
          Canvas.Rectangle(Rect);   
        end;
    
        if MultiSelect then
        begin
          if (Index > 0) then
          begin
            ItemSelected := Boolean(ListBox1.Items.Objects[Index - 1]);
            if ItemSelected then
            begin
              if (odSelected in State) then
              begin
                Canvas.Pen.Color := SelBackColor;
                Canvas.MoveTo(Rect.Left + 1, Rect.Top);
                Canvas.LineTo(Rect.Right - 1, Rect.Top);
              end
              else
                Canvas.Pen.Color := SelBorderColor;
            end
            else
              Canvas.Pen.Color := Color;
            Canvas.MoveTo(Rect.Left + 1, Rect.Top - 1);
            Canvas.LineTo(Rect.Right - 1, Rect.Top - 1);
          end;
    
          if (Index < Items.Count - 1) then
          begin
            ItemSelected := Boolean(ListBox1.Items.Objects[Index + 1]);
            if ItemSelected then
            begin
              if (odSelected in State) then
              begin
                Canvas.Pen.Color := SelBackColor;
                Canvas.MoveTo(Rect.Left + 1, Rect.Bottom - 1);
                Canvas.LineTo(Rect.Right - 1, Rect.Bottom - 1);
              end
              else
                Canvas.Pen.Color := SelBorderColor;
            end
            else
              Canvas.Pen.Color := Color;
            Canvas.MoveTo(Rect.Left + 1, Rect.Bottom);
            Canvas.LineTo(Rect.Right - 1, Rect.Bottom);
          end;
        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;
    

    And the result:

    enter image description here

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have this string: B82V16814133260 what would be the most efficient way to get
What would be the most efficient way to clean a user input that is
What would be the most efficient way of counting the number of times a
What would be the most elegant and efficient way of finding/returning the first list
I have a list of checkboxes like you would see in most email clients
We've got a multi-agent Java environment where different agent would most likely produce all
Most people would agree that internationalizing an existing app is more expensive than developing
What would be the most sensible choice for building a socket server application, assuming
I would assume that most User-defined Exceptions are for Business Logic level exceptions, but
In a nutshell: what sort of applications would be benefit most from the dashboard

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.