Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

subclassing

Status
Not open for further replies.

butthead

Programmer
Feb 24, 2002
545
US
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

TC
 
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
project.

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.

Code:
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
{
    public:

    __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;
        StringGrid->Canvas->FillRect(Rect);
        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;

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

        StringGrid->Canvas->Font->Color = StringGrid->Font->Color;
        StringGrid->Canvas->FillRect(Rect);
    }

    // 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;
    else
        InplaceEditor->Brush->Color = clHighlightText;

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


bool __fastcall GetCheckState(
  TStringGrid& AGrid, int ACol,int ARow)
{
  return HIWORD(reinterpret_cast<long>(
    AGrid.Objects[ACol][ARow]));
}

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

bool __fastcall GetCheckBox(
 TStringGrid& AGrid, int ACol, int ARow)
{
  return LOWORD(reinterpret_cast<long>(
    AGrid.Objects[ACol][ARow]));
}

void __fastcall SetCheckBox(
 TStringGrid& AGrid,
 int ACol, int ARow,
 bool AShow, bool AChecked)
{
  AGrid.Objects[ACol][ARow] =
    reinterpret_cast<TObject*>(
      MAKELONG(AShow, false));
  SetCheckState(
    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 +
    GetSystemMetrics(SM_CXMENUCHECK);
  RCell.bottom = RCell.top +
    GetSystemMetrics(SM_CYMENUCHECK);
  RCell.top -= 0.5 *
    (RCell.bottom - RCell.top) + 2;

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

TC
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Sponsor

Back
Top