Solved

Make A Combo Box List With MultipleColors?

Posted on 2000-03-21
18
357 Views
Last Modified: 2010-04-04
Is it possible to make the entries
in a combo box list different colors?
For instance if the combo box has
Fred, Wilma, and Scoobe as choices
how would I make Scoobe a different color than Fred and Wilma?
0
Comment
Question by:CHORN
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
  • 3
  • +3
18 Comments
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2642209
You can provide your own item drawer by setting the style to csOwnerDrawFixed and adding this event handler:

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  if Index = 1 then
    Combobox1.canvas.font.color := clRed
  else
    Combobox1.canvas.font.color := clBlack;
  Combobox1.canvas.textout(rect.left + 2, rect.top + 2, Combobox1.items[index]);
end;

This is incomplete as it does not draw the focus rectangle etc, but it gives you a start...

Cheers,

Raymond.
0
 
LVL 17

Accepted Solution

by:
inthe earned 150 total points
ID: 2642230
hi,

set the style to csownderdrawfixed in object inspector then :

procedure TForm1.FormCreate(Sender: TObject);
begin
 with ComboBox1.Items do
 begin
    Add('Fred');
    Add('Wilma');
    Add('Barney');
    Add('Betty');
    Add('Bam Bam');
   end;
end;

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
itemstr : string;
colors : array[0..4]of string;
 begin
colors[0] := inttostr(clRed);
colors[1] := inttostr(clBlue);
colors[2] := inttostr(clFuchsia);
colors[3] := inttostr(clTeal);
colors[4] := inttostr(clGray);
 with Control as tComboBox,Canvas do begin
  Brush.Color := clWhite;
   FillRect(Rect);
   InflateRect(Rect,-2,-2);
    Brush.Color := StrToInt(colors[Index]);
    Brush.Style := bsBDiagonal;
   FillRect(Rect);
   itemStr := ComboBox1.Items.Strings[Index];
    DrawText(Combobox1.Canvas.Handle,pchar(itemstr),Length(itemstr),
      Rect, DT_LEFT and DT_VCENTER and DT_SINGLELINE);
   end;
 end;

Regards Barry
0
 
LVL 2

Expert Comment

by:kubeerja
ID: 2642291
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
const CharOffset = 2;
begin
  with ComboBox1.Canvas do
  begin
      if ComboBox1.Items[index]='Scoobe'  then
      begin
        brush.Color:= clTeal ;
        font.color := clWhite ;
      end
      else
      begin
        brush.Color:= clYellow ;
        font.color := clRed ;
      end;
    FillRect(Rect);
    textout(rect.left+CharOffset, rect.top+CharOffset, ComboBox1.Items[index]);
  end
end;
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 13

Expert Comment

by:Epsylon
ID: 2642296
Here you can find some nice components:

http://www.tmssoftware.com
0
 
LVL 2

Expert Comment

by:kubeerja
ID: 2642300
you have to set combobox style to csOwnerDrawVariable or csownderdrawfixed
0
 
LVL 17

Expert Comment

by:inthe
ID: 2642335
mmm ..
0
 

Author Comment

by:CHORN
ID: 2642491
In my example when I change the color
to red for scoobe I get an error telling me 'Canvas Does Not Allow Drawing'.  Does anyone know why this error is occuring ?
0
 
LVL 17

Expert Comment

by:inthe
ID: 2642594
did you try the code i posted?
it works with no errors on d4.

what code gave the error ?

0
 

Author Comment

by:CHORN
ID: 2642702
The textout procedure raises the error
when I select scoobe.
I am using this in a VCL that I derived
from TCustomCombo.  When I initialize the control I set it's style as you havr mentioned.  In the control I am overriding the DrawItem event.
Thanks for your help.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2642858
Can you post the code you are using?
0
 
LVL 2

Expert Comment

by:kotik
ID: 2643824
Do you create your ComboBox at runtime? You have to set the Parent property in that case to be able to draw on the canvas.

Regards,
Kot.
0
 

Author Comment

by:CHORN
ID: 2645063
I do create the combobox at runtime.
What method do I need to look at in order to let the parent draw on the canvas ?
0
 
LVL 2

Expert Comment

by:kotik
ID: 2645312
After creation simply add this code:

  ComboBox.Parent := self;  // the owner form

Regards,
Kot.
0
 

Author Comment

by:CHORN
ID: 2646265
This code is from a VCL.
in the protected section of the implementation I have the following:
protected
 { Protected declarations }
  procedure Change; override;
  procedure DrawItem(Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
  override;
  procedure KeyDown(var Key: Word;
  Shift: TShiftState); override;


Then in the implementation
the procedure looks like this :

procedure TLookupList.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
   if TCodeList(Items.Objects[Index]).Valid then
      Font.color := clBlack
   else
      Font.color := clRed;
   //inherited DrawItem(Index, Rect, State);
   try
      Canvas.FillRect(Rect);
      Canvas.TextOut(rect.left, rect.top, Items[index]);
   except
   end;
end;

0
 

Author Comment

by:CHORN
ID: 2650855
Adjusted points from 100 to 150
0
 

Author Comment

by:CHORN
ID: 2650856
Thanks for all the help everyone.
I will award the points to the first person who can explain how to change the
font color while the item is selected.
I have tries changing the font when the state is odSelected but it seems like the focus rectangle has it's own font property.
Again Thanks for all the help.
0
 

Author Comment

by:CHORN
ID: 2651077
Thanks InThe
The TextOut method was raising the error
I mentioned above, but the DrawText
method does not.
Thanks again.
0
 
LVL 2

Expert Comment

by:kotik
ID: 2653869
I have no problems with this code:

with (Control as TListBox).Canvas do
begin
  { display the text }
  Font.Name := 'Verdana';
  Font.Size := 8;
  if odSelected in (State) then
    Font.Color := clYellow
  else
    Font.Color := clNavy;
  TextOut(Rect.Left + 18, Rect.Top + 4, GetItemText));
end;
Regards,
Kot.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question