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?
OutOfLuckAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
Become a Certified Penetration Testing Engineer

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.

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Pascal

From novice to tech pro — start learning today.