Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here





a recent post has directed my attention to the subject
of subclassing that I have heretofore not been aware of.

all the items I can find in the builder help files refers
to building a new component.

I have a few questions.

1.   is the term subclassing just refering to the method
     of creating a derived class.

2.   can the method of subclassing be accomplished without
     creating a new component.

thanx in advance


RE: subclassing

I dont know if this is the correct way to do it, but
to a certain extant it works.

I do have a problem with the onclik event throwing an
exception if the editor mode is not set and the goediting
option is not set.  I also can not access the checkboxes
on the string grid.  I think it is because of the way I am
calling the "OnDrawCell" method. I am using "this" for one
of the parameters and I think it is not correct.  I also
dont think I have properly accessed the  "OnDrawCell"
event.  and this may be the problem.  other than those items
I have thrashed out a bunch of interesting code and I may
even learn something. I am still trying to get the "OnDrawCell" event accessible.

I have used some of bhobbs solution and some other stuff
I found on the web from borland.  here is the complete

I have implemented the code directly into a
TStringrid object (all except the inplaceedit stuff) and
I dont get any errors or problems with the checkboxes.


TmyStringGrid *myStringGrid;

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    myStringGrid = new TmyStringGrid (this);
    myStringGrid->Parent = Form1;
    myStringGrid->Top = Edit1->Top + 50;
    myStringGrid->Left = Edit1->Left + 50;
    myStringGrid->Width =400;
    myStringGrid->Height =200;
    myStringGrid->Options.Clear ();
    myStringGrid->Options = myStringGrid->Options<<goEditing;
    //myStringGrid->Options = myStringGrid->Options<<goAlwaysShowEditor;
    myStringGrid->Options = myStringGrid->Options<<goVertLine;
    myStringGrid->Options = myStringGrid->Options<<goHorzLine;
    //myStringGrid->Options = myStringGrid->Options<<goDrawFocusSelected;
    //myStringGrid->Options = myStringGrid->Options>>goRangeSelect;
    myStringGrid->DefaultDrawing = false;
    myStringGrid->Color = clTeal;
    myStringGrid->EditorMode = true;

void __fastcall InvalidateCell(TStringGrid& AGrid, int ACol, int ARow);
bool __fastcall GetCheckState(TStringGrid& AGrid, int ACol,int ARow);
void __fastcall SetCheckState(TStringGrid& AGrid, int ACol, int ARow, bool AChecked);
bool __fastcall GetCheckBox(TStringGrid& AGrid, int ACol, int ARow);
void __fastcall SetCheckBox(TStringGrid& AGrid, int ACol, int ARow, bool AShow, bool AChecked);
bool __fastcall PtInCheckBox(TStringGrid& AGrid, int AX, int AY, int &ACol, int &ARow);

class TmyStringGrid : public TStringGrid

    __fastcall TmyStringGrid (Classes::TComponent* AOwner) : TStringGrid(AOwner) { }

    bool __fastcall SelectCell(int ACol, int ARow);

    void __fastcall TmyStringGrid::DrawCell(int ACol,int ARow, const Windows::TRect &ARect,
        TGridDrawState AState);

    void __fastcall TmyStringGrid::OnDrawCell(TObject *Sender, int ACol, int ARow,
        const Windows::TRect &Rect, TGridDrawState State);

void __fastcall TmyStringGrid::DrawCell(int ACol, int ARow, const Windows::TRect &ARect,
    TGridDrawState AState)
    OnDrawCell(this, ACol, ARow, ARect, AState);

void __fastcall TmyStringGrid::OnDrawCell(TObject *Sender, int ACol, int ARow,
        const Windows::TRect &Rect, TGridDrawState State)
    //ShowMessage ("stRT");
    TStringGrid* StringGrid = static_cast<TStringGrid*>(Sender);
    assert(StringGrid != NULL);  

    RECT RText = static_cast<RECT>(Rect);
    const AnsiString text(StringGrid->Cells[ACol][ARow]);

    const bool fixed = State.Contains(gdFixed);
    const bool focused = State.Contains(gdFocused);
    bool selected = State.Contains(gdSelected);
    if (!StringGrid->Options.Contains (goDrawFocusSelected))
        selected = selected && !focused;

    // if the cell is fixed (headers)
    if (fixed)
        //ShowMessage ("fixed");
        StringGrid->Canvas->Brush->Color = StringGrid->FixedColor;
        StringGrid->Canvas->Font->Color = clBtnText;
        Frame3D(StringGrid->Canvas, (TRect)Rect, clBtnHighlight, clBtnShadow, 1);
    // if the cell is selected
    else if (selected)
        //ShowMessage ("select");
        unsigned char step = 30;
        unsigned char r = 0x80,
        g = 0x80, b = 0xC0;
        TColor clr_highlight = static_cast<TColor>(PALETTERGB(r + step, g + step, b + step));
        TColor clr_shadow = static_cast<TColor>(PALETTERGB(r - step, g - step, b - step));

        StringGrid->Canvas->Brush->Color = static_cast<TColor>(PALETTERGB(r, g, b));
        StringGrid->Canvas->Font->Color = clWhite;
        StringGrid->Canvas->Font->Style = StringGrid->Canvas->Font->Style << fsItalic;

        Frame3D(StringGrid->Canvas, (TRect)Rect, clr_shadow, clr_highlight, 3);
    // if the cell is normal
        //ShowMessage ("normal");
        if (ARow % 2 == 0)
            StringGrid->Canvas->Brush->Color = clInfoBk;
            StringGrid->Canvas->Brush->Color = StringGrid->Color;

        StringGrid->Canvas->Font->Color = StringGrid->Font->Color;

    // if this cell contains a checkbox
    if (GetCheckBox(*StringGrid, ACol, ARow))
        //ShowMessage ("CheckBox");
        // set the flags for rendering
        // checked/unchecked
        unsigned int state = DFCS_BUTTONCHECK;
        if (GetCheckState(*StringGrid, ACol, ARow))
            state = state | DFCS_CHECKED;

        // size the checkbox
        RECT RCell =static_cast<RECT>(Rect);
        OffsetRect(&RCell, 2, 0.5 * (RCell.bottom - RCell.top));
        RCell.right = RCell.left + GetSystemMetrics(SM_CXMENUCHECK);
        RCell.bottom = RCell.top + GetSystemMetrics(SM_CYMENUCHECK);
        RCell.top -= 0.5 * (RCell.bottom - RCell.top) + 2;

        // draw the checkbox
        DrawFrameControl(StringGrid->Canvas->Handle, &RCell, DFC_BUTTON, state);

        // move the text over
        RText.left = RCell.right;

    // draw the text
    RText.left += 2; RText.top += 2;
    DrawText(StringGrid->Canvas->Handle, text.c_str(), text.Length(), &RText, DT_LEFT |DT_VCENTER |DT_SINGLELINE);

bool __fastcall TmyStringGrid::SelectCell(int ACol, int ARow)
    if (ACol == 3)
        InplaceEditor->Brush->Color = clRed;
        InplaceEditor->Brush->Color = clHighlightText;

    return true;
void __fastcall InvalidateCell(
 TStringGrid& AGrid, int ACol, int ARow)
  AGrid.Objects[ACol][ARow] =

bool __fastcall GetCheckState(
  TStringGrid& AGrid, int ACol,int ARow)
  return HIWORD(reinterpret_cast<long>(

void __fastcall SetCheckState(
  TStringGrid& AGrid,
  int ACol, int ARow, bool AChecked)
  long data = reinterpret_cast<long>(
  AGrid.Objects[ACol][ARow] =
      MAKELONG(LOWORD(data), AChecked));

bool __fastcall GetCheckBox(
 TStringGrid& AGrid, int ACol, int ARow)
  return LOWORD(reinterpret_cast<long>(

void __fastcall SetCheckBox(
 TStringGrid& AGrid,
 int ACol, int ARow,
 bool AShow, bool AChecked)
  AGrid.Objects[ACol][ARow] =
      MAKELONG(AShow, false));
    AGrid, ACol, ARow, AChecked);

bool __fastcall PtInCheckBox(
  TStringGrid& AGrid, int AX, int AY,
  int &ACol, int &ARow)
  AGrid.MouseToCell(AX, AY, ACol, ARow);
  RECT RCell = static_cast<RECT>(
    AGrid.CellRect(ACol, ARow));

  OffsetRect(&RCell, 2,
    0.5 * (RCell.bottom - RCell.top));
  RCell.right = RCell.left +
  RCell.bottom = RCell.top +
  RCell.top -= 0.5 *
    (RCell.bottom - RCell.top) + 2;

    PtInRect(&RCell, Point(AX, AY));


Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close