Board index » delphi » TStringGrid with multiple text colors

TStringGrid with multiple text colors

Is there a component like the TStringGrid component that
allows control over the color of the text of an individual row,
or of the background color of individual rows?

For example, I have a larger number of strings in a
StringGrid component.  I would somehow like to
"highlight" those that do not fall within certain
parameters.

Thanks,
Mark Everly

 

Re:TStringGrid with multiple text colors


Mark,

in article <3A8C30F0.99F8...@ace-comp.com>, you wrote:

Quote
> For example, I have a larger number of strings in a
> StringGrid component.  I would somehow like to
> "highlight" those that do not fall within certain
> parameters.

you need to catch OnDrawCell. Here's an example:

unit AlignText;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids, StdCtrls, ExtCtrls;

type
  TFrmAlignText = class(TForm)
    StringGrid: TStringGrid;
    Label1: TLabel;
    ListBox: TListBox;
    Image: TImage;
    procedure StringGridDrawCell(Sender: TObject; Col, Row: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure ListBoxDrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FrmAlignText: TFrmAlignText;

implementation

{$R *.DFM}

procedure DrawTheText(ACanvas: TCanvas; ARect: TRect;
                      AValue: string; AAlign: TAlignment);
var
  horzOffset: integer;
  options:    integer;
  vertOffset: integer;
begin
  // Note: The Handle property of TCanvas is
  //       the handle of its DC.
  with ACanvas do begin
    vertOffset := ARect.Top + (((ARect.Bottom - ARect.Top) -
TextExtent(AValue).CY) div 2);
    horzOffset := TextExtent('Mi').CX div 4; // Yields rougly the width of
                                             // an "average" character.
    options    := ETO_CLIPPED or ETO_OPAQUE;

    case AAlign of
      taLeftJustify: begin
        SetTextAlign(Handle, TA_LEFT or TA_TOP or TA_NOUPDATECP);
        ExtTextOut(Handle, ARect.Left + horzOffset, vertOffset, options,
                   @ARect, PChar(AValue), Length(AValue), nil);
      end;

      taRightJustify: begin
        SetTextAlign(Handle, TA_RIGHT or TA_TOP or TA_NOUPDATECP);
        ExtTextOut(Handle, ARect.Right - horzOffset, vertOffset, options,
                   @ARect, PChar(AValue), Length(AValue), nil);
      end;

      taCenter: begin
        horzOffset := ((ARect.Right - ARect.Left) - TextExtent(AValue).CX) div
2;
        SetTextAlign(Handle, TA_LEFT or TA_TOP or TA_NOUPDATECP);
        ExtTextOut(Handle, ARect.Left + horzOffset, vertOffset, options,
                   @ARect, PChar(AValue), Length(AValue), nil);
      end;
    end;
  end;
end;

procedure TFrmAlignText.StringGridDrawCell(Sender: TObject; Col, Row: Integer;
  Rect: TRect; State: TGridDrawState);
var
  align:    TAlignment;
  theText:  string;
  thisRect: TRect;
begin
  // Assumes that DefaultDrawing := true.

  theText := IntToStr(Col) + ':' + IntToStr(Row);
  align   := taLeftJustify;

  // Select background color.

  if gdSelected in State then
    StringGrid.Canvas.Brush.Color := clHighlight
  else if gdFixed in State then
    StringGrid.Canvas.Brush.Color := clBtnFace
  else
    StringGrid.Canvas.Brush.Color := clWindow;

  // Determine font/text attributes.

  StringGrid.Canvas.Font.Color := clBlack;
  StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style - [fsBold];

  if Col = 1 then begin
    align := taRightJustify;
    StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style + [fsBold];
    StringGrid.Canvas.Font.Color := clRed;
    StringGrid.Canvas.Font.Name  := 'Courier New';
  end
  else if Col = 2 then begin
    align := taCenter;
    StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style + [fsBold]
  end
  else if (Row = 0) and (Col = 0) then begin
    StringGrid.Canvas.Draw(Rect.Left + 2, Rect.Top + 2, Image.Picture.Graphic);
  end;

  if not ((Row = 0) and (Col = 0)) then
    DrawTheText(StringGrid.Canvas, Rect, theText, align);

  // Draw focus rectangle.

  if gdFocused in State then
    StringGrid.Canvas.DrawFocusRect (Rect);

  if gdFixed in State then begin
    Frame3D(StringGrid.Canvas, Rect, clWindow, clHighlight, 1);
  end;
end;

procedure TFrmAlignText.ListBoxDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  horzOffset: integer;
  vertOffset: integer;
begin
  // ListBox.Style is set to lbOwnerDrawFixed.
  //
  with ListBox.Canvas do begin
    // vertOffset added to Rect.Top causes the string
    // to be vertically centered in the rectangle.
    //
    vertOffset  := (((Rect.Bottom - Rect.Top)
                   - TextExtent(ListBox.Items[Index]).CY) div 2);

    // TextWidth('Mi') div 4 gives (roughly)
    // 1/2 of an average character width.
    //
    horzOffset := TextWidth('Mi') div 4;

    if not (odSelected in State) then begin
      if Odd(Index) then begin
        Brush.Color := clBtnFace;
        Font.Color  := clBtnText
      end
      else begin
        Font.Color  := clFuchsia;
      end;
    end;

    FillRect(Rect);

    TextOut(Rect.Left + horzOffset,
            Rect.Top  + vertOffset,
            ListBox.Items[Index]);
  end;
end;

procedure TFrmAlignText.FormCreate(Sender: TObject);
var
  i: integer;
begin
  StringGrid.ColWidths[0]  := Image.Width + 4;
  StringGrid.RowHeights[0] := Image.Height + 4;

  for i := 1 to 50 do
    ListBox.Items.Add('Item ' + IntToStr(i));

  Image.Visible := false;
end;

end.
--
Regards
Ralph (TeamB)
===

Re:TStringGrid with multiple text colors


Thanks Ralph,

That did it.....

Mark

Quote
"Ralph Friedman (TeamB)" wrote:
> Mark,

> in article <3A8C30F0.99F8...@ace-comp.com>, you wrote:

> > For example, I have a larger number of strings in a
> > StringGrid component.  I would somehow like to
> > "highlight" those that do not fall within certain
> > parameters.

> you need to catch OnDrawCell. Here's an example:

> unit AlignText;

> interface

> uses
>   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
>   Grids, StdCtrls, ExtCtrls;

> type
>   TFrmAlignText = class(TForm)
>     StringGrid: TStringGrid;
>     Label1: TLabel;
>     ListBox: TListBox;
>     Image: TImage;
>     procedure StringGridDrawCell(Sender: TObject; Col, Row: Integer;
>       Rect: TRect; State: TGridDrawState);
>     procedure ListBoxDrawItem(Control: TWinControl; Index: Integer;
>       Rect: TRect; State: TOwnerDrawState);
>     procedure FormCreate(Sender: TObject);
>   private
>     { Private declarations }
>   public
>     { Public declarations }
>   end;

> var
>   FrmAlignText: TFrmAlignText;

> implementation

> {$R *.DFM}

> procedure DrawTheText(ACanvas: TCanvas; ARect: TRect;
>                       AValue: string; AAlign: TAlignment);
> var
>   horzOffset: integer;
>   options:    integer;
>   vertOffset: integer;
> begin
>   // Note: The Handle property of TCanvas is
>   //       the handle of its DC.
>   with ACanvas do begin
>     vertOffset := ARect.Top + (((ARect.Bottom - ARect.Top) -
> TextExtent(AValue).CY) div 2);
>     horzOffset := TextExtent('Mi').CX div 4; // Yields rougly the width of
>                                              // an "average" character.
>     options    := ETO_CLIPPED or ETO_OPAQUE;

>     case AAlign of
>       taLeftJustify: begin
>         SetTextAlign(Handle, TA_LEFT or TA_TOP or TA_NOUPDATECP);
>         ExtTextOut(Handle, ARect.Left + horzOffset, vertOffset, options,
>                    @ARect, PChar(AValue), Length(AValue), nil);
>       end;

>       taRightJustify: begin
>         SetTextAlign(Handle, TA_RIGHT or TA_TOP or TA_NOUPDATECP);
>         ExtTextOut(Handle, ARect.Right - horzOffset, vertOffset, options,
>                    @ARect, PChar(AValue), Length(AValue), nil);
>       end;

>       taCenter: begin
>         horzOffset := ((ARect.Right - ARect.Left) - TextExtent(AValue).CX) div
> 2;
>         SetTextAlign(Handle, TA_LEFT or TA_TOP or TA_NOUPDATECP);
>         ExtTextOut(Handle, ARect.Left + horzOffset, vertOffset, options,
>                    @ARect, PChar(AValue), Length(AValue), nil);
>       end;
>     end;
>   end;
> end;

> procedure TFrmAlignText.StringGridDrawCell(Sender: TObject; Col, Row: Integer;
>   Rect: TRect; State: TGridDrawState);
> var
>   align:    TAlignment;
>   theText:  string;
>   thisRect: TRect;
> begin
>   // Assumes that DefaultDrawing := true.

>   theText := IntToStr(Col) + ':' + IntToStr(Row);
>   align   := taLeftJustify;

>   // Select background color.

>   if gdSelected in State then
>     StringGrid.Canvas.Brush.Color := clHighlight
>   else if gdFixed in State then
>     StringGrid.Canvas.Brush.Color := clBtnFace
>   else
>     StringGrid.Canvas.Brush.Color := clWindow;

>   // Determine font/text attributes.

>   StringGrid.Canvas.Font.Color := clBlack;
>   StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style - [fsBold];

>   if Col = 1 then begin
>     align := taRightJustify;
>     StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style + [fsBold];
>     StringGrid.Canvas.Font.Color := clRed;
>     StringGrid.Canvas.Font.Name  := 'Courier New';
>   end
>   else if Col = 2 then begin
>     align := taCenter;
>     StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style + [fsBold]
>   end
>   else if (Row = 0) and (Col = 0) then begin
>     StringGrid.Canvas.Draw(Rect.Left + 2, Rect.Top + 2, Image.Picture.Graphic);
>   end;

>   if not ((Row = 0) and (Col = 0)) then
>     DrawTheText(StringGrid.Canvas, Rect, theText, align);

>   // Draw focus rectangle.

>   if gdFocused in State then
>     StringGrid.Canvas.DrawFocusRect (Rect);

>   if gdFixed in State then begin
>     Frame3D(StringGrid.Canvas, Rect, clWindow, clHighlight, 1);
>   end;
> end;

> procedure TFrmAlignText.ListBoxDrawItem(Control: TWinControl;
>   Index: Integer; Rect: TRect; State: TOwnerDrawState);
> var
>   horzOffset: integer;
>   vertOffset: integer;
> begin
>   // ListBox.Style is set to lbOwnerDrawFixed.
>   //
>   with ListBox.Canvas do begin
>     // vertOffset added to Rect.Top causes the string
>     // to be vertically centered in the rectangle.
>     //
>     vertOffset  := (((Rect.Bottom - Rect.Top)
>                    - TextExtent(ListBox.Items[Index]).CY) div 2);

>     // TextWidth('Mi') div 4 gives (roughly)
>     // 1/2 of an average character width.
>     //
>     horzOffset := TextWidth('Mi') div 4;

>     if not (odSelected in State) then begin
>       if Odd(Index) then begin
>         Brush.Color := clBtnFace;
>         Font.Color  := clBtnText
>       end
>       else begin
>         Font.Color  := clFuchsia;
>       end;
>     end;

>     FillRect(Rect);

>     TextOut(Rect.Left + horzOffset,
>             Rect.Top  + vertOffset,
>             ListBox.Items[Index]);
>   end;
> end;

> procedure TFrmAlignText.FormCreate(Sender: TObject);
> var
>   i: integer;
> begin
>   StringGrid.ColWidths[0]  := Image.Width + 4;
>   StringGrid.RowHeights[0] := Image.Height + 4;

>   for i := 1 to 50 do
>     ListBox.Items.Add('Item ' + IntToStr(i));

>   Image.Visible := false;
> end;

> end.
> --
> Regards
> Ralph (TeamB)
> ===

Other Threads