Home

Grids

   

Grids Fundamentals

 

Introduction

A grid is a series of columns and rows to represent data in a visual format. There is no strict rule as to what a grid control is used for. It can be used to simply display a series of values by categories. To organize its content, a grid is made of vertical and horizontal lines. These lines are used as separators. They create vertical entities called columns and horizontal sections called rows:

Grid

The intersection of a column and a row is called a cell:

Cell

The cell is the most important entity and the most used aspect of a grid. The cells hold the actual values of a grid. The cells of a grid can be used to display data or they can be used to receive data from the user. This means that data of a grid is entered or stored in cells.

Because the role of a grid is not defined by any standard, the most top cell of each column can be used to display a label. In fact, a column specifies a category of value. Therefore, the label of a column signifies the category of values of that column:

Column Headers

To create a series of values for each category, you use a row of data. A row is also called a record. To make a record explicit, the most left row can display a label. The easiest and most basic label consists of a number. For example, rows can be labeled from top to bottom as 1, 2, 3, 4, etc:

Row Headers

In most cases, each cell is in fact an edit control and its content is a UnicodeString. This means that a cell can contain a natural number, a floating-point variable, or a string.

Practical LearningPractical Learning: Introducing Grids

  1. Start Embarcadero RAD Studio
  2. To create a new project, on the main menu, click File -> New -> VCL Forms Application - C++Builder
  3. In the Object Inspector, change the properties of the form as follows:
    Caption: Depreciation Evaluation
    Name:
    frmDepreciation
    Position: poScreenCenter
    ShowHint: True
  4. In the Standard section of the Tool Palette, click the TPanel icon and click the form
  5. In the Object Inspector, set the panel's Align property to alTop
  6. In the Win32 section of the Tool Palette, click the TStatusBar icon and click the empty area of the form
  7. In the Additional section of the Tool Palette, click the TCategoryPanelGroup icon and click the middle empty area of the form
  8. Right-click the category panel group and click New Panel
  9. Right-click the category panel group and click New Panel
  10. Right-click the category panel group and click New Panel
  11. Complete the design of the form as follows:
     
    Depreciation
    Control Align Alignment Caption Name Text
    TPanel TPanel alTop   Delete    
    TLabel Label     &Original Item Price:    
    TEdit Edit   taRightJustify   edtCost 0.00
    TLabel Label     &Salvage:    
    TEdit Edit   taRightJustify   edtSalvage 0.00
    TLabel Label     Estimated &Life:    
    TEdit Edit   taRightJustify   edtLife 0
    TButton Button     &Evaluate btnEvaluate  
    TCategoryPanelGroup TCategoryPanelGroup alClient        
    CategoryPanel       Double Declining Balance    
    CategoryPanel       Straight-Line Method    
    CategoryPanel       Sum of the Years Digit    
    TStatusBar Label alBottom        

Creating a Grid

To create a grid of data, the Visual Component Library (VCL) provides various controls based on classes. Those classes are defined in the Grids.hpp library. The fundamental class that supports grids in the VCL is named TCustomGrid but its main job is to lay a foundation for derived classes. The TCustomGrid class is derived from TCustomControl, which itself is based on TWinControl. The TCustomGrid class has the TCustomDrawGrid abstract class as its child. Below the TCustomDrawGrid class is a derived class named TDrawGrid. This is the first class that implements a grid control.

To visually create a grid, from the Additional section of the Tool Palette, you can click TDrawGrid TDrawGrid and click a form. A draw grid can be used for all types of values, including graphics, etc. If you want a grid that holds regular values, the VCL provides a class named TStringGrid. The TStringGrid is (directly) derived from TDrawGrid. To visually create a string grid, in the Additional section of the Tool Palette click the TStringGrid button TStringGrid and click the form.

To programmatically create a string grid control, declare a pointer to TStringGrid class using the new operator. Use its default constructor to specify the container of the control as parent. Here is an example:

//---------------------------------------------------------------------------
#include <vcl.h>
#include <Grids.hpp>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    TStringGrid *StatRates = new TStringGrid(this);
    StatRates->Parent = this;
}
//---------------------------------------------------------------------------

After creating the control, you can set its properties to the values of your choice. After using the control, you can get rid of it using the delete operator, or you can trust its parent to do it for you.

As a descendant of TWinControl, the TStringGrid class inherits all the usual characteristics and events common to Windows control. It fires the OnClick event when the user clicks anywhere on the control. It sends an OnDblClick event when the user double-clicks any cell. It uses all mouse events (OnMouseDown, OnMouseMove, OnMouseUp, OnMouseWheelDown, and OnMouseWheelUp) as well as keyboard events (OnKeyDown, OnKeyPress, and OnKeyUp). Besides the regular control events, the string grid fires events that are proper to its functionality.

Practical LearningPractical Learning: Adding a Grid

  1. In the Tool Palette, click Additional
  2. Click the TStringGrid icon TStringGrid
  3. On the form, click under the Double Declining Balance bar
  4. While the string grid control is still selected, in the Object Inspector, click Name and type grdDoubleDecliningBalance
  5. In the Additional section of the Tool Palette, click the TStringGrid icon TStringGrid
  6. On the form, click under the Straight-Line Method bar
  7. While the string grid control is still selected, in the Object Inspector, click Name and type grdStraightLineMethod
  8. In the Additional section of the Tool Palette, click the TStringGrid icon TStringGrid
  9. On the form, click under the Sum of the Years Digit bar
  10. While the string grid control is still selected, in the Object Inspector, click Name and type grdSumOfYears

Characteristics of a Grid Control

 

The Border Style

Like many other controls, a grid is represented with a 3-D effect that raises its borders. This effect is controlled by the BorderStyle property of the TCustomGrid class:

__property Forms::TFormBorderStyle BorderStyle = {read=FBorderStyle,write=SetBorderStyle};

If you do not want to display borders on the control, set the BorderStyle property to bsNone:

Border Style

Introduction to Columns and Rows

A grid is made of vertical divisions called columns and horizontal divisions called rows. Two of the most visual characteristics of a string grid are its number of columns and its number of rows. These two
values are set using the ColCount and the RowCount properties. The values are integer types and should be >= 0. If you set either property to a negative value, it would be set to 1. If you do not want to display columns, set the ColCount to 0. In the same way, if you do not want to display rows, set the RowCount value to 0.

Practical LearningPractical Learning: Setting the Number of Columns

  1. On the form, click the string grid control in the Double Declining Balance section
  2. In the Tool Palette, click ColCount
  3. Type 4 and press Enter
  4. On the form, click the string grid in the Straight Line Method section
  5. Press and hold Shift
  6. Click the string grid in the Sum of the Years Digit section
  7. Release Shift
  8. In the Tool Palette, click ColCount
  9. Type 4 and press Enter

Depreciation

The Scroll Bars

By default, if a grid contains more columns than its width can show, it would display a vertical scroll bar. In the same way, if there are more rows than the control's height can accommodate, it would be equipped with a horizontal scroll bar. The ability to display scroll bars is controlled by the ScrollBars property. You can use it to display only the vertical scroll bar (ssVertical), only the horizontal scroll bar (ssHorizontal), both scroll bars (ssBoth), or no scroll bar (ssNone) at all.

The Fixed Rows and Fixed Columns

Like most other list-based controls, a grid is used to display data and, in some applications, you may want the users to enter or use values of the grid control. To guide the users with the values in the grid, you can display explicit text in the fixed columns and fixed rows. The top and left cells are qualified as fixed and, by default, they are the most top and the left cells respectively. Besides these ranges of cells, you can add a fixed row of cells and a fixed column of rows.

If you want to display only one fixed row, it must be the most top range. This characteristic is controlled by the FixedRows property and, by default, is set to 1. If you want to display an additional range of fixed cells on top, change the value of FixedRows. In the same way, the number of fixed columns on the left side of the object is controlled by the FixedCols property. Setting either of these values to 0 would hide the fixed
column or row:

FixedCols=1; FixedRows=1 FixedCols=0; FixedRows=0
Border Style Border Style
FixedCols=1; FixedRows=0 FixedCols=0; FixedRows=1
Border Style Border Style
FixedCols=2; FixedRows=1 FixedCols=1; FixedRows=2
Border Style Border Style

In the same way, you can decide how many columns and how rows to fix.

Introduction to Cells

As mentioned already, the intersection of a column and a row is called a cell. To distinguish cells that hold indicative values and those that hold usable or modifiable values, cells are divided in two categories distinguished by two colors. The cells on the top section and those on the left, when displaying a different color than the cells in the middle-center section of the control, are called fixed cells.

The Cells Colors

To guide the user with the values on the grid, the cells on top and those on the left display the same color as the form, known in the Control Panel as the Button Color. The cells that display usable and modifiable values have a background color known in Control Panel as Window Color. To visually change the background color of cells that display values, use the Color property of the Object Inspector. Here is a grid with the clSkyBlue color:

Headers Color

You can also change these colors programmatically. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    TStringGrid *StatRates = new TStringGrid(this);
    StatRates->Parent = this;
    
    StatRates->Color = TColor(RGB(255, 230, 204));
}
//---------------------------------------------------------------------------

To change the colors of the fixed columns and rows, change the color value of the FixedColor property of the TCustomGrid class:

__property Graphics::TColor FixedColor = {read=FFixedColor,write=SetFixedColor};

Here is a grid with the clNavy FixedColor:

Headers Color

You can also change these colors programmatically. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    TStringGrid *StatRates = new TStringGrid(this);
    StatRates->Parent = this;
    StatRates->Color = TColor(RGB(255, 230, 204));
    
    StatRates->FixedColor = TColor(RGB(255, 128, 0));
}
//---------------------------------------------------------------------------

The Grid Lines

To distinguish cells, they are separated by vertical and horizontal lines known as grid lines. By default, the grid lines have a width of 1 integer. To display a wider line, change the value of the GridLineWidth. A reasonable value should be less than 10. If you do not want to display grid lines, set the GridLineWidth property to 0.

In order to access all of the cells that are part of a column, you should know the columnís index number. The most left column, which is sometimes the fixed column, unless the FixedCols value is set to 0, has an index of 0. The second column from left has an index of 1, etc. In the same way, rows are presented by an index. The most top row has an index of 0; the second row from top has an index of 1, etc.

Columns Widths

By default, all columns have a width of 64 pixels. At design or run time, you can control this by changing the value of the DefaultColWidth property. If you want to control the widths of individual columns, at run time, call the ColWidths property:

__property int ColWidths = {read=GetColWidths,write=SetColWidths};

Specify the index of the column you need. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    StringGrid1->Color = TColor(RGB(255, 230, 204));
    StringGrid1->FixedColor = TColor(RGB(255, 128, 0));
    StringGrid1->ColWidths[2] = 48;
    StringGrid1->ColWidths[3] = 22;
    StringGrid1->ColWidths[4] = 96;
}
//---------------------------------------------------------------------------

Rows Heights

By default, all rows have a height of 24 pixels. At design or run time, you can control this by changing the value of the DefaultRowHeight property of the TCustomGrid class:

__property int DefaultColWidth = {read=FDefaultColWidth,write=SetDefaultColWidth};

If you want to control the height of individual rows, at run time, call the ColHeights property and specify the index of the row you want access to. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    StringGrid1->Color = TColor(RGB(255, 230, 204));
    StringGrid1->FixedColor = TColor(RGB(255, 128, 0));
    StringGrid1->ColWidths[2] = 48;
    StringGrid1->ColWidths[3] = 22;
    StringGrid1->ColWidths[4] = 96;
    StringGrid1->RowHeights[1] = 18;
    StringGrid1->RowHeights[2] = 40;
    StringGrid1->RowHeights[3] = 12;
}
//---------------------------------------------------------------------------

Default Drawing

In order to display cells with their default control appearance, the DefaultDrawing property must be set to true, which is the default:

__property bool DefaultDrawing = {read=FDefaultDrawing,write=FDefaultDrawing};

If you want to further customize the appearance of cells, you may have to draw them at run time. In this case, you would set the DefaultDrawing value to false.

A Grid is Made of Collections

The columns of the grid are stored in a collection or array called Cols. This property is a member of the TStringGrid class:

__property Classes::TStrings * Cols = {read=GetCols,write=SetCols};

By specifying the index of a column, you can change the label of the column header. In the same way, the rows are grouped in a collection called Rows, also a member of the TStringGrid class:

__property Classes::TStrings * Rows = {read=GetRows,write=SetRows};

This allows you to change the text of a row header based on its index. The cells of a grid are stored in a two-dimensional array called Cells, which is a member of the TStringGrid class:

__property System::UnicodeString Cells = {read=GetCells,write=SetCells};

The Options of a Grid

A grid provides options that allow you to customize the behavior of the string grid. For example, you may want to allow the user to move the position of a column, to be able to put values in cells, to change the existing values in cells, etc. To support options, the TCustomGrid class provides its children with the Options property that is of type TGridOption:

__property System::Set<Grids::TGridOption,0,17> Options = 
{
    read=FOptions,
    write=SetOptions
};

The TGridOption enumeration is defined as follows:

enum TGridOption{
	goFixedVertLine,
	goFixedHorzLine,
	goVertLine,
	goHorzLine,
	goRangeSelect,
	goDrawFocusSelected,
	goRowSizing,
	goColSizing,
	goRowMoving,
	goColMoving,
	goEditing,
	goTabs,
	goRowSelect,
	goAlwaysShowEditor,
	goThumbTracking,
	goFixedColClick,
	goFixedRowClick,
	goFixedHotTrack
};

The options are represented in the Object Inspector by a field named Option:

Options

The members of the TGridOption appear self-explanatory. For example, if you want to allow the users to be able to move the columns, you can set the goColMoving option to true. If you want users to be able to move rows, set the goRowMoving option to true.

If you had allowed the user to move the columns, whenever a user has performed this operation, the string grid would fire the OnColumnMoved() event. Its syntax is:

void __fastcall TStringGrid(TObject* Sender, long FromIndex, long ToIndex);

This event is a good place to decide what to do, if there is anything to do, when the user has moved a column. In the same way, if you had allowed the user to move rows, the string grid sends an OnRowMoved event immediately after the user has moved a row.

 
 
 

Using a Cell

 

The Cell's Box

If at any time a cell is selected, you can get the rectangular dimension of that cell using the CellRect() method. Its syntax is:

TRect __fastcall CellRect(int ACol, int ARow);

The arguments, ACol and ARow, represent the column index and the row index of the cell that has focus. This method returns the TRect rectangle of the cell. You can call this method when the user clicks a cell in the string grid. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    StringGrid1->ColWidths[0] = 72;
    StringGrid1->ColWidths[1] = 54;
    StringGrid1->ColWidths[2] = 35;
    StringGrid1->ColWidths[3] = 75;
    StringGrid1->RowHeights[0]= 15;
    StringGrid1->RowHeights[1]= 22;
    StringGrid1->RowHeights[2]= 10;
    StringGrid1->RowHeights[3]= 35;
}
//---------------------------------------------------------------------------

This would produce:

Grid

The Mouse on a Cell

As mentioned already, the string grid a Windows control that has its origin in the TWinControl class. As a result, when a grid is clicked, it fires the OnClick event. When the user clicks a cell, you can call the CellRect() method to get the rectangular box of that cell and do whatever you want with it. Here is an example:

void __fastcall TForm1::StringGrid1Click(TObject *Sender)
{
    TRect Recto = StringGrid1->CellRect(StringGrid1->Col, StringGrid1->Row);
    int Area = Recto.Width() * Recto.Height();
    Label1->Caption = Area;
}
//---------------------------------------------------------------------------

Grid

 

Grid

If the mouse is positioned or passing somewhere on or over the string grid and you want to know
on what cell the mouse is, you can use the MouseToCell() method. Its syntax is:

void __fastcall MouseToCell(int X, int Y, int &ACol, int &ARow);

This method is usually used on a mouse event such as OnMouseDown(), OnMouseMove(), and OnMouseUp() as these events provide the mouse coordinates. The MouseToCell() method retrieves the horizontal and vertical coordinates of the mouse, translates that position to the column and row indexes of the cell under the mouse and return those values. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1MouseMove(TObject *Sender,
					     TShiftState Shift, int X, int Y)
{
    int x, y;
    StringGrid1->MouseToCell(X, Y, x, y);
    Label1->Caption = L"Col: " + UnicodeString(x) + L" Row: " + UnicodeString(y);
}
//---------------------------------------------------------------------------

Grid

Grid

In the same way, sometimes when the user clicks a cell, you may want to find out what cell was clicked. To get this information, you can call the MouseCoord() method of the TCustomGrid class. The TCustomGrdi::MouseCoord() method returns an object of type TGridCoord, which is a structure:

struct TGridCoord
{
    int X;
    int Y;
    {
 	in    int X    int Y;
    }
};

The syntax of the TCustomGrdi::MouseCoord() method is:

TGridCoord __fastcall MouseCoord(int X, int Y);

This method also is usually used in a mouse event. It takes as arguments the mouse position. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1MouseDown(TObject *Sender,
			TMouseButton Button, TShiftState Shift, int X, int Y)
{
    TGridCoord GC = StringGrid1->MouseCoord(X, Y);
    Label1->Caption = "Col: " + AnsiString(GC.X) + L" Row: " + AnsiString(GC.Y);
}
//---------------------------------------------------------------------------

Just before the user selects the content of a cell, the control fires the OnSelectCell() event. Its syntax is:

void __fastcall OnSelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect)

The ACol and ARow arguments represent the cell that is about to be selected. The CanSelect argument allows you to specify whether the user is allowed to select the content of the cell. This event allows you to decide whether the cell can be selected or not. The following event is used to let the user know that a certain cell cannot be accessed:

//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol,
					      int ARow, bool &CanSelect)
{
    if( ACol == 2 && ARow == 4 )
    {
    	ShowMessage(L"The content of this cell is not accessible.\n"
		    L"Please select another cell!");
	return;
    }
}
//---------------------------------------------------------------------------

If the user has selected a cell and wants to edit its content, you can find out the content of such a cell using the OnGetEditText() event:

void OnGetEditText(TObject *Sender, int ACol, int ARow, UnicodeString &Value)

This even fires as soon as the user has selected text included in a cell but just before the user has had a chance to edit it. This means that you can determine whether the user is allowed to change the contents of a particular cell. When this event fires, it communicates the grid coordinates of the cell that was clicked, allowing you to retrieve the content of that cell and do what you want. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1GetEditText(TObject *Sender, int ACol,
						int ARow, AnsiString &Value)
{
    UnicodeString Content = StringGrid1->Cells[ACol][ARow];
    Label1->Caption = Content;
}
//---------------------------------------------------------------------------

On the other hand, when the user has changed the content of a cell, the string grid fires an OnSetEditText() event:

void OnSetEditText(TObject *Sender, int ACol, int ARow,
		   const UnicodeString Value)

This is a good place to validate, accept, or reject the changes that the user has performed. This event also provides you with the grid coordinates of the cell whose contents the user has modified.

To better control what type of text the user is allowed to enter in a cell, in all cells of a particular row, or in all cells of a particular column, you can use the OnGetEditMask() event. Its syntax is:

void __fastcall OnGetEditMask(TObject *Sender,
			      int ACol, int ARow,
 			      AnsiString &Value)

The ACol and the ARow parameters represent the grid indexes of the cell. The Value is a string of the same type used for the EditMask property of the mask edit control. This event is used to set the EditMask needed for a particular cell. The following event restricts only US Social Security Numbers in all cells of the second column:

//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1GetEditMask(TObject *Sender, int ACol,
					       int ARow, AnsiString &Value)
{
    if( StringGrid1->Col == 2 )
	Value = "000-00-0000";
}
//---------------------------------------------------------------------------

If you had let the compiler know that you would set the appearance of cells yourself, which would have been communicated by setting the DefaultDrawing property to False, you can use the OnDrawCell event to perform this customization. The syntax of this event is:

void __fastcall StringGridDrawCell(TObject *Sender, 
				   int ACol,
 				   int ARow,
				   TRect &Rect, 
				   TGridDrawState State)

The cell whose characteristics need to be set is cell[ACol][ARow]. This means that you can locate any cell in the grid and set its properties as you like and as possible. For example, you can change the individual background color of a cell. The following code changes the background color of cell[3][2] to blue:

//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender,
					    int ACol, int ARow,
  					   TRect &Rect,
		  			   TGridDrawState State)
{
    if( ACol == 3 && ARow == 2 )
    {
	StringGrid1->Canvas->Brush->Color = clBlue;
	StringGrid1->Canvas->FillRect(Rect);
    }
}
//---------------------------------------------------------------------------

In the same way, you can change the text color of any cell of your choice independently of the other cells. The Rect parameter is the location and dimension of the cell whose characteristics you want to change. The State argument is a member of the TGridDrawState set which is defined as follows:

enum Grids__3 { gdSelected, gdFocused, gdFixed };
typedef Set<Grids_3, gdSelected, gdFixed> TGridDrawState;arajust"

This set allows you to examine the state of a particular cell. Because this value is a set, a particular cell can have more than one of these values. If a cell is selected, which by default gives it a background color different than the others, then its State contains the gdSelected value. If a cell has focus, which could mean that the user has just clicked it, sometimes to edit, the cell has the gdFocused value. Note that a cell can be selected and have focus, which means it would have both gdSelected and gdFocused. If a cell is a fixed cell as we described previously, then the cell has the gdFixed value. Here is an example of using the OnDrawCell event to customize the appearance of a string grid:

//---------------------------------------------------------------------------
#include <vcl.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
    StringGrid1->DefaultDrawing = False;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
					    int ARow, TRect &Rect,
					    TGridDrawState State)
{
    if( State.Contains(gdFixed) )
    {
	StringGrid1->Canvas->Brush->Color = static_cast<TColor>(RGB(255, 155, 0));
	StringGrid1->Canvas->Font->Style = TFontStyles() << fsBold;
	StringGrid1->Canvas->Font->Color = static_cast<TColor>(RGB(250, 245, 135));
	StringGrid1->Canvas->Rectangle(Rect);
    }
    else if( State.Contains(gdSelected) )
    {
	StringGrid1->Canvas->Brush->Color = static_cast<TColor>(RGB(255, 205, 155));
	StringGrid1->Canvas->Font->Style = TFontStyles() >> fsBold;
	StringGrid1->Canvas->Font->Color = clNavy;
	StringGrid1->Canvas->FillRect(Rect);
    }
    else
    {
	StringGrid1->Canvas->Brush->Color = clWhite;
	StringGrid1->Canvas->Font->Color = clBlue;
	StringGrid1->Canvas->FillRect(Rect);
    }
    
    StringGrid1->ColWidths[0] = 15;
    StringGrid1->ColWidths[1] = 75;
    StringGrid1->ColWidths[2] = 75;
    StringGrid1->ColWidths[3] = 90;
    StringGrid1->ColWidths[4] = 120;
    StringGrid1->RowHeights[0] = 16;
    StringGrid1->RowHeights[1] = 16;
    StringGrid1->RowHeights[2] = 16;
    StringGrid1->RowHeights[3] = 16;
    StringGrid1->RowHeights[4] = 16;
    UnicodeString text = StringGrid1->Cells[ACol][ARow];
    StringGrid1->Canvas->TextRect(Rect, Rect.Left, Rect.Top, text);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    StringGrid1->Cells[0][1] = "1";
    StringGrid1->Cells[0][2] = "2";
    StringGrid1->Cells[0][3] = "3";
    StringGrid1->Cells[0][4] = "4";
    StringGrid1->Cells[1][0] = "First Name";
    StringGrid1->Cells[2][0] = "Last Name";
    StringGrid1->Cells[3][0] = "Phone Number";
    StringGrid1->Cells[4][0] = "Email Address";
    StringGrid1->Cells[1][1] = "Alex";
    StringGrid1->Cells[2][1] = "Walters";
    StringGrid1->Cells[3][1] = "(202) 133-7402";
    StringGrid1->Cells[4][1] = "waltersa88@yahoo.com";
    StringGrid1->Cells[1][2] = "Bertrand";
    StringGrid1->Cells[2][2] = "Kumar";
    StringGrid1->Cells[4][2] = "kumarb@mailman.com";
    StringGrid1->Cells[3][3] = "Hermine";
}
//---------------------------------------------------------------------------

Grid

Practical LearningPractical Learning: Using a String

  1. In the Structure window, click the name of the form
  2. In the Object Inspector, click Events
  3. Double-click the right side of OnCreate
  4. Implement the event as follows:
    //---------------------------------------------------------------------------
    #include <vcl.h>
    #include <math.hpp>
    #pragma hdrstop
    
    #include "Evaluation.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TfrmEvaluation *frmEvaluation;
    //---------------------------------------------------------------------------
    __fastcall TfrmEvaluation::TfrmEvaluation(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmEvaluation::FormCreate(TObject *Sender)
    {
    	grdDoubleDecliningBalance->Cells[1][0] = "Year";
    	grdDoubleDecliningBalance->ColWidths[2] = 100;
    	grdDoubleDecliningBalance->Cells[2][0] = "Yearly Depreciation";
    	grdDoubleDecliningBalance->ColWidths[3] = 100;
    	grdDoubleDecliningBalance->Cells[3][0] = "Current Value";
    
    	grdStraightLineMethod->Cells[1][0] = "Year";
    	grdStraightLineMethod->ColWidths[2] = 100;
    	grdStraightLineMethod->Cells[2][0] = "Yearly Depreciation";
    	grdStraightLineMethod->ColWidths[3] = 100;
    	grdStraightLineMethod->Cells[3][0] = "Current Value";
    
    	grdSumOfYears->Cells[1][0] = "Year";
    	grdSumOfYears->ColWidths[2] = 100;
    	grdSumOfYears->Cells[2][0] = "Yearly Depreciation";
    	grdSumOfYears->ColWidths[3] = 100;
    	grdSumOfYears->Cells[3][0] = "Current Value";
    }
    //---------------------------------------------------------------------------
  5. Press F12 to return to the form
  6. On the form, double-click the Evaluate button
  7. Implement the event as follows:
  8. Implement the above method as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmEvaluation::btnEvaluateClick(TObject *Sender)
    {
    	int Life;
    	Extended Depreciation, Cost, Salvage;
    
    	Cost = StrToFloat(edtCost->Text);
    	Salvage = StrToFloat(edtSalvage->Text);
    	Life = StrToInt(edtLife->Text);
    
    	grdDoubleDecliningBalance->RowCount = Life + 1;
    	grdStraightLineMethod->RowCount     = Life + 1;
    	grdSumOfYears->RowCount             = Life + 1;
    
    	double DDBCurrentValue = Cost;
    	for(int i = 1; i <= Life; i++)
    	{
    		Depreciation = DoubleDecliningBalance(Cost, Salvage, Life, i);
    		DDBCurrentValue -= Depreciation;
    
    		grdDoubleDecliningBalance->Cells[1][i] = i;
    		grdDoubleDecliningBalance->Cells[2][i] =
    				FloatToStrF(Depreciation, ffCurrency, 8, 2);
    		grdDoubleDecliningBalance->Cells[3][i] =
    				FloatToStrF(DDBCurrentValue, ffCurrency, 8, 2);
    	}
    
    	Depreciation = SLNDepreciation(Cost, Salvage, Life);
    	double SLNCurrentValue = Cost;
    
    	for(int i = 1; i <= Life; i++)
    	{
    		SLNCurrentValue -= Depreciation;
    
    		grdStraightLineMethod->Cells[1][i] = i;
    		grdStraightLineMethod->Cells[2][i] =
    				FloatToStrF(Salvage, ffCurrency, 8, 2);
    		grdStraightLineMethod->Cells[3][i] =
    				FloatToStrF(SLNCurrentValue, ffCurrency, 8, 2);
    	}
    
    	double SYDCurrentValue = Cost;
    	for(int i = 1; i <= Life; i++)
    	{
    		Depreciation = SYDDepreciation(Cost, Salvage, Life, i);
    		SYDCurrentValue -= Depreciation;
    
    		grdSumOfYears->Cells[1][i] = i;
    		grdSumOfYears->Cells[2][i] =
    				FloatToStrF(Depreciation, ffCurrency, 8, 2);
    		grdSumOfYears->Cells[3][i] =
    				FloatToStrF(SYDCurrentValue, ffCurrency, 8, 2);
    	}
    }
    //---------------------------------------------------------------------------
  9. Press F12 to display the form
  10. In the Original Item Price edit box, type 12450.00 and press Tab
  11. In the Salvage edit box, type 980.00 and press Tab
  12. In the Estimated Life edit box, type 10
  13. Click the Evaluate button
     
    Depreciation
  14. Enter new values in the edit boxes
     
    Depreciation
  15. Close the form and return to your programming environment
 
 
   
 

Home Copyright © 2010-2011 FunctionX, Inc.