Change font color in a TComboxBox? [Edit]

I have a 5 row combo box showing, in a black font, the values
 'select a grade'
 '1'
 '2'
 '3'
 '4'

Using the OnDrawitem event I color the background of each row depending upon the text shown (1 = blue, 2 = green, 3 = yellow, 4 = red).
However the 'preselect' font color, when the mouse is over an item, and also the selected font color always changes to white. This does not show up on the yellow or green backgrounds.

How can I make the preselect and selected font color stay black (or even change depending on the backgroupd color)?

For info, the code I currently use to change the background color of the rows is below. The actual color is recovered from a database using a line like Frm_Options.GetGradeColour4;

Howard

{code}
procedure TStaffComplete.ComboBoxGradeDrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
 ColourRowsOfComboBox(Control, Index, Rect, State);
end;


procedure TStaffComplete.ColourRowsOfComboBox(Control: TWinControl;  Index: Integer; Rect: TRect; State: TOwnerDrawState);
//to do this it needs the style property of the combobox or listbox set to csOwnerDrawFixed
//then call this code in the OnDrawItem event
var
   myColor: TColor;
   myBrush: TBrush;
   Xposition:integer;
   linewidth:integer;
begin
   myBrush := TBrush.Create;
   with (Control as TcomboBox).Canvas do
      begin
      case Index of
      0: myColor := clwhite;
      1: mycolor := Frm_Options.GetGradeColour1;
      2: mycolor := Frm_Options.GetGradeColour2;
      3: mycolor := Frm_Options.GetGradeColour3;
      4: mycolor := Frm_Options.GetGradeColour4;
      end;

      myBrush.Style := bsSolid;              //setthe style of the background
      myBrush.Color := myColor;
      Windows.FillRect(handle, Rect, myBrush.Handle) ;//colour the background
      Brush.Style := bsClear;

      //centre the text
      linewidth := Rect.right - Rect.Left;
      Xposition := (linewidth div 2);
      if Index = 0 then
         TextOut(Rect.Left, Rect.Top,(Control as TcomboBox).Items[Index])  //left aligned
      else
         TextOut(Rect.Left+Xposition, Rect.Top,(Control as TcomboBox).Items[Index]) ; //centred
      end;
   MyBrush.Free;
end;
{code}

Edited by: howard manwaring on May 30, 2012 2:14 AM
0
howard
5/30/2012 9:14:54 AM
embarcadero.delphi.vcl.using 2297 articles. 2 followers. Follow

5 Replies
1509 Views

Similar Articles

[PageSpeed] 22

On 30/05/2012 7:14 PM, howard manwaring wrote:
> I have a 5 row combo box showing, in a black font, the values
>   'select a grade'
>   '1'
>   '2'
>   '3'
>   '4'
>
> Using the OnDrawitem event I color the background of each row depending upon the text shown (1 = blue, 2 = green, 3 = yellow, 4 = red).
> However the 'preselect' font color, when the mouse is over an item, and also the selected font color always changes to white. This does not show up on the yellow or green backgrounds.
>
> How can I make the preselect and selected font color stay black (or even change depending on the backgroupd color)?
>
> For info, the code I currently use to change the background color of the rows is below. The actual color is recovered from a database using a line like Frm_Options.GetGradeColour4;
>
> Howard
>
> {code}
> procedure TStaffComplete.ComboBoxGradeDrawItem(Control: TWinControl; Index: Integer;
>    Rect: TRect; State: TOwnerDrawState);
> begin
>   ColourRowsOfComboBox(Control, Index, Rect, State);
> end;
>
>
> procedure TStaffComplete.ColourRowsOfComboBox(Control: TWinControl;  Index: Integer; Rect: TRect; State: TOwnerDrawState);
> //to do this it needs the style property of the combobox or listbox set to csOwnerDrawFixed
> //then call this code in the OnDrawItem event
> var
>     myColor: TColor;
>     myBrush: TBrush;
>     Xposition:integer;
>     linewidth:integer;
> begin
>     myBrush := TBrush.Create;
>     with (Control as TcomboBox).Canvas do
>        begin
>        case Index of
>        0: myColor := clwhite;
>        1: mycolor := Frm_Options.GetGradeColour1;
>        2: mycolor := Frm_Options.GetGradeColour2;
>        3: mycolor := Frm_Options.GetGradeColour3;
>        4: mycolor := Frm_Options.GetGradeColour4;
>        end;
>
>        myBrush.Style := bsSolid;              //setthe style of the background
>        myBrush.Color := myColor;
>        Windows.FillRect(handle, Rect, myBrush.Handle) ;//colour the background
>        Brush.Style := bsClear;
>
>        //centre the text
>        linewidth := Rect.right - Rect.Left;
>        Xposition := (linewidth div 2);
>        if Index = 0 then
>           TextOut(Rect.Left, Rect.Top,(Control as TcomboBox).Items[Index])  //left aligned
>        else
>           TextOut(Rect.Left+Xposition, Rect.Top,(Control as TcomboBox).Items[Index]) ; //centred
>        end;
>     MyBrush.Free;
> end;
> {code}
>
> Edited by: howard manwaring on May 30, 2012 2:14 AM

As you are changing the brush color, why don't you also change the Font 
color? Font.Color := myfontcolor.

Then, when you call TextOut, it'll use the correct color that you have 
specified.

HTH
Andrew
0
Andrew
5/30/2012 10:48:48 AM
> {quote:title=Andrew Baylis wrote:}{quote}

> As you are changing the brush color, why don't you also change the Font 
> color? Font.Color := myfontcolor.
> 
> Then, when you call TextOut, it'll use the correct color that you have 
> specified.
> 
> HTH
> Andrew

Thank you, that sort of helped.
Using font.color := clblack, the font stays black all the time, whether the mouse is over it or not, which is much better than changing from black to white as the mouse goes over a row and when a selection has been made.

Of course this means that now the user can no longer see which row is preselected (ie nothing appears to happen as they move the mouse which is a bit disconcerting) but with only four rows to choose from I don't suppose that matters too much.

I'd be interested to know if there is a way to change the preselect (and selected) font color independently of the base font color though so that for example the text in the rows ise shown in black and as you move the mouse over the rows the text changes to grey (or even a complimentary color tro that of the background).
Howard
0
howard
5/30/2012 1:09:12 PM
howard manwaring wrote:

> I have a 5 row combo box showing, in a black font, the values
>  'select a grade'
>  '1'
>  '2'
>  '3'
>  '4'
> 
> Using the OnDrawitem event I color the background of each row
> depending upon the text shown (1 = blue, 2 = green, 3 = yellow, 4 =
> red).  However the 'preselect' font color, when the mouse is over an
> item, and also the selected font color always changes to white. This
> does not show up on the yellow or green backgrounds.
> 
> How can I make the preselect and selected font color stay black (or
> even change depending on the backgroupd color)?

Your code completely ignores the value of the State parameter. That is
a big fault on your part, this parameter is there for a reason, it
tells you which state the items needs to be drawn in (normal, selected,
hotlight etc.). You need to adjust your background and foreground
(font) color according to state.




-- 
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires), 
use the newsgroup archives :
http://codenewsfast.com
http://groups.google.com
0
Peter
5/30/2012 4:50:53 PM
howard wrote:

> However the 'preselect' font color, when the mouse is over an item,
> and also the selected font color always changes to white. This does
> not show up on the yellow or green backgrounds.

As Peter said, you need to look at the State parameter of the OnDrawItem 
event to know how to draw each item.  Try something like this:

{code:delphi}
procedure TStaffComplete.ComboBoxGradeDrawItem(Control: TWinControl; Index: 
Integer; Rect: TRect; State: TOwnerDrawState);
begin
  ColourRowsOfComboBox(Control, Index, Rect, State);
end;

procedure TStaffComplete.ColourRowsOfComboBox(Control: TWinControl; Index: 
Integer; Rect: TRect; State: TOwnerDrawState);
var
  myBkgColor: TColor;
  myFontColor: TColor;
begin
  if (State * [odSelected, odHotLight]) <> [] then
  begin
    myBkgColor := clHighlight;
    myFontColor := clHighlightText;
  end else
  begin
    case Index of
      0: begin
        myBkgColor := clWhite;
        myFontColor := clBlack;
      end;
      1: begin
        myBkgColor := Frm_Options.GetGradeColour1;
        myFontColor := ...;
      end;
      2: begin
        myBkgColor := Frm_Options.GetGradeColour2;
        myFontColor := ...;
      end;
      3: begin
        myBkgColor := Frm_Options.GetGradeColour3;
        myFontColor := ...;
      end;
      4: begin
        myBkgColor := Frm_Options.GetGradeColour4;
        myFontColor := ...;
      end;
    end;
  end;
  with (Control as TComboBox).Canvas do
  begin
    Brush.Style := bsSolid;
    Brush.Color := myBkgColor;
    Font.Color := myFontColor;
    FillRect(Rect);
    Brush.Style := bsClear;
    if Index = 0 then
      TextRect(Rect, Rect.Left, Rect.Top, (Control as TComboBox).Items[Index])
    else
      TextRect(Rect, Rect.Left+((Rect.Right - Rect.Left) div 2), Rect.Top, 
(Control as TComboBox).Items[Index]);
  end;
end;
{code}

--
Remy Lebeau (TeamB)
0
Remy
5/30/2012 6:52:17 PM
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}

> As Peter said, you need to look at the State parameter of the OnDrawItem 
> event to know how to draw each item.  Try something like this:


Its true I was ignoring the state variable as Peter said. I wrote that code from a snippet posted as a reply to a similar question and had no idea what the state variable did. Thank you Remy for making it clear. My combo box is now all singing and dancing!
Howard
0
howard
5/31/2012 12:09:24 PM
Reply: