From 6d5796902a980f189f470a4e8ea7084548c52f49 Mon Sep 17 00:00:00 2001
From: KEJ <kimeungju@diteam.co.kr>
Date: 월, 26 6월 2023 17:43:48 +0900
Subject: [PATCH] Ongoing80 #4528 CF AOI Review Motor Offset 기능 추가 1. Motor Offset 설정 Dlg 추가. 2. Offset 파라미터 추가. 3. Motor Offset 기능 적용

---
 Internal_Library/CHCommonControls/GridCtrl.cpp |  623 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 467 insertions(+), 156 deletions(-)

diff --git a/Internal_Library/CHCommonControls/GridCtrl.cpp b/Internal_Library/CHCommonControls/GridCtrl.cpp
index b486b5a..16e6e73 100644
--- a/Internal_Library/CHCommonControls/GridCtrl.cpp
+++ b/Internal_Library/CHCommonControls/GridCtrl.cpp
@@ -190,6 +190,28 @@
 /////////////////////////////////////////////////////////////////////////////
 // CGridCtrl
 
+CCellID CGridCtrl::GetMergeCellID(CCellID cell)
+{
+	CGridCellBase *pCell = (CGridCellBase*)GetCell(cell);
+	if (pCell && pCell->IsMergeWithOthers())
+		return pCell->GetMergeCellID();
+	return cell;
+}
+
+int  CGridCtrl::GetMergeCellHeight(CCellID cell)
+{
+	CCellID mergecell = GetMergeCellID(cell);
+	CGridCellBase *pCell = (CGridCellBase*)GetCell(mergecell);
+	if (!pCell->IsMerged())
+		return GetRowHeight(cell.row);
+	int height = 0;
+	for (int mergerow = pCell->GetMergeRange().GetMaxRow();mergerow >= pCell->GetMergeRange().GetMinRow();mergerow--)
+	{
+		height += GetRowHeight(mergerow);
+	}
+	return height;
+}
+
 CGridCtrl::CGridCtrl(int nRows, int nCols, int nFixedRows, int nFixedCols)
 {
     RegisterWindowClass();
@@ -330,8 +352,10 @@
 
     if (!(::GetClassInfo(hInst, GRIDCTRL_CLASSNAME, &wndcls)))
     {
-        // otherwise we need to register a new class
-        wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+		// otherwise we need to register a new class
+		//< SWK 20201123 - #2803 MOD >
+//		wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+		wndcls.style            = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
         wndcls.lpfnWndProc      = ::DefWindowProc;
         wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
         wndcls.hInstance        = hInst;
@@ -1650,178 +1674,343 @@
     if (GetVirtualMode())
         SendCacheHintToParent(VisCellRange);
 
-    // draw top-left cells 0..m_nFixedRows-1, 0..m_nFixedCols-1
-    rect.bottom = -1;
-    for (row = 0; row < m_nFixedRows; row++)
-    {
-        if (GetRowHeight(row) <= 0) continue;
+	CPen pen;
+	pen.CreatePen(PS_SOLID, 0, m_crGridLineColour);
+	pDC->SelectObject(&pen);
 
-        rect.top = rect.bottom+1;
-        rect.bottom = rect.top + GetRowHeight(row)-1;
-        rect.right = -1;
+	// draw vertical lines (drawn at ends of cells)
+	if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
+	{
+		int x = nFixedColWidth;
+		for (col = minVisibleCol; col <= maxVisibleCol; col++)
+		{
+			if (GetColumnWidth(col) <= 0) continue;
 
-        for (col = 0; col < m_nFixedCols; col++)
-        {
-            if (GetColumnWidth(col) <= 0) continue;
+			x += GetColumnWidth(col);
+			pDC->MoveTo(x - 1, nFixedRowHeight);
+			pDC->LineTo(x - 1, VisRect.bottom);
+		}
+	}
 
-            rect.left = rect.right+1;
-            rect.right = rect.left + GetColumnWidth(col)-1;
+	// draw horizontal lines (drawn at bottom of each cell)
+	if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
+	{
+		int y = nFixedRowHeight;
+		for (row = minVisibleRow; row <= maxVisibleRow; row++)
+		{
+			if (GetRowHeight(row) <= 0) continue;
 
-            pCell = GetCell(row, col);
-            if (pCell)
+			y += GetRowHeight(row);
+			pDC->MoveTo(nFixedColWidth, y - 1);
+			pDC->LineTo(VisRect.right, y - 1);
+		}
+	}
+
+	pDC->SelectStockObject(NULL_PEN);
+
+	// draw rest of non-fixed cells
+	rect.bottom = nFixedRowHeight - 1;
+	for (row = minVisibleRow; row <= maxVisibleRow; row++)
+	{
+		if (GetRowHeight(row) <= 0) continue;
+
+		rect.top = rect.bottom + 1;
+		rect.bottom = rect.top + GetRowHeight(row) - 1;
+
+		// rect.bottom = bottom pixel of previous row
+		if (rect.top > clipRect.bottom)
+			break;                // Gone past cliprect
+		if (rect.bottom < clipRect.top)
+			continue;             // Reached cliprect yet?
+
+		rect.right = nFixedColWidth - 1;
+		for (col = minVisibleCol; col <= maxVisibleCol; col++)
+		{
+			if (GetColumnWidth(col) <= 0) continue;
+
+			rect.left = rect.right + 1;
+			rect.right = rect.left + GetColumnWidth(col) - 1;
+
+			if (rect.left > clipRect.right)
+				break;        // gone past cliprect
+			if (rect.right < clipRect.left)
+				continue;     // Reached cliprect yet?
+
+			pCell = GetCell(row, col);
+			// TRACE(_T("Cell %d,%d type: %s\n"), row, col, pCell->GetRuntimeClass()->m_lpszClassName);
+			if (pCell)
 			{
-				pCell->SetCoords(row,col);
-                pCell->Draw(pDC, row, col, rect, FALSE);
+				//Used for merge cells
+				//by Huang Wei
+
+				if (!pCell->IsMerged())
+				{
+					if (!pCell->IsMergeWithOthers())
+					{
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, rect, FALSE);
+					}
+					else
+					{
+						CGridCellBase* pMergedCell = GetCell(pCell->GetMergeCellID());
+						CRect mergerect = rect;
+						if (GetCellRangeRect(pMergedCell->m_MergeRange, &mergerect))
+						{
+							mergerect.DeflateRect(0, 0, 1, 1);
+							pMergedCell->SetCoords(pCell->GetMergeCellID().row, pCell->GetMergeCellID().col);
+							pMergedCell->Draw(pDC, pCell->GetMergeCellID().row, pCell->GetMergeCellID().col, mergerect, TRUE);
+						}
+					}
+				}
+				else
+				{
+					CRect mergerect = rect;
+
+					if (GetCellRangeRect(pCell->m_MergeRange, &mergerect))
+					{
+						mergerect.DeflateRect(0, 0, 1, 1);
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, mergerect, TRUE);
+					}
+				}
 			}
-        }
-    }
+		}
+	}
 
-    // draw fixed column cells:  m_nFixedRows..n, 0..m_nFixedCols-1
-    rect.bottom = nFixedRowHeight-1;
-    for (row = minVisibleRow; row <= maxVisibleRow; row++)
-    {
-        if (GetRowHeight(row) <= 0) continue;
+	// draw fixed column cells:  m_nFixedRows..n, 0..m_nFixedCols-1
+	rect.bottom = nFixedRowHeight - 1;
+	for (row = minVisibleRow; row <= maxVisibleRow; row++)
+	{
+		if (GetRowHeight(row) <= 0) continue;
 
-        rect.top = rect.bottom+1;
-        rect.bottom = rect.top + GetRowHeight(row)-1;
+		rect.top = rect.bottom + 1;
+		rect.bottom = rect.top + GetRowHeight(row) - 1;
 
-        // rect.bottom = bottom pixel of previous row
-        if (rect.top > clipRect.bottom)
-            break;                // Gone past cliprect
-        if (rect.bottom < clipRect.top)
-            continue;             // Reached cliprect yet?
+		// rect.bottom = bottom pixel of previous row
+		if (rect.top > clipRect.bottom)
+			break;                // Gone past cliprect
+		if (rect.bottom < clipRect.top)
+			continue;             // Reached cliprect yet?
 
-        rect.right = -1;
-        for (col = 0; col < m_nFixedCols; col++)
-        {
-            if (GetColumnWidth(col) <= 0) continue;
+		rect.right = -1;
+		for (col = 0; col < m_nFixedCols; col++)
+		{
+			if (GetColumnWidth(col) <= 0) continue;
 
-            rect.left = rect.right+1;
-            rect.right = rect.left + GetColumnWidth(col)-1;
+			rect.left = rect.right + 1;
+			rect.right = rect.left + GetColumnWidth(col) - 1;
 
-            if (rect.left > clipRect.right)
-                break;            // gone past cliprect
-            if (rect.right < clipRect.left)
-                continue;         // Reached cliprect yet?
+			if (rect.left > clipRect.right)
+				break;            // gone past cliprect
+			if (rect.right < clipRect.left)
+				continue;         // Reached cliprect yet?
 
-            pCell = GetCell(row, col);
-            if (pCell)
+			pCell = GetCell(row, col);
+			//         if (pCell)
+					 //{
+					 //	pCell->SetCoords(row,col);
+			//             pCell->Draw(pDC, row, col, rect, TRUE);
+					 //}
+			if (pCell)
 			{
-				pCell->SetCoords(row,col);
-                pCell->Draw(pDC, row, col, rect, FALSE);
+				//Used for merge cells
+				//by Huang Wei
+
+				if (!pCell->IsMerged())
+				{
+					if (!pCell->IsMergeWithOthers())
+					{
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, rect, FALSE);
+					}
+					else
+					{
+						CGridCellBase* pMergedCell = GetCell(pCell->GetMergeCellID());
+						CRect mergerect = rect;
+						if (GetCellRangeRect(pMergedCell->m_MergeRange, &mergerect))
+						{
+							mergerect.DeflateRect(0, 0, 1, 1);
+							pMergedCell->SetCoords(pCell->GetMergeCellID().row, pCell->GetMergeCellID().col);
+							pMergedCell->Draw(pDC, pCell->GetMergeCellID().row, pCell->GetMergeCellID().col, mergerect, TRUE);
+						}
+					}
+				}
+				else
+				{
+					CRect mergerect = rect;
+
+					if (GetCellRangeRect(pCell->m_MergeRange, &mergerect))
+					{
+						mergerect.DeflateRect(0, 0, 1, 1);
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, mergerect, TRUE);
+					}
+				}
 			}
-        }
-    }
+		}
+	}
 
-    // draw fixed row cells  0..m_nFixedRows, m_nFixedCols..n
-    rect.bottom = -1;
-    for (row = 0; row < m_nFixedRows; row++)
-    {
-        if (GetRowHeight(row) <= 0) continue;
+	// draw fixed row cells  0..m_nFixedRows, m_nFixedCols..n
+	rect.bottom = -1;
+	for (row = 0; row < m_nFixedRows; row++)
+	{
+		if (GetRowHeight(row) <= 0) continue;
 
-        rect.top = rect.bottom+1;
-        rect.bottom = rect.top + GetRowHeight(row)-1;
+		rect.top = rect.bottom + 1;
+		rect.bottom = rect.top + GetRowHeight(row) - 1;
 
-        // rect.bottom = bottom pixel of previous row
-        if (rect.top > clipRect.bottom)
-            break;                // Gone past cliprect
-        if (rect.bottom < clipRect.top)
-            continue;             // Reached cliprect yet?
+		// rect.bottom = bottom pixel of previous row
+		if (rect.top > clipRect.bottom)
+			break;                // Gone past cliprect
+		if (rect.bottom < clipRect.top)
+			continue;             // Reached cliprect yet?
 
-        rect.right = nFixedColWidth-1;
-        for (col = minVisibleCol; col <= maxVisibleCol; col++)
-        {
-            if (GetColumnWidth(col) <= 0) continue;
+		rect.right = nFixedColWidth - 1;
+		for (col = minVisibleCol; col <= maxVisibleCol; col++)
+		{
+			if (GetColumnWidth(col) <= 0) continue;
 
-            rect.left = rect.right+1;
-            rect.right = rect.left + GetColumnWidth(col)-1;
+			rect.left = rect.right + 1;
+			rect.right = rect.left + GetColumnWidth(col) - 1;
 
-            if (rect.left > clipRect.right)
-                break;        // gone past cliprect
-            if (rect.right < clipRect.left)
-                continue;     // Reached cliprect yet?
+			if (rect.left > clipRect.right)
+				break;        // gone past cliprect
+			if (rect.right < clipRect.left)
+				continue;     // Reached cliprect yet?
 
-            pCell = GetCell(row, col);
-            if (pCell)
+			pCell = GetCell(row, col);
+			//         if (pCell)
+					 //{
+					 //	pCell->SetCoords(row,col);
+			//             pCell->Draw(pDC, row, col, rect, TRUE);
+					 //}
+			if (pCell)
 			{
-				pCell->SetCoords(row,col);
-                pCell->Draw(pDC, row, col, rect, FALSE);
+				//Used for merge cells
+				//by Huang Wei
+
+				if (!pCell->IsMerged())
+				{
+					if (!pCell->IsMergeWithOthers())
+					{
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, rect, FALSE);
+					}
+					else
+					{
+						CGridCellBase* pMergedCell = GetCell(pCell->GetMergeCellID());
+						CRect mergerect = rect;
+						if (GetCellRangeRect(pMergedCell->m_MergeRange, &mergerect))
+						{
+							mergerect.DeflateRect(0, 0, 1, 1);
+							pMergedCell->SetCoords(pCell->GetMergeCellID().row, pCell->GetMergeCellID().col);
+							pMergedCell->Draw(pDC, pCell->GetMergeCellID().row, pCell->GetMergeCellID().col, mergerect, TRUE);
+						}
+					}
+				}
+				else
+				{
+					CRect mergerect = rect;
+
+					if (GetCellRangeRect(pCell->m_MergeRange, &mergerect))
+					{
+						mergerect.DeflateRect(0, 0, 1, 1);
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, mergerect, TRUE);
+					}
+				}
 			}
-        }
-    }
+		}
+	}
+	/*
+		// draw top-left cells 0..m_nFixedRows-1, 0..m_nFixedCols-1
+		rect.bottom = -1;
+		for (row = 0; row < m_nFixedRows; row++)
+		{
+			if (GetRowHeight(row) <= 0) continue;
 
-    // draw rest of non-fixed cells
-    rect.bottom = nFixedRowHeight-1;
-    for (row = minVisibleRow; row <= maxVisibleRow; row++)
-    {
-        if (GetRowHeight(row) <= 0) continue;
+			rect.top = rect.bottom+1;
+			rect.bottom = rect.top + GetRowHeight(row)-1;
+			rect.right = -1;
 
-        rect.top = rect.bottom+1;
-        rect.bottom = rect.top + GetRowHeight(row)-1;
-
-        // rect.bottom = bottom pixel of previous row
-        if (rect.top > clipRect.bottom)
-            break;                // Gone past cliprect
-        if (rect.bottom < clipRect.top)
-            continue;             // Reached cliprect yet?
-
-        rect.right = nFixedColWidth-1;
-        for (col = minVisibleCol; col <= maxVisibleCol; col++)
-        {
-            if (GetColumnWidth(col) <= 0) continue;
-
-            rect.left = rect.right+1;
-            rect.right = rect.left + GetColumnWidth(col)-1;
-
-            if (rect.left > clipRect.right)
-                break;        // gone past cliprect
-            if (rect.right < clipRect.left)
-                continue;     // Reached cliprect yet?
-
-            pCell = GetCell(row, col);
-            // TRACE(_T("Cell %d,%d type: %s\n"), row, col, pCell->GetRuntimeClass()->m_lpszClassName);
-            if (pCell)
+			for (col = 0; col < m_nFixedCols; col++)
 			{
-				pCell->SetCoords(row,col);
-                pCell->Draw(pDC, row, col, rect, FALSE);
+				if (GetColumnWidth(col) <= 0) continue;
+
+				rect.left = rect.right+1;
+				rect.right = rect.left + GetColumnWidth(col)-1;
+
+				pCell = GetCell(row, col);
+				if (pCell)
+				{
+					pCell->SetCoords(row,col);
+					pCell->Draw(pDC, row, col, rect, FALSE);
+				}
 			}
-        }
-    }
+		}
+	*/
+	// draw top-left cells 0..m_nFixedRows-1, 0..m_nFixedCols-1
+	rect.bottom = -1;
+	for (row = 0; row < m_nFixedRows; row++)
+	{
+		if (GetRowHeight(row) <= 0) continue;
 
+		rect.top = rect.bottom + 1;
+		rect.bottom = rect.top + GetRowHeight(row) - 1;
+		rect.right = -1;
 
-    CPen pen;
-    pen.CreatePen(PS_SOLID, 0, m_crGridLineColour);
-    pDC->SelectObject(&pen);
+		for (col = 0; col < m_nFixedCols; col++)
+		{
+			if (GetColumnWidth(col) <= 0) continue;
 
-    // draw vertical lines (drawn at ends of cells)
-    if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
-    {
-        int x = nFixedColWidth;
-        for (col = minVisibleCol; col <= maxVisibleCol; col++)
-        {
-            if (GetColumnWidth(col) <= 0) continue;
+			rect.left = rect.right + 1;
+			rect.right = rect.left + GetColumnWidth(col) - 1;
 
-            x += GetColumnWidth(col);
-            pDC->MoveTo(x-1, nFixedRowHeight);
-            pDC->LineTo(x-1, VisRect.bottom);
-        }
-    }
+			pCell = GetCell(row, col);
+			/* if (pCell)
+			{
+			pCell->SetCoords(row,col);
+			pCell->Draw(pDC, row, col, rect, FALSE);
+			}*/
+			if (pCell)
+			{
+				//Used for merge cells by Huang Wei
+				//bugfix by Luther Bruck
 
-    // draw horizontal lines (drawn at bottom of each cell)
-    if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
-    {
-        int y = nFixedRowHeight;
-        for (row = minVisibleRow; row <= maxVisibleRow; row++)
-        {
-            if (GetRowHeight(row) <= 0) continue;
+				if (!pCell->IsMerged())
+				{
+					if (!pCell->IsMergeWithOthers())
+					{
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, rect, FALSE);
+					}
+					else
+					{
+						CGridCellBase* pMergedCell = GetCell(pCell->GetMergeCellID());
+						CRect mergerect = rect;
+						if (GetCellRangeRect(pMergedCell->m_MergeRange, &mergerect))
+						{
+							mergerect.DeflateRect(0, 0, 1, 1);
+							pMergedCell->SetCoords(pCell->GetMergeCellID().row, pCell->GetMergeCellID().col);
+							pMergedCell->Draw(pDC, pCell->GetMergeCellID().row, pCell->GetMergeCellID().col, mergerect, TRUE);
+						}
+					}
+				}
+				else
+				{
+					CRect mergerect = rect;
 
-            y += GetRowHeight(row);
-            pDC->MoveTo(nFixedColWidth, y-1);
-            pDC->LineTo(VisRect.right,  y-1);
-        }
-    }
+					if (GetCellRangeRect(pCell->m_MergeRange, &mergerect))
+					{
+						mergerect.DeflateRect(0, 0, 1, 1);
+						pCell->SetCoords(row, col);
+						pCell->Draw(pDC, row, col, mergerect, TRUE);
+					}
+				}
+			}
+		}
+	}
 
-    pDC->SelectStockObject(NULL_PEN);
 
     // Let parent know it can discard it's data if it needs to.
     if (GetVirtualMode())
@@ -2863,7 +3052,7 @@
     if (!GetCellOrigin(idCurrentCell, &start))
         return FALSE;
 
-    int endy = start.y + GetRowHeight(idCurrentCell.row);
+	int endy = start.y + GetMergeCellHeight(idCurrentCell);
 
     if ((point.y - start.y < m_nResizeCaptureRange && idCurrentCell.row != 0) ||
         endy - point.y < m_nResizeCaptureRange)
@@ -2885,7 +3074,7 @@
     if (!GetCellOrigin(idCurrentCell, &start))
         return FALSE;
 
-    int endx = start.x + GetColumnWidth(idCurrentCell.col);
+	int endx = start.x + GetMergeCellWidth(idCurrentCell);
 
     if ((point.x - start.x < m_nResizeCaptureRange && idCurrentCell.col != 0) ||
         endx - point.x < m_nResizeCaptureRange)
@@ -2977,7 +3166,8 @@
             cellID.row = -1;
         else
             cellID.row = row;
-    }
+	}
+	cellID = GetMergeCellID(cellID);
     return cellID;
 }
 
@@ -3368,9 +3558,12 @@
     if (nCol >= m_nFixedCols || nRow >= m_nFixedRows)
         idTopLeft = GetTopleftNonFixedCell();
 
-    if ((nRow >= m_nFixedRows && nRow < idTopLeft.row) ||
-        (nCol>= m_nFixedCols && nCol < idTopLeft.col))
-        return FALSE;
+	//Merge the selected cells 
+	//by Huang Wei
+
+    //if ((nRow >= m_nFixedRows && nRow < idTopLeft.row) ||
+    //    (nCol>= m_nFixedCols && nCol < idTopLeft.col))
+    //    return FALSE;
 
     p->x = 0;
     if (nCol < m_nFixedCols)                      // is a fixed column
@@ -3380,8 +3573,18 @@
         {                                        // is a scrollable data column
             for (i = 0; i < m_nFixedCols; i++)
                 p->x += GetColumnWidth(i);
-            for (i = idTopLeft.col; i < nCol; i++)
-                p->x += GetColumnWidth(i);
+			//Merge the selected cells 
+			//by Huang Wei
+			if(nCol>idTopLeft.col)
+			{
+				for (i = idTopLeft.col; i < nCol; i++)
+					p->x += GetColumnWidth(i);
+			}
+			else
+			{
+				for (i = nCol; i <idTopLeft.col ; i++)
+					p->x -= GetColumnWidth(i);
+			}
         }
         
         p->y = 0;
@@ -3392,11 +3595,64 @@
             {                                        // is a scrollable data row
                 for (i = 0; i < m_nFixedRows; i++)
                     p->y += GetRowHeight(i);
-                for (i = idTopLeft.row; i < nRow; i++)
-                    p->y += GetRowHeight(i);
+ 				//Merge the selected cells 
+				//by Huang Wei
+				if(nRow>idTopLeft.row)
+				{
+					for (i = idTopLeft.row; i < nRow; i++)
+						p->y += GetRowHeight(i);
+				}
+				else
+				{
+					for (i = nRow; i <idTopLeft.row; i++)
+						p->y -= GetRowHeight(i);
+				}
             }
             
             return TRUE;
+}
+// returns the top left point of the cell. Returns FALSE if cell not visible.
+// don't consider cell's merge
+BOOL CGridCtrl::GetCellOriginNoMerge(int nRow, int nCol, LPPOINT p)
+{
+	int i;
+
+	if (!IsValid(nRow, nCol))
+		return FALSE;
+
+	CCellID idTopLeft;
+	if (nCol >= m_nFixedCols || nRow >= m_nFixedRows)
+		idTopLeft = GetTopleftNonFixedCell();
+
+    if ((nRow >= m_nFixedRows && nRow < idTopLeft.row) ||
+        (nCol>= m_nFixedCols && nCol < idTopLeft.col))
+        return FALSE;
+
+    p->x = 0;
+    if (nCol < m_nFixedCols)                      // is a fixed column
+        for (i = 0; i < nCol; i++)
+            p->x += GetColumnWidth(i);
+    else 
+    {                                        // is a scrollable data column
+        for (i = 0; i < m_nFixedCols; i++)
+            p->x += GetColumnWidth(i);
+        for (i = idTopLeft.col; i < nCol; i++)
+            p->x += GetColumnWidth(i);
+    }
+    
+    p->y = 0;
+    if (nRow < m_nFixedRows)                      // is a fixed row
+        for (i = 0; i < nRow; i++)
+            p->y += GetRowHeight(i);
+    else 
+    {                                        // is a scrollable data row
+        for (i = 0; i < m_nFixedRows; i++)
+            p->y += GetRowHeight(i);
+        for (i = idTopLeft.row; i < nRow; i++)
+            p->y += GetRowHeight(i);
+    }
+    
+    return TRUE;
 }
 
 BOOL CGridCtrl::GetCellOrigin(const CCellID& cell, LPPOINT p)
@@ -3416,11 +3672,21 @@
     if (!GetCellOrigin(nRow, nCol, &CellOrigin))
         return FALSE;
 
-    pRect->left   = CellOrigin.x;
-    pRect->top    = CellOrigin.y;
-    pRect->right  = CellOrigin.x + GetColumnWidth(nCol)-1;
-    pRect->bottom = CellOrigin.y + GetRowHeight(nRow)-1;
-
+    //Merge the selected cells 
+    //by Huang Wei
+    CGridCellBase *pCell = (CGridCellBase*) GetCell(nRow,nCol);
+	
+	if(!pCell->IsMerged())
+	{
+		pRect->left   = CellOrigin.x;
+		pRect->top    = CellOrigin.y;
+		pRect->right  = CellOrigin.x + GetColumnWidth(nCol)-1;
+		pRect->bottom = CellOrigin.y + GetRowHeight(nRow)-1;
+	}
+	else
+	{
+		GetCellRangeRect(pCell->m_MergeRange,pRect);
+	}
     //TRACE("Row %d, col %d: L %d, T %d, W %d, H %d:  %d,%d - %d,%d\n",
     //      nRow,nCol, CellOrigin.x, CellOrigin.y, GetColumnWidth(nCol), GetRowHeight(nRow),
     //      pRect->left, pRect->top, pRect->right, pRect->bottom);
@@ -6481,12 +6747,18 @@
         if (m_LeftClickDownPoint != point  && (point.x != 0 || point.y != 0)) // 0 pt fix by email1@bierling.net
         {
             CPoint start;
+			//Used for merge cells
+			//by Huang Wei
+			m_LeftClickDownCell=GetMergeCellID(m_LeftClickDownCell);
             if (!GetCellOrigin(m_LeftClickDownCell, &start))
                 return;
             
-            int nRowHeight = __max(point.y - start.y, m_bAllowRowHide? 0 : 1);
+            int nRowHeight = max(point.y - start.y, m_bAllowRowHide? 0 : 1);
+			//Used for merge cells
+			//by Huang Wei
+			int mergeheight=GetMergeCellHeight(m_LeftClickDownCell)-GetRowHeight(m_LeftClickDownCell.row);
 
-            SetRowHeight(m_LeftClickDownCell.row, nRowHeight);
+            SetRowHeight(m_LeftClickDownCell.row, nRowHeight-mergeheight);
             ResetScrollBars();
             Invalidate();
         }
@@ -7600,6 +7872,45 @@
 
 }
 
+
+void CGridCtrl::MergeCells(int nStartRow, int nStartCol, int nEndRow, int nEndCol)
+{
+	for(int row=nStartRow;row<=nEndRow;row++)
+	{
+		for(int col=nStartCol;col<=nEndCol;col++)
+		{
+		    CGridCellBase *pCell = (CGridCellBase*) GetCell(row,col);
+			pCell->Show(FALSE);
+			if(row==nStartRow && col==nStartCol)
+			{
+				CCellRange range(nStartRow,  nStartCol,  nEndRow,  nEndCol);
+				pCell->SetMergeRange(range);
+			}
+			else
+			{
+				CCellID cell(nStartRow,nStartCol);
+				pCell->SetMergeCellID(cell);
+			}
+
+		}
+	}
+	Invalidate();
+}
+
+int CGridCtrl::GetMergeCellWidth(CCellID cell)
+{
+	CCellID mergecell = GetMergeCellID(cell);
+	CGridCellBase *pCell = (CGridCellBase*)GetCell(mergecell);
+	if (!pCell->IsMerged())
+		return GetColumnWidth(cell.col);
+	int width = 0;
+	for (int mergecol = pCell->GetMergeRange().GetMaxCol();mergecol >= pCell->GetMergeRange().GetMinCol();mergecol--)
+	{
+		width += GetColumnWidth(mergecol);
+	}
+	return width;
+}
+
 void CGridCtrl::OnKillFocus(CWnd* pNewWnd)
 {
 	CWnd::OnKillFocus(pNewWnd);

--
Gitblit v1.9.3