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 derfloh 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
Joined
Feb 24, 2002
Messages
545
Location
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