CGXGridCore::OnTestGridDimension

virtual void OnTestGridDimension(ROWCOL nLastRow, ROWCOL nLastCol);

nLastRow

Specifies the row to be tested against the real grid dimension. If you specify GX_MAXROWCOL, the exact row count will be determined.

nLastCol

Specifies the column to be tested against the real grid dimension. If you specify GX_MAXROWCOL, the exact column count will be determined.

Remarks

In some situations the row count or column count is not known in advance and therefore needs to be estimated. If you are browsing the CRecordset of an ODBC data source, the CRecordset only returns a high water mark for the record count. This high water mark will increase when you scroll through the CRecordset.

In such a situation, you should estimate the row count. This can be done by overriding GetRowCount and returning the value of the high water mark. This estimation works well as long as the estimated row count will not go over the last record in the CRecordset. OnTestGridDimension is the solution for this problem.

OnTestGridDimension is called whenever Objective Grid wants to be sure that the grid will not go over the last valid row or column.

For example, if you scroll down one page, OnGridDraw determines the cells to be drawn by calculating the bottom row and the right column visible in the window. Before the cells are drawn, OnGridDraw calls OnTestGridDimension to ensure that the bottom row and right column are valid coordinates. If they would go over the last row or column, subsequent calls to GetRowCount or GetColCount will no longer return values greater than the last row or column. See the example.

If you want to ensure that the grid returns the exact row or column count and not only an estimated row or column count, you should call OnTestGridDimension(GX_MAXROWCOL, GX_MAXROWCOL).

Example

This example illustrates how the row count is estimated in CGXODBCGrid.
GetRowCount adds an extra page of rows to the row count if CRecordset only returns a high water mark.

OnTestGridDimension loops though the records. If nLastRow would go over the last record, a flag is set indicating that all records have been seen, and in subsequent calls to GetRowCount the record count no longer needs to be estimated.

void CGXODBCGrid::OnTestGridDimension(ROWCOL nLastRow, ROWCOL nLastCol)
{
   CRecordset* pRecordset = OnGetRecordset( );
   CGXDbParam* pBrowseData = GetDbParam( );
   if (pBrowseData->m_bEOFSeen || pRecordset == NULL || !pRecordset->IsOpen( ))
      return;
   long lRecord = -1;
   if (nLastRow < LONG_MAX)
      lRecord = GetRecordFromRow(nLastRow);
   else
      lRecord = LONG_MAX;
   // NOTE: if nLastRow is equal to GX_MAXROWCOL, lRecord is -1
   if (OnGetRecordCount( ) != LONG_MAX // Record count is already known
      || lRecord <= pBrowseData->m_nRecordLastSeen) // record is already checked
      return;
   // check if GetRecordCount( ) works correctly
   pBrowseData->m_nRecordCount = pRecordset ? pRecordset->GetRecordCount( ) : 0;
   // the record count should increase with a given increment, e.g. 500 rows at a time
   if (lRecord != LONG_MAX && pBrowseData->m_nRecordCountInc > 1 && lRecord > 0)
      // rounds up lRecord to the next possible increment
      lRecord = ((lRecord-1) / pBrowseData->m_nRecordCountInc + 1) * pBrowseData->m_nRecordCountInc;
   BOOL bWait = FALSE;
   // First case: is record set empty?
   if (pRecordset == NULL || pRecordset->IsBOF( ) && pRecordset->IsEOF( ))
   {
      pBrowseData->m_bEOFSeen = TRUE;
      pBrowseData->m_nRecordLastSeen = -1;
   }
   // Second case: we use CRecordset::GetRecordCount as high water mark
   else
   {
      long nRecordLastSeen = pBrowseData->m_nRecordCount-1;
      CRecordsetStatus rs;
      pRecordset->GetStatus(rs);
      TRY
      {
         long lMove = nRecordLastSeen-rs.m_lCurrentRecord;
         if (lMove != 0)
         {
            // display wait cursor
            bWait = labs(nRecordLastSeen-lRecord) > pBrowseData->m_lMoveRecordWaitCursor;
            if (bWait)
               AfxGetApp( )->BeginWaitCursor( );
            pRecordset->Move(lMove);
         }
         // and try to position to record lRecord
         while (nRecordLastSeen < lRecord && !pRecordset->IsEOF( ))
         {
            pRecordset->MoveNext( );
            nRecordLastSeen = pRecordset->GetRecordCount( )-1;
         }
      }
      CATCH(CDBException, e)
      {
         // Trace then the reason it failed to move to the specified record
         TRACE(e->m_strError);
         // e->Delete( );
      }
      END_CATCH
      // Now, save the record
      pBrowseData->m_nRecordLastSeen = pRecordset->GetRecordCount( )-1;
      pBrowseData->m_bEOFSeen = pRecordset->IsEOF( );
   }
   if (bWait)
      AfxGetApp( )->EndWaitCursor( );
   TRACE(_T("OnTestGridDimension(%lu, %lu)"), nLastRow, nLastCol);
   TRACE(_T("m_bEOFSeen = %d, m_nRecordLastSeen = %ld\n"), pBrowseData->m_bEOFSeen, pBrowseData->m_nRecordLastSeen);
   // Unused:
   nLastCol;
}
// OnGetRecordCount( )
//
// This method returns the number of records if last record has been accessed
// or LONG_MAX if record count is undetermined.
//
// If you know the exact record count in advance (maybe by using a "SELECT COUNT(*)"),
// you can override this method and return the record count.
//
long CGXODBCGrid::OnGetRecordCount( )
{
   CRecordset* pRecordset = OnGetRecordset( );
   CGXBrowseParam* pBrowseData = GetBrowseParam( );
   if (pRecordset == NULL || !pRecordset->IsOpen( ))
      return 0;
   // check if record count is known
   if (pBrowseData->m_bEOFSeen)
      return pBrowseData->m_nRecordLastSeen+1;
   // last record has not been seen yet, record count is unknown
   return LONG_MAX;
}

See Also

 CGXGridCore::OnGridDraw  CGXGridCore::OnGridPrint  CGXGridCore::UpdateScrollbars

CGXGridCore

 Class Overview |  Class Members