• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1390
  • Last Modified:

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?
0
OutOfLuck
Asked:
OutOfLuck
  • 10
  • 7
  • 4
2 Solutions
 
twinsoftCommented:
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;
0
 
OutOfLuckAuthor Commented:
hi for the DrawGrid im using it says that a Cell  (  if StringGrid1.Cells[ACol, ARow] = '' then) is an undeclared identifier.
0
 
twinsoftCommented:
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;
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
moorhouselondonCommented:
Shouldn't that read:-

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
 if (ACol=3) and (ARow=1) then
  begin
   StringGrid1.Canvas.Brush.Color := clRed; // set the color
   StringGrid1.Canvas.FillRect(Rect);            // draw the Rectangle
  end;
end;

(make sure as to whether the rows and cols you're referring to start at 0 or 1)
0
 
moorhouselondonCommented:
ah to be able to type quicker than twinsoft
0
 
OutOfLuckAuthor Commented:
thankyou the code works, however i was wondering if there was anyway to do it without an if statement?
0
 
twinsoftCommented:
If you remove the if, all cells will be painted with the same color. What do you have in mind ?
0
 
OutOfLuckAuthor Commented:
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.
0
 
moorhouselondonCommented:
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.
0
 
moorhouselondonCommented:
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
0
 
moorhouselondonCommented:
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.
0
 
OutOfLuckAuthor Commented:
i dont follow what you mean with the setting of global variables
0
 
moorhouselondonCommented:
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;
0
 
twinsoftCommented:
You should store into an external 2dimension array the status of each cell. Then check this array in the DroawCell event to determine if a cell should be painted or not.

Something like this:

var
 a: array[1..10][1..10] of boolean;

...
begin
 if PicturesMatch then // do your check probably in the OnClick event
  a[acol][arow] := true;
end;
...

and then in drawcell

if a[acol][arow] then
 begin
   StringGrid1.Canvas.Brush.Color := clRed; // set the color
   StringGrid1.Canvas.FillRect(Rect);            // draw the Rectangle
 end;
0
 
moorhouselondonCommented:
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.
0
 
OutOfLuckAuthor Commented:
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);
0
 
moorhouselondonCommented:
Yes, that would be the correct way to go about it.
0
 
OutOfLuckAuthor Commented:
then to colour in the cell would you use this code: DrawGrid1.Canvas.FloodFill
0
 
moorhouselondonCommented:
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;
0
 
OutOfLuckAuthor Commented:
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
0
 
moorhouselondonCommented:
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.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

  • 10
  • 7
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now