Link to home
Start Free TrialLog in
Avatar of OutOfLuck
OutOfLuck

asked on

Change the colour of a paticular cell in a DrawGrid

I was wondering if it is possible to change the colour of one cell (e.g Row 1, Column 3) in a drawgrid. If it is possible then how would you do it?
Avatar of twinsoft
twinsoft
Flag of Greece image

Hi use OnDrawCell Event like this:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
 if StringGrid1.Cells[ACol, ARow] = '' then // do the check here
  begin
   StringGrid1.Canvas.Brush.Color := clRed; // set the color
   StringGrid1.Canvas.FillRect(Rect);            // draw the Rectangle
  end;
end;
Avatar of OutOfLuck
OutOfLuck

ASKER

hi for the DrawGrid im using it says that a Cell  (  if StringGrid1.Cells[ACol, ARow] = '' then) is an undeclared identifier.
Hi, try this

procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
 if ACol = 2 then
  begin
   DrawGrid1.Canvas.Brush.Color := clRed;
   DrawGrid1.Canvas.FillRect(Rect);
  end;
end;
ASKER CERTIFIED SOLUTION
Avatar of moorhouselondon
moorhouselondon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ah to be able to type quicker than twinsoft
thankyou the code works, however i was wondering if there was anyway to do it without an if statement?
If you remove the if, all cells will be painted with the same color. What do you have in mind ?
im working on a memory game where if two matching pictures are selected then the cells which they occupy are coloured into red, the game only finishes when the whole grid is red. However when i put this code into the game code it doesnt colour the cells.
The code for "matching" is best done by running a check for matches when a cell is clicked on and that event is fired: the code goes into the event trigger.
having ascertained which cells need to be painted red, you set global variables col1, row1, col2, row2 then do this code in the ondrawcell event (see above)

if col1 and row1 then

or

if col2 and row2 then
Thinking about maintaining cells that have been coloured remaining coloured, what you're best off doing is to have an array which indicates which cells should be painted red.  Every match you find goes into that array, and every call to ondrawcell looks up the appropriate entry in the array to see what colour it should be.
i dont follow what you mean with the setting of global variables
Actually it's better to use an array.  Global means that it's defined at the top of the Unit:-

implementation

{$R *.dfm}

matches: array[0..colmax-1,0..rowmax-1] of boolean;

You then initialise this to all False at the start of your program.  Every time a match is found you set the two entries found to True.  Now when you the ondrawcell routine, the code becomes:-

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
 if matches[acol,arow]=true
  begin
   StringGrid1.Canvas.Brush.Color := clRed; // set the color
   StringGrid1.Canvas.FillRect(Rect);            // draw the Rectangle
  end;
end;
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You could actually get rid of the "if then" by defining your array with integers.  You fill the array with clblack (or whatever the start colour is), and then when a match occurs set it to clred.  clred and clblack are effectively just integers.
if i was to do it like you said with integers would it go something like this...
const
  CellColors : array [0..1] of TColor = (clRed, clBlack);
Yes, that would be the correct way to go about it.
then to colour in the cell would you use this code: DrawGrid1.Canvas.FloodFill
Use the code from previously:-

procedure TForm1.String
Grid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
   StringGrid1.Canvas.Brush.Color := matches[acol,arow]
   StringGrid1.Canvas.FillRect(Rect);            // draw the Rectangle
  end;
end;
to set matches to false would you have to do it for all the integer values for example matches[0,0]:=false, matches[0,1]:= false
As mentioned before, what needs to happen is that whenever a change is made by clicking on an element, the "onclick" event is fired, and it is in here that the check to see whether a match occurs, and the values of matches for the two entries is changed as appropriate.