The BrwsGrid Program
This section examines the BrwsGrid program you just ran. The grid in this program displays and allows you to edit the data stored in the data member m_data of the document.
In the following sections, code modules are followed by the explanations of the comments.
Initialization and Setting Column Count
void CBrwsGridView::OnInitialUpdate()
{
CGXBrowserView::OnInitialUpdate();
LockUpdate(TRUE);
GetParam()->EnableUndo(FALSE);
InitBrowserSettings(); //1
GetParam()->EnableTrackRowHeight();
SetColCount(
GetDocument()->m_data.GetColCount()); //2
SetStyleRange(CGXRange().SetCols(4),
CGXStyle().SetControl(GX_IDS_CTRL_CHECKBOX)); //3
SetStyleRange(CGXRange().SetCols(1),
CGXStyle().SetInterior(RGB(150,150,150)));
SetStyleRange(CGXRange().SetCols(2),
CGXStyle().SetTextColor(RGB(0,0,255)));
for(ROWCOL col = 1; col <=
GetDocument()->m_data.GetColCount(); col++) //4
{
SetValueRange(CGXRange(0, col),
GetDocument()->m_data.GetValueRowCol(0, col));
}
GetParam()->SetSortRowsOnDblClk(TRUE);
GetParam()->EnableUndo(TRUE);
LockUpdate(FALSE);
Redraw();
}
Supplying the Row Count Dynamically
// Supply the record count to the grid.
long CBrwsGridView::OnGetRecordCount()
{
return GetDocument()->m_data.GetRowCount(); //1
}
Managing Sorted Rows and Moved Columns
short CBrwsGridView::GetFieldFromCol(ROWCOL nCol)
{
return (short)
(GetColIndex(nCol) - GetHeaderCols()); //1
}
long CBrwsGridView::GetRecordFromRow(ROWCOL nRow)
{
return (long) GetRowIndex(nRow) -
(long) GetHeaderRows(); //2
}
Supplying the Value To the Grid and Storing the Changes
BOOL CBrwsGridView::OnLoadCellStyle(ROWCOL nRow, ROWCOL nCol, CGXStyle & style,
LPCTSTR pszExistingValue)
{
int nField = GetFieldFromCol(nCol); // 1
if (pszExistingValue == NULL && nRow >= GetFirstRow())// 2
{
if (!m_bNoValueNeeded && nField != -1 && nField <= (short)
GetDocument()->m_data.GetColCount()) // 3
{
style.SetValue(GetDocument()->m_data.GetValueRowCol(
GetRecordFromRow(nRow), nField));// 4
}
else
style.SetEnabled(FALSE);
}
return TRUE;
}
void CBrwsGridView::OnFlushCellValue(ROWCOL nRow, ROWCOL nCol,
LPCTSTR pszChangedValue) // 5
{
// cannot handle this.
if (pszChangedValue == NULL)
return;
int nField = GetFieldFromCol(nCol);
if (nField <= 0 || nField > (short)
GetDocument()->m_data.GetColCount()) // 6
{
SetWarningText(_T(
"You have tried to modify the value of an unbound field!"));
AfxThrowNotSupportedException();
return;
}
GetDocument()->m_data.StoreValueRowCol(GetRecordFromRow(nRow),
nField, pszChangedValue, gxOverride); //7
}
Deleting Rows
Override DeleteRows(), as shown in the tutorial sample code. The code is not discussed here line by line, since it is very elaborate. Please refer to the source code in the sample project for detailed information.
Basically, this code deals with the issue of deleting multiple non-contiguous rows. The problem is that as soon as you delete a row, the index of any row that is to be deleted (and that is below the current deleted row) becomes invalid.
It resolves the issue by deleting rows one at a time from bottom up, so that all the indexes for the rows to be deleted remain valid.
It also updates the internal data structure that is a map of the current moved rows to their original position before they were moved.