Hallo, can someone help me out:
I have a stringgrid, where i display hex data of a file( a hexeditor), and i need to change the color of the cell, if i chenge the data inside it. How can i do that??
Thanks.

Recommended Answers

All 10 Replies

Hmm, sorry. I thought I responded to this already.

You'll have to set the DefaultDrawing property to false, and provide a method for the OnDrawCell event.

Here's an example I googled.
http://bcbjournal.com/bcbcaq/index.php?loc=grids&caq=48
(It is in BC++, but all the essentials are the same, so you shouldn't have any trouble reading it.)

Hi, thanks for reply. I did some googeling to, but i cannot understand how it works.

var x : array[0..15,0..255] of integer;
      y : array[0..15,0..255] of integer;

procedure TForm1.sGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);

var   S : string;
begin
   if (x[acol,arow] = y[valx,valy]) then
   begin
    Sgrid.Canvas.Brush.Color := clYellow;
    Sgrid.Canvas.FillRect(Rect);
    S := Sgrid.Cells[ACol, ARow];
    Sgrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, S);
  end;
  end;

I add this to the onDrawCell event.
But i dont need to change color of only one cell.
I readed thet i need to store in an array the data of each cell, and then change my specific cell data.
Im a beginner in delphi programming , so i dont have mutch experience.

Can anyone please explain me how hoes this cell color change work.
Thanks.

In your OnDrawCell event you need to choose your color based on whatever criteria you are interested in. The criteria may apply to more than one cell, even.

procedure TForm1.sGridDrawCell(
  Sender:     TObject;
  ACol, ARow: Longint;
  Rect:       TRect;
  State:      TGridDrawState
  );
  var
    savefg: TColor;
    savebg: TColor;
  begin
  // Save the current colors
  savefg := Font.Color;
  savebg := Canvas.Brush.Color;

  if not (gdFixed in State)
  and IsHighlightMyCell( Sender, ARow, ACol )  // note 1
    then if (gdSelected in State)
           then begin
                // Something really bright for highlighted special cells
                Font.Color         := clYellow;
                Canvas.Brush.Color := clRed
                end
           else begin
                // Something not quite so bright for normal special cells
                Font.Color         := clLtGray;
                Canvas.Brush.Color := clMaroon
                end;

  // All I wanted is to change colors,
  // so we'll let the string grid draw itself.
  DrawCell( Sender, ACol, ARow, Rect, State );

  // Restore the original colors
  Canvas.Brush.Color := savebg;
  Font.Color         := savefg
  end;

The line labeled "note 1" is what you are interested in. You should have a function as: [B]function[/B] TForm1.IsHighlightMyCell( Sender: [B]TStringGrid[/B]; row, col: [B]longint[/B] ): [B]boolean[/B]; which indicates whether or not the indicated cell needs to be highlighted. You can choose any criteria as to whether the cell is highlighted or not.

For example, you could have the function body as: result := (Sender.Cells[ row, col ] = 'Hello'); This would be true for every cell with the text "Hello".

You could highlight the third column: result := (col = 2); Whatever you want.

Hope this helps.

hallo, thanks for reply. Im starting now to understand how that onDrawCell event works, but i have a few questions:
1.

and IsHighlightMyCell( Sender, ARow, ACol )

Here sender must be sGrid, right?
2.

DrawCell( Sender, ACol, ARow, Rect, State );

Im getting am error here, "Undeclered Identifier", i dont know what that wants to be??
3.
in Function IsHighlightMyCell( Sender, ARow, ACol ) ;
i want to highlight the cells that i had changed the data inside, and i can change data from a cell by 2 ways:
1.by takeing cursor in the right cell and input data by keyboard.
2.by converting a number in hex and write direct to sgrid as:

with sgrid do
Cells[1,0] := x;

How can i do that?
Thanks again for helping me.

1. Yep. Exactly. Sender should be sGrid.

2. Oops! It should be sGrid.DrawCell( ACol, ARow, Rect, State ); I just typed this stuff in off the top of my head...

You can resolve things like this by placing the cursor over the name "DrawCell" and pressing F1. The online help will give you choices of TCustomGrid objects to choose from. This means that DrawCell is a method of a TCustomGrid (or descendant), not TForm.

3. However you change the cell, you must somewhere remember that the cell has been changed.
The TStringGrid.Objects[] property allows you to attach arbitrary data to each cell. You can use a simple class to keep information about the change state of the cell:

type
  TCellDataModified = class end;

Then, when you modify a cell, tag it by the presence of a modified class:

with sGrid do
  begin
  Cells[ 1, 0 ] := x;
  if not Assigned( Objects[ 1, 0 ] )
    then Objects[ 1, 0 ] := TCellDataModified.Create
  end;

And finally, inside the IsHighlightMyCell function, you can simply return whether or not the cell has an attached TCellDataModified object:

function TForm1.IsHighlightMyCell( Sender: TStringGrid; row, col: longint ): boolean;
  begin
  result := Assigned( Sender.Objects[ col, row ] )
  end;

You will have to remember to free all objects you create at some point (like if you delete a row or column, or when you delete the whole table).

// delete entire table
with sGrid do
  for row := 0 to RowCount -1 do
  for col := 0 to ColCount -1 do
    begin
    Objects[ col, row ].free;
    Objects[ col, row ] := nil
    end;

In the above example, TCellDataModified functions as a semaphore object (a boolean): It has no purpose but to indicate a specific state by its presence or absence. If you need to attach more data to the cells, you'll have to make a class that simply includes a boolean field that you can use:

type
  TCellData = class
    public
      IsModified: boolean;
      Age:        cardinal;
      etc
    end;

Then check that field for whether the cell is modified.

Hope this helps.

ok, Thanks for reply, i do have 1 question again:

sGrid.DrawCell( ACol, ARow, Rect, State );

I did try this line, but since sGrid is TStringGrid it doesnt work.
I need to install TCustomGrid component?? If so where can i find it??
Thanks.

Argh. You made me go and do this myself. I forgot how primitive a TStringGrid is... It derives from TCustomGrid but hides its DrawCell method...

Alas. I also forgot to wrap the method body in an appropriate with statement above. (All this stuff is in the documentation.)

procedure Form1.sGridDrawCell( ... );
  ...
  begin
  with Sender as TStringGrid do
    begin
    savefg := Font.Color;
    savebg := Canvas.Brush.Color;

    if not (gdFixed in State)
      then ...

    // Fill the background color of the cell
    Canvas.FillRect( Rect );

    // Draw the text with the desired foreground color
    Canvas.TextRect( Rect, Rect.Left +2, Rect.Top +2, Cell[ ACol, ARow ] );

    ...
    end
  end;

When I messed with this before (Long Ago), I wrote my own TGrid descendant, so DrawCell was available to me. Sorry I forgot about that.

Good luck.

Thanks Duoas , here is what i have doen afterall:

procedure TForm1.sGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var s:string;
begin
if not (gdFixed in State)
 and  IsHighlightMyCell( sgrid, ARow, ACol )
    then if (gdSelected in State)
           then
               begin
                SGrid.Canvas.Brush.Color := clWhite;
                Sgrid.canvas.Font.Color  := clBlack;
               end
            else
               begin
                SGrid.Canvas.Brush.Color := clred;
                Sgrid.canvas.Font.Color  := clBlack;
               end;
    SGrid.Canvas.FillRect(Rect);
    S := SGrid.Cells[ACol, ARow];
    SGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, S);
 end;

All of this changes color when i activate this procedure:

procedure TForm1.Button3Click(Sender: TObject);
begin
with sGrid do
  begin
  Cells[ 1, 1 ] := 'FF';
  Objects[ 1, 1 ] := TCellDataModified.Create;
  Cells[ 2, 1 ] := 'AA';
  Objects[ 2, 1 ] := TCellDataModified.Create;
  end;
end;

This is one thing i needed, and it works perfect.

Now i need to change color when im editing manualy the StringGrid, how can i do that?

Heh heh heh... Glad you got it working.

Now i need to change color when im editing manualy the StringGrid, how can i do that?

That, my friend, is a whole new can of beans. A really big, really deep one. Essentially you have to write your own cell editor. It isn't particularly difficult, just involved. Can you live with the way it works now? Or do you want to continue?

Heh heh heh... Glad you got it working.


That, my friend, is a whole new can of beans. A really big, really deep one. Essentially you have to write your own cell editor. It isn't particularly difficult, just involved. Can you live with the way it works now? Or do you want to continue?

OK, well i live it this way for now, i had try to do this for almost 3 weeks and no result, and now thanks to your help i managed to finish this. Now i continue coding and if i get in "trouble" i hope u can help me again.
Again i want to thank you for your help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.