Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Coloring multiple cells in a StringGrid

Status
Not open for further replies.

barnarp

Programmer
May 7, 2002
16
ZA
Hi,

I need to color more than one cell in a grid at the same time.

I have a query from a database that returns the column and row position of the cells that need to be painted/colored. I then add these values to a multi dimensional array. The code looks something like this:

var idxarray : Integer;
arrayHighlight : array of array of Integer;
HighlightCellsFound : Boolean;

idxarray := 0;
SetLength(arrayHighlight, 10, 10); //wont be more than 10 cells to color
While not EOF do
begin
arrayHighlight[idxarray,0] := fieldbyname('col').AsInteger;
arrayHighlight[idxarray,1] := fieldbyname('col').AsInteger;
idxarray := idxarray + 1;
end;
if idxarray > 0 then HighlightCellsFound := True;

Then all the col and row coordinates of the cells that needs coloring is in the array.

The part which I cannot get right is for the grid to actually paint it. I have tried this code, but for obvious reasons it doesn't work:

procedure Tform1.stringgrid1GetCellColor(Sender: TObject; ARow,
ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
var i : Integer;
begin
if (HighlightCellsFound = True) then
begin
for i := Low( arrayHighlight ) to High( arrayHighlight ) do
begin
ACol := arrayHighlight[i,0];
ARow := arrayHighlight[i,1];
if (ACol = arrayHighlight[i,0]) and (ARow = arrayHighlight[i,1]) then
begin
AFont.Color := clBlue;
ABrush.Color:=clSkyBlue;
end;

end;
HighlightCellsFound := False;
end;


end;

Can someone please assist me.
 

You have a fundamental lack of understanding how Delphi controls the painting of a TStringGrid.

See thread102-1173813 for a working example.

If you want to build an array to control the process, that's just fine. But the actual painting of any given cell is done when Delphi wants to, namely on the DrawCell event.

When you want to redraw the grid, you can use the .Repaint method. Then process each DrawCell event as it happens.

 
Thanks,

I have looked at the example, but I am not sure how to incorporate the array code with it.

I also don't understand why stringgrid1GetCellColor can't be used instead.

I need some example code or something. I am really at wits end.
 
I got it working by doing the following:

procedure TfrmMain.grdMonthViewDrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
i : Integer;
begin

if (ACol > 0) and (ARow > 0) then
begin
for i := Low( arrayHighlight ) to High( arrayHighlight ) do
begin
if (ACol = arrayHighlight[i,0]) and (ARow = arrayHighlight[i,1]) then
begin
grdMonthView.Canvas.Font.Color := clWhite;
grdMonthView.Canvas.Brush.Color:=clGray;
grdMonthView.canvas.FillRect(rect);
grdMonthView.canvas.textRect(rect,Rect.left,rect.top,grdMonthView.cells[ACol,ARow]);
end;

end;
end;
end;
 
You might simplify and speed your code by using the Objects property of TStringGrid instead of your arrayhighlight.

Objects is an array of the same dimensions as the string grid. It is of type TObject which can be used as an integer.

So your code might look something like:
Code:
const
  Highlight = TObject(1);
begin
  while not EOF do begin
    grdMonthView.Objects[FieldByName('col').AsInteger, FieldByName('row').AsInteger] := Highlight;
    Next;
  end;
end;
Note that there is no need for idxArray, arrayHighlight or HighlightCellsFound variables.

Your DrawCell handler would look something like:
Code:
procedure TfrmMain.grdMonthViewDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
  if grdMonthView.Objects[ACol,ARow] = Highlight then 
    with grdMonthView.Canvas do begin
      Font.Color := clWhite;
      Brush.Color:=clGray;
      FillRect(rect);
      TextRect(rect,Rect.left,rect.top,grdMonthView.cells[ACol,ARow]);
    end;
end;
Note using this technique there is no need to loop through an array to decide on colouring.

Andrew
Hampshire, UK
 
The objects can hold the colour value directly so each cell knows what colour it is, this idea can be expaned to hold the Font, style, Size and colour as well as the Backgrond colours or any other info you like.

Defining a type for the colour
Code:
type TCellCol = Class(TObject)
     Colour: TColor;
     // other fields
     end;

Initalising the array
Code:
var CellColour: TCellCol;
begin
// other stuff
Cellcolour := TCellCol.Create;
Cellcolour.Colour := ClWhite;
for A := 0 to 1999 do
  begin
     emergidata.cells[0,A] := inttostr(A);
     emergidata.Objects[0,A] := Cellcolour;
  end;
//etc

so (not tested much) the values can be accessed in ondraw
Code:
//Its just an object we need to cast it to the correct type
with gridmonth do
   Brush.color := (Objects[ACol,ARow] as TCellcol).Colour;
//


[red]GNBM 4th Feb[/red] More on and other neat UK stuff at forum1091
Steve: Delphi a feersum engin indeed.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top