Board index » cppbuilder » Adding rows to TStringGrid

Adding rows to TStringGrid


2006-07-20 03:55:04 AM
cppbuilder46
I have implemented a TStringGrid object (let's call it SG) and
initialized the RowCount to 1. The ColCount remains fixed at
12. When I click an Add button, I increase the RowCount by 1,
assign text to the needed column fields, and have my Draw
function draw it. This works just fine until I get to around
40 rows, at which time I get an exception:
"Project AD.exe raised exception class EAccessViolation with
message 'Access violation at address 0044e7C1 in module
'AD.exe'. Read of address 046537AC'. Process stopped..."
Is there a size limit to TStringGrid? If so, is there a way
around it? Any other ideas?
 
 

Re:Adding rows to TStringGrid

"Barry" < XXXX@XXXXX.COM >wrote in message
Quote
This works just fine until I get to around 40 rows, at which
time I get an exception:
Please show your actual code.
Quote
Is there a size limit to TStringGrid?
No. It is limited only by available memory.
Quote
is there a way around it?
Have a look at using TListView instead. Its vsReport style works very well
as a grid, especially if you use the TListView in virtual mode, in which
case you can have literally millions of rows without using up very much
memory.
Gambit
 

Re:Adding rows to TStringGrid

Sorry for the delay in responding to your request for more info. I was pulled off to another project for a while and am now getting back to this.
The code to add a row is:
//--------------------------------------------------------------
void __fastcall TTestProfile::AddButtonClick(TObject *Sender)
{
// Sets initializes the next new element of my
// underlying data structure
DefaultSetpoint(CurrentFileRev, (void *)&qTestProfile.Setpoint[qTestProfile.NumSetpoints]);
qTestProfile.NumSetpoints++;
// Add a row to the StringGrid
SetpointGrid->RowCount++;
// Set index to last line
SetpointGrid->Row = SetpointGrid->RowCount - 1; // Automatically calls StringGridClick()
// Shows/hides vertical scroll bar
if (SetpointGrid->RowCount * SetpointGrid->DefaultRowHeight>SetpointGrid->Height)
SetpointGrid->ScrollBars |= ssVertical;
else
SetpointGrid->ScrollBars = ssNone;
TableDirtybit = true;
}
//--------------------------------------------------------------
// This is my default draw cell function
void __fastcall TTestProfile::SetpointGridDrawCell(
TObject *Sender, int ACol, int ARow, TRect &Rect,
TGridDrawState State)
{
static AnsiString s;
static int tw,th,x,y;
static TStringGrid * pSG;
static TCanvas * pCanvas;
// Point to objects
pSG = (TStringGrid *) Sender;
pCanvas = pSG->Canvas;
s = pSG->Cells[ACol][ARow];
// Get info for centering text (horiz and vert))
tw = pCanvas->TextWidth(s);
x = ((Rect.Left + Rect.Right) - tw) / 2;
th = pCanvas->TextHeight(s);
y = ((Rect.Top + Rect.Bottom) - th) / 2;
// Paint it!
pCanvas->Brush->Color = ARow == CurrSetpointIndex ? clHighlite : clBtnFace;
pCanvas->FillRect(Rect);
DrawText(pCanvas->Handle,s.c_str(),-1,&Rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER);
}
//--------------------------------------------------------------
Naturally, I have other functions for deleting rows, editing the base data structure, writing files, etc., (the whole C++ module is 88 KB, but this other stuff shouldn't have any impact on thiss add function. At least I don't see any connection.
"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

"Barry" < XXXX@XXXXX.COM >wrote in message
news:44be8e18$ XXXX@XXXXX.COM ...

>This works just fine until I get to around 40 rows, at which
>time I get an exception:

Please show your actual code.

>Is there a size limit to TStringGrid?

No. It is limited only by available memory.

>is there a way around it?

Have a look at using TListView instead. Its vsReport style works very well
as a grid, especially if you use the TListView in virtual mode, in which
case you can have literally millions of rows without using up very much
memory.


Gambit


 

{smallsort}

Re:Adding rows to TStringGrid

"Barry" < XXXX@XXXXX.COM >wrote:
Quote

Please wrap your lines when you post. If using the web
interface, you need to enter a hard return at the end
of each line. If using a reader, look for an option to
set the line width. Also, please trim your posts.
Quote
The code to add a row is:

// Add a row to the StringGrid
SetpointGrid->RowCount++;
Once you get around 50 rows, this method becomes slower and
slower and slower. One way around that is to allocate new rows
in chunks and keep a seperate Count variable (if you don't
like visible empty rows, you can ignore them in the OnDrawCell
event.
Something else that will help (because TStringGrid does *alot*
of drawing) is to use BeginUpdate (check the help for any
control) when adding rows. TStringGrid doesn't have a
BeginUpdate method but you can accomplish the same by using
SendMessage to send the grid a WM_SETREDRAW message.
Quote
// Shows/hides vertical scroll bar
if (SetpointGrid->RowCount * SetpointGrid->DefaultRowHeight>SetpointGrid->Height)
SetpointGrid->ScrollBars |= ssVertical;
The ScrollBars property is an enums so the above is in
error. You can set that property to ssNone or ssVertical
or ssHorizontal or ssBoth.
Quote
void __fastcall TTestProfile::SetpointGridDrawCell(
TObject *Sender, int ACol, int ARow, TRect &Rect,
TGridDrawState State)
{

static AnsiString s;
static int tw,th,x,y;
static TStringGrid * pSG;
static TCanvas * pCanvas;
Using static places the variables into the Global name space
and it's not needed here.
Quote
// Point to objects
pSG = (TStringGrid *) Sender;
You're using C++ so you should be using C++ casting instead of
old c-style casting:
TStringGrid *pSG = static_cast<TStringGrid*>( Sender );
Quote
s = pSG->Cells[ACol][ARow];
Useless variable and assignment.
Quote
// Get info for centering text (horiz and vert))
tw = pCanvas->TextWidth(s);
x = ((Rect.Left + Rect.Right) - tw) / 2;
th = pCanvas->TextHeight(s);
y = ((Rect.Top + Rect.Bottom) - th) / 2;
Unneeded and extreemly slow. In fact, it's not even used with
the code that you posted.
Quote
// Paint it!
pCanvas->Brush->Color = ARow == CurrSetpointIndex ? clHighlite : clBtnFace;
You probably want to be setting the Font Color as well.
Quote
pCanvas->FillRect(Rect);
DrawText(pCanvas->Handle,s.c_str(),-1,&Rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER);
Look at the docs for DrawText in the win32.hlp file. There are
other flags available as well for aligning text. I'm guessing
that you didn't post your actual code here. If I'm correct and
the ScrollBars property is not your problem, please do so.
~ JD
 

Re:Adding rows to TStringGrid

"JD" < XXXX@XXXXX.COM >wrote:
Quote

"Barry" < XXXX@XXXXX.COM >wrote:
>

Please wrap your lines when you post. If using the web
interface, you need to enter a hard return at the end
of each line. If using a reader, look for an option to
set the line width. Also, please trim your posts.

>The code to add a row is:
>
>// Add a row to the StringGrid
>SetpointGrid->RowCount++;

Once you get around 50 rows, this method becomes slower and
slower and slower. One way around that is to allocate new rows
in chunks and keep a seperate Count variable (if you don't
like visible empty rows, you can ignore them in the OnDrawCell
event.

Something else that will help (because TStringGrid does *alot*
of drawing) is to use BeginUpdate (check the help for any
control) when adding rows. TStringGrid doesn't have a
BeginUpdate method but you can accomplish the same by using
SendMessage to send the grid a WM_SETREDRAW message.

>// Shows/hides vertical scroll bar
>if (SetpointGrid->RowCount * SetpointGrid->DefaultRowHeight>SetpointGrid->Height)
>SetpointGrid->ScrollBars |= ssVertical;

The ScrollBars property is an enums so the above is in
error. You can set that property to ssNone or ssVertical
or ssHorizontal or ssBoth.

>void __fastcall TTestProfile::SetpointGridDrawCell(
>TObject *Sender, int ACol, int ARow, TRect &Rect,
>TGridDrawState State)
>{
>
>static AnsiString s;
>static int tw,th,x,y;
>static TStringGrid * pSG;
>static TCanvas * pCanvas;

Using static places the variables into the Global name space
and it's not needed here.

>// Point to objects
>pSG = (TStringGrid *) Sender;

You're using C++ so you should be using C++ casting instead of
old c-style casting:

TStringGrid *pSG = static_cast<TStringGrid*>( Sender );

>s = pSG->Cells[ACol][ARow];

Useless variable and assignment.

>// Get info for centering text (horiz and vert))
>tw = pCanvas->TextWidth(s);
>x = ((Rect.Left + Rect.Right) - tw) / 2;
>th = pCanvas->TextHeight(s);
>y = ((Rect.Top + Rect.Bottom) - th) / 2;

Unneeded and extreemly slow. In fact, it's not even used with
the code that you posted.

>// Paint it!
>pCanvas->Brush->Color = ARow == CurrSetpointIndex ? clHighlite : clBtnFace;

You probably want to be setting the Font Color as well.

>pCanvas->FillRect(Rect);
>DrawText(pCanvas->Handle,s.c_str(),-1,&Rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER);

Look at the docs for DrawText in the win32.hlp file. There are
other flags available as well for aligning text. I'm guessing
that you didn't post your actual code here. If I'm correct and
the ScrollBars property is not your problem, please do so.

~ JD

 

Re:Adding rows to TStringGrid

I tried some of the cleanups you suggested and VOILA! I can go
to 80 rows without a problem. My guess is it had something to
do with the scrollbar error. Thanks for the help.
BTW, I was posting this a moment ago and pressing the <enter>key at the wrong time did the post. Please ignore it - sorry.
"JD" < XXXX@XXXXX.COM >wrote:
Quote

"Barry" < XXXX@XXXXX.COM >wrote:
>

Please wrap your lines when you post. If using the web
interface, you need to enter a hard return at the end
of each line. If using a reader, look for an option to
set the line width. Also, please trim your posts.

>The code to add a row is:
>
>// Add a row to the StringGrid
>SetpointGrid->RowCount++;

Once you get around 50 rows, this method becomes slower and
slower and slower. One way around that is to allocate new rows
in chunks and keep a seperate Count variable (if you don't
like visible empty rows, you can ignore them in the OnDrawCell
event.

Something else that will help (because TStringGrid does *alot*
of drawing) is to use BeginUpdate (check the help for any
control) when adding rows. TStringGrid doesn't have a
BeginUpdate method but you can accomplish the same by using
SendMessage to send the grid a WM_SETREDRAW message.

>// Shows/hides vertical scroll bar
>if (SetpointGrid->RowCount * SetpointGrid->DefaultRowHeight>SetpointGrid->Height)
>SetpointGrid->ScrollBars |= ssVertical;

The ScrollBars property is an enums so the above is in
error. You can set that property to ssNone or ssVertical
or ssHorizontal or ssBoth.

>void __fastcall TTestProfile::SetpointGridDrawCell(
>TObject *Sender, int ACol, int ARow, TRect &Rect,
>TGridDrawState State)
>{
>
>static AnsiString s;
>static int tw,th,x,y;
>static TStringGrid * pSG;
>static TCanvas * pCanvas;

Using static places the variables into the Global name space
and it's not needed here.

>// Point to objects
>pSG = (TStringGrid *) Sender;

You're using C++ so you should be using C++ casting instead of
old c-style casting:

TStringGrid *pSG = static_cast<TStringGrid*>( Sender );

>s = pSG->Cells[ACol][ARow];

Useless variable and assignment.

>// Get info for centering text (horiz and vert))
>tw = pCanvas->TextWidth(s);
>x = ((Rect.Left + Rect.Right) - tw) / 2;
>th = pCanvas->TextHeight(s);
>y = ((Rect.Top + Rect.Bottom) - th) / 2;

Unneeded and extreemly slow. In fact, it's not even used with
the code that you posted.

>// Paint it!
>pCanvas->Brush->Color = ARow == CurrSetpointIndex ? clHighlite : clBtnFace;

You probably want to be setting the Font Color as well.

>pCanvas->FillRect(Rect);
>DrawText(pCanvas->Handle,s.c_str(),-1,&Rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER);

Look at the docs for DrawText in the win32.hlp file. There are
other flags available as well for aligning text. I'm guessing
that you didn't post your actual code here. If I'm correct and
the ScrollBars property is not your problem, please do so.

~ JD

 

Re:Adding rows to TStringGrid

"Barry" < XXXX@XXXXX.COM >wrote in message
Quote
// Add a row to the StringGrid
SetpointGrid->RowCount++;
You cannot use the '++' operator with properties. You need to use '+' and
'=' separately instead:
SetpointGrid->RowCount = SetpointGrid->RowCount + 1;
Quote
SetpointGrid->ScrollBars |= ssVertical;
You cannot use the '|=' operator with properties, either. Besides, you
should not be 'or'ing the values anyway. If you want both horizontal and
vertical scrollbars, then you should be using ssBoth instead:
SetpointGrid->ScrollBars = ssBoth;
Quote
static AnsiString s;
static int tw,th,x,y;
static TStringGrid * pSG;
static TCanvas * pCanvas;
Why are you using 'static' here?
Quote
// Get info for centering text (horiz and vert))
tw = pCanvas->TextWidth(s);
x = ((Rect.Left + Rect.Right) - tw) / 2;
th = pCanvas->TextHeight(s);
y = ((Rect.Top + Rect.Bottom) - th) / 2;
You don't need any of that, especially since you are not actually using them
for anything.
Gambit
 

Re:Adding rows to TStringGrid

Got it. I will fix the ++ problem. The rest is already taken
care of. Thanks for the help.
"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

"Barry" < XXXX@XXXXX.COM >wrote in message
news:44ca009e$ XXXX@XXXXX.COM ...

>// Add a row to the StringGrid
>SetpointGrid->RowCount++;

You cannot use the '++' operator with properties. You need to use '+' and
'=' separately instead:

SetpointGrid->RowCount = SetpointGrid->RowCount + 1;

>SetpointGrid->ScrollBars |= ssVertical;

You cannot use the '|=' operator with properties, either. Besides, you
should not be 'or'ing the values anyway. If you want both horizontal and
vertical scrollbars, then you should be using ssBoth instead:

SetpointGrid->ScrollBars = ssBoth;

>static AnsiString s;
>static int tw,th,x,y;
>static TStringGrid * pSG;
>static TCanvas * pCanvas;

Why are you using 'static' here?

>// Get info for centering text (horiz and vert))
>tw = pCanvas->TextWidth(s);
>x = ((Rect.Left + Rect.Right) - tw) / 2;
>th = pCanvas->TextHeight(s);
>y = ((Rect.Top + Rect.Bottom) - th) / 2;

You don't need any of that, especially since you are not actually using them
for anything.


Gambit


 

Re:Adding rows to TStringGrid

"Barry" < XXXX@XXXXX.COM >wrote:
Quote

Please wrap your lines and trim your posts.
Quote
BTW, I was posting this a moment ago and pressing the <enter>key at the wrong time did the post. Please ignore it - sorry.
If you're using a reader, there should be an option that will
allow you to cancel (remove;delete) your own posts.
~ JD
 

Re:Adding rows to TStringGrid

Remy Lebeau (TeamB) wrote:
Quote
You cannot use the '++' operator with properties. You need to use '+' and
'=' separately instead:

SetpointGrid->RowCount = SetpointGrid->RowCount + 1;

Just curious: why cannot I use ++ operator with properties?
--
Darío Alejandro Guzik (El Tío Borracho)
tioborracho.tripod.com
e-mail: XXXX@XXXXX.COM
ICQ : 8389493
 

Re:Adding rows to TStringGrid

"Darío Alejandro Guzik" < XXXX@XXXXX.COM >wrote in message
Quote
Just curious: why cannot I use ++ operator with properties?
Because unary operators (++, --, +=, -=, etc) are not implemented for
properties.
Gambit