Can I display a message-box from within OnValidateCell?

The easiest way is to override OnValidateCell and call SetWarningText. This technique is illustrated in the first example:

// validate input
BOOL CDerGrid::OnValidateCell(ROWCOL nRow, ROWCOL nCol)
{
   CString s;
   CGXControl* pControl = GetControl(nRow, nCol);
   pControl->GetCurrentText(s);
   if (!s.IsEmpty( ))
   {
      if (_ttoi(s) < 1 || _ttoi(s) > 100)
      {
         SetWarningText (_T("Please enter a value between 1 and 100!"));
         return FALSE;
      }
      return TRUE;
   }
   return CGXGridView::OnValidateCell(nRow, nCol);
}

The second example displays a message box and also demonstrates how to correct the value or reset the cell to its previous value. Please note that we check the m_bLockActivateGrid before we display a message box. This avoids a message box being displayed when the grid loses focus because a user hit the “Cancel” key in a dialog.

BOOL CSample2GridWnd::OnValidateCell(ROWCOL nRow, ROWCOL nCol)
{
   CString s;
   // retrieve text from current cell
   CGXControl* pControl = GetControl(nRow, nCol);
   pControl->GetCurrentText(s);
   if (_ttol(s) < 0 || _ttol(s) > 100)
   {
      TCHAR sz[255];
      wsprintf(sz, _T("Please enter a value between 0 and 100!"));
      ScrollCellInView(nRow, nCol);
      // Display message box
      if (m_bLockActivateGrid)
      {
         AfxMessageBox(sz);
         // m_bWarningTextDisplayed is looked up in OnLButtonHitRowCol
         // if you set this TRUE, OnLButtonHitRowCol will cancel any further mouse processing
         m_bWarningTextDisplayed = TRUE;
         // If you want the current cell to be undone, call
         // TransferCurrentCell(FALSE);
         // This is only a sample. You might also display a message box
         // and ask the user if he wants to retry or ignore the value or
         // you could also call pControl->SetCurrentText() to change
         // the value.
         // pControl->SetCurrentText("22");
      }
      // else do nothing, the focus will go back to the current cell
      return FALSE;
   }
   return TRUE;
}

The third example displays a message box and lets the user choose Yes, No or Cancel.

BOOL CGridSample9View::OnValidateCell(ROWCOL nRow, ROWCOL nCol)
{
   CString s;
   // retrieve text from current cell
   CGXControl* pControl = GetControl(nRow, nCol);
   pControl->GetCurrentText(s);
   // Display message box
   if (m_bLockActivateGrid)
   {
      int result = AfxMessageBox(s, MB_YESNOCANCEL);
      // m_bWarningTextDisplayed is looked up in OnLButtonHitRowCol
      // if you set this TRUE, OnLButtonHitRowCol will cancel any further mouse processing
      m_bWarningTextDisplayed = TRUE;
   
      // If Yes then move to next cell.......
      if(result == IDYES)
         return TRUE;
      // If No then clear the current text and return to the current cell
      else if(result == IDNO)
      {
         TransferCurrentCell(FALSE);
         return FALSE;
      }
      // if cancel, then return to the current cell for further editing.
      else if(result = IDCANCEL)
         return FALSE;
   }
   return TRUE;
}