Another approach for using covered cells as a recurring pattern (e.g. covered cells are the same for each row).

// As the covered cells are the same for each row,
// I suggest creating one array of ROWCOLS
// It is like a pattern   (very similar to the "quicken-like
// rows" FAQ.
ROWCOL awCoverCols[] = {
      // start, end
      2, 10,
      12, 20,
      22, 30,
      32, 40,
      42, 50,
      52, 60,
      62, 70,
      72, 85,
      0, 0   // end of list
   };

CGXRange* C1stGridView::GetCoveredCellsRowCol(ROWCOL nRow, ROWCOL nCol, CGXRange& range)
{
   if (nRow > 0)
   // if (nRow > 0 && nRow % 2 == 0) // apply pattern to every second row only
      // (just for testing here)
   {
      for (int n = 0; awCoverCols[n] > 0; n+=2)
      {
         if (nCol >= awCoverCols[n] && nCol <= awCoverCols[n+1])
         {
            range.SetCells(nRow, awCoverCols[n], nRow, awCoverCols[n+1]);
            return &range;
         }
      }
   }
   // normal cell, not covered:
   return NULL;
}
void C1stGridView::MergeCoveredCells(CGXRange& area)
{
   if (area.bottom > 0)
   // if (area.GetHeight() > 1 || area.top % 2 == 0 && area.top > 0)
      // // apply pattern to every second row only
      // (just for testing here)
   {
      for (int n = 0; awCoverCols[n] > 0; n+=2)
      {
         if (area.left >= awCoverCols[n] && area.left <= awCoverCols[n+1])
            area.left = awCoverCols[n];
            
         if (area.right >= awCoverCols[n] && area.right <= awCoverCols[n+1])
            area.right = awCoverCols[n+1];
      }
   }
}