StringGrid cell manipulation

Dingbats 0 Tallied Votes 663 Views Share

Hello Everyone,
my first post - so please don't shoot me if it goes wrong!

I'd been looking for this for some time now and have seen a number of related queries but no solutions.

I cannot take credit for the whole code here, but I did adapt it to include the text formatting. The possibilities are endless.

Hopefully someone will find this usefull.
Good luck

void __fastcall TForm1::GridDrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{

  //Affects the fixed cells - should there be any
  if (State.Contains(gdFixed))
  {
    StringGrid70->Canvas->Brush->Color = clBtnShadow;  //background
    StringGrid70->Canvas->Font->Color = clWhite;       //text
  }
  else

  //the currently selected cell is green
  //change this to the same colour as the background in order
  //to "hide" the selected cell
  if (State.Contains(gdSelected))
  {
      Form1->StringGrid70->Canvas->Brush->Color = clGreen;
      Form1->StringGrid70->Canvas->Font->Color = clBlack;
  }
  else

  //turns cell[2][2] yellow
  if (ARow == 2 && ACol == 2)
  {
    StringGrid70->Canvas->Brush->Color = clYellow;
    StringGrid70->Canvas->Font->Color = clWhite;
  }
  else

  //turns rows 7 & 8 silver - but not the fixed cells
  if ((ARow == 7 || ARow == 8) && !State.Contains(gdFixed))
  {
    StringGrid70->Canvas->Brush->Color = clSilver;
    StringGrid70->Canvas->Font->Color = clWhite;
  }
  else

  //if the cell contains an "a" anywhere then the text is bold & struck through
  if (StringGrid70->Cells[ACol][ARow].AnsiPos("a") != 0 && !State.Contains(gdFixed))
  {
    StringGrid70->Canvas->Font->Style = TFontStyles() << fsBold << fsStrikeOut;
    StringGrid70->Canvas->Font->Color = clBlack;
  }

  // Fills the cells
  StringGrid70->Canvas->FillRect(Rect);

  // A neat trick for text alignment
  int hAlign;     // text align, 0/1/2 - Left/Center/Right
  if (ACol % 2)
    hAlign = 1;
  else
    hAlign = 2;

  // and now put everything in the cells
  DrawText(StringGrid70->Canvas->Handle, StringGrid70->Cells[ACol][ARow].c_str(),
    -1, &Rect, DT_SINGLELINE | DT_VCENTER | hAlign);

}

Dani AI

Generated

provided a compact, practical OnDrawCell example that demonstrates a lot of useful ideas. A few clarifications and best-practices make the handler more robust and avoid surprising visual glitches when the grid repaints.

Always restore the Canvas state at the start of the handler. Canvas properties persist between cell draws, so colors and font styles will “leak” unless reset. A minimal safe reset looks like this:

TStringGrid* g = StringGrid70;
g->Canvas->Brush->Color = g->Color;     // restore default background
g->Canvas->Font->Assign(g->Font);       // restore default font (color, size, style)

After that, apply conditional overrides (gdFixed, gdSelected, special rows/cols) and explicitly set Canvas->Font->Style for formatted cells; otherwise reassign the grid font to clear previous styles. Check gdFixed first so fixed-cell styling isn’t accidentally overridden by later cases.

Prefer explicit text-alignment flags and vertical centering instead of passing magic integers. Build a flags variable from DT_SINGLELINE | DT_VCENTER and OR in DT_LEFT/DT_CENTER/DT_RIGHT so intent is obvious. For vertical centering an alternative is to compute the Y offset using Canvas->TextHeight and call TextRect. To reduce flicker on heavy redraws, enable DoubleBuffered (form or control) and avoid per-paint allocations. For repeated checks (like “contains an 'a'”), consider caching per-cell attributes (an array or TObject attached to Cells) instead of scanning the string every paint; this keeps drawing fast and deterministic.

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.