// GridCellBase.cpp : implementation file // // MFC Grid Control - Main grid cell base class // // Provides the implementation for the base cell type of the // grid control. No data is stored (except for state) but default // implementations of drawing, printingetc provided. MUST be derived // from to be used. // // Written by Chris Maunder <cmaunder@mail.com> // Copyright (c) 1998-2002. All Rights Reserved. // // This code may be used in compiled form in any way you desire. This // file may be redistributed unmodified by any means PROVIDING it is // not sold for profit without the authors written consent, and // providing that this notice and the authors name and all copyright // notices remains intact. // // An email letting me know how you are using it would be nice as well. // // This file is provided "as is" with no expressed or implied warranty. // The author accepts no liability for any damage/loss of business that // this product may cause. // // For use with CGridCtrl v2.22+ // // History: // Ken Bertelson - 12 Apr 2000 - Split CGridCell into CGridCell and CGridCellBase // C Maunder - 19 May 2000 - Fixed sort arrow drawing (Ivan Ilinov) // C Maunder - 29 Aug 2000 - operator= checks for NULL font before setting (Martin Richter) // C Maunder - 15 Oct 2000 - GetTextExtent fixed (Martin Richter) // C Maunder - 1 Jan 2001 - Added ValidateEdit // // NOTES: Each grid cell should take care of it's own drawing, though the Draw() // method takes an "erase background" paramter that is called if the grid // decides to draw the entire grid background in on hit. Certain ambient // properties such as the default font to use, and hints on how to draw // fixed cells should be fetched from the parent grid. The grid trusts the // cells will behave in a certain way, and the cells trust the grid will // supply accurate information. // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "GridCtrl.h" #include "GridCellBase.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNAMIC(CGridCellBase, CObject) ///////////////////////////////////////////////////////////////////////////// // GridCellBase CGridCellBase::CGridCellBase() { Reset(); } CGridCellBase::~CGridCellBase() { } ///////////////////////////////////////////////////////////////////////////// // GridCellBase Operations void CGridCellBase::Reset() { m_Hide=false; m_nState = 0; m_MergeRange.Set(); m_IsMergeWithOthers=false; m_MergeCellID.row=-1; m_MergeCellID.col=-1; product_id = 0; data_id = 0; } //Used for merge cells,remove const //by Huang Wei void CGridCellBase::operator=( CGridCellBase& cell) { if (this == &cell) return; SetGrid(cell.GetGrid()); // do first in case of dependencies SetText(cell.GetText()); SetImage(cell.GetImage()); SetData(cell.GetData()); SetState(cell.GetState()); SetFormat(cell.GetFormat()); SetTextClr(cell.GetTextClr()); SetBackClr(cell.GetBackClr()); SetFont(cell.IsDefaultFont()? NULL : cell.GetFont()); SetMargin(cell.GetMargin()); //Used for merge cells //by Huang Wei SetMergeCellID(cell.GetMergeCellID()); SetMergeRange(cell.GetMergeRange()); Show(cell.IsShow()); } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Attributes // Returns a pointer to a cell that holds default values for this particular type of cell CGridCellBase* CGridCellBase::GetDefaultCell() const { if (GetGrid()) return GetGrid()->GetDefaultCell(IsFixedRow(), IsFixedCol()); return NULL; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Operations // EFW - Various changes to make it draw cells better when using alternate // color schemes. Also removed printing references as that's now done // by PrintCell() and fixed the sort marker so that it doesn't draw out // of bounds. BOOL CGridCellBase::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /*=TRUE*/) { // Note - all through this function we totally brutalise 'rect'. Do not // depend on it's value being that which was passed in. //Used for merge cells //by Huang Wei if( m_Hide && !IsMerged()) { return TRUE; } CGridCtrl* pGrid = GetGrid(); ASSERT(pGrid); if (!pGrid || !pDC) return FALSE; if( rect.Width() <= 0 || rect.Height() <= 0) // prevents imagelist item from drawing even return FALSE; // though cell is hidden //TRACE3("Drawing %scell %d, %d\n", IsFixed()? _T("Fixed ") : _T(""), nRow, nCol); int nSavedDC = pDC->SaveDC(); pDC->SetBkMode(TRANSPARENT); // Get the default cell implementation for this kind of cell. We use it if this cell // has anything marked as "default" CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell(); if (!pDefaultCell) return FALSE; // Set up text and background colours COLORREF TextClr, TextBkClr; TextClr = (GetTextClr() == CLR_DEFAULT)? pDefaultCell->GetTextClr() : GetTextClr(); if (GetBackClr() == CLR_DEFAULT) TextBkClr = pDefaultCell->GetBackClr(); else { bEraseBkgnd = TRUE; TextBkClr = GetBackClr(); } // Draw cell background and highlighting (if necessary) if ( IsFocused() || IsDropHighlighted() ) { // Always draw even in list mode so that we can tell where the // cursor is at. Use the highlight colors though. if(GetState() & GVIS_SELECTED) { TextBkClr = ::GetSysColor(COLOR_HIGHLIGHT); TextClr = ::GetSysColor(COLOR_HIGHLIGHTTEXT); bEraseBkgnd = TRUE; } rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom if (bEraseBkgnd) { TRY { CBrush brush(TextBkClr); pDC->FillRect(rect, &brush); } CATCH(CResourceException, e) { //e->ReportError(); } END_CATCH } // Don't adjust frame rect if no grid lines so that the // whole cell is enclosed. if(pGrid->GetGridLines() != GVL_NONE) { rect.right--; rect.bottom--; } if (pGrid->GetFrameFocusCell()) { // Use same color as text to outline the cell so that it shows // up if the background is black. TRY { CBrush brush(TextClr); pDC->FrameRect(rect, &brush); } CATCH(CResourceException, e) { //e->ReportError(); } END_CATCH } pDC->SetTextColor(TextClr); // Adjust rect after frame draw if no grid lines if(pGrid->GetGridLines() == GVL_NONE) { rect.right--; rect.bottom--; } rect.DeflateRect(0,1,1,1); } else if ((GetState() & GVIS_SELECTED)) { rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom pDC->FillSolidRect(rect, ::GetSysColor(COLOR_HIGHLIGHT)); rect.right--; rect.bottom--; pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { if (bEraseBkgnd) { rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom CBrush brush(TextBkClr); pDC->FillRect(rect, &brush); rect.right--; rect.bottom--; } pDC->SetTextColor(TextClr); } // Draw lines only when wanted if (IsFixed() && pGrid->GetGridLines() != GVL_NONE) { CCellID FocusCell = pGrid->GetFocusCell(); // As above, always show current location even in list mode so // that we know where the cursor is at. BOOL bHiliteFixed = pGrid->GetTrackFocusCell() && pGrid->IsValid(FocusCell) && (FocusCell.row == nRow || FocusCell.col == nCol); // If this fixed cell is on the same row/col as the focus cell, // highlight it. if (bHiliteFixed) { rect.right++; rect.bottom++; pDC->DrawEdge(rect, BDR_SUNKENINNER /*EDGE_RAISED*/, BF_RECT); rect.DeflateRect(1,1); } else { CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)), darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)), *pOldPen = pDC->GetCurrentPen(); pDC->SelectObject(&lightpen); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.left, rect.top); pDC->LineTo(rect.left, rect.bottom); pDC->SelectObject(&darkpen); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.right, rect.bottom); pDC->LineTo(rect.left, rect.bottom); pDC->SelectObject(pOldPen); rect.DeflateRect(1,1); } } // Draw Text and image #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING) if (!pDC->m_bPrinting) #endif { CFont *pFont = GetFontObject(); ASSERT(pFont); if (pFont) pDC->SelectObject(pFont); } rect.DeflateRect(GetMargin(), 0); if (pGrid->GetImageList() && GetImage() >= 0) { IMAGEINFO Info; if (pGrid->GetImageList()->GetImageInfo(GetImage(), &Info)) { // would like to use a clipping region but seems to have issue // working with CMemDC directly. Instead, don't display image // if any part of it cut-off // // CRgn rgn; // rgn.CreateRectRgnIndirect(rect); // pDC->SelectClipRgn(&rgn); // rgn.DeleteObject(); int nImageWidth = Info.rcImage.right-Info.rcImage.left+1; int nImageHeight = Info.rcImage.bottom-Info.rcImage.top+1; if( nImageWidth + rect.left <= rect.right + (int)(2*GetMargin()) && nImageHeight + rect.top <= rect.bottom + (int)(2*GetMargin()) ) { pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL); } //rect.left += nImageWidth+GetMargin(); } } // Draw sort arrow if (pGrid->GetSortColumn() == nCol && nRow == 0) { CSize size = pDC->GetTextExtent(_T("M")); int nOffset = 2; // Base the size of the triangle on the smaller of the column // height or text height with a slight offset top and bottom. // Otherwise, it can get drawn outside the bounds of the cell. size.cy -= (nOffset * 2); if (size.cy >= rect.Height()) size.cy = rect.Height() - (nOffset * 2); size.cx = size.cy; // Make the dimensions square // Kludge for vertical text BOOL bVertical = (GetFont()->lfEscapement == 900); // Only draw if it'll fit! if (size.cx + rect.left < rect.right + (int)(2*GetMargin())) { int nTriangleBase = rect.bottom - nOffset - size.cy; // Triangle bottom right //int nTriangleBase = (rect.top + rect.bottom - size.cy)/2; // Triangle middle right //int nTriangleBase = rect.top + nOffset; // Triangle top right //int nTriangleLeft = rect.right - size.cx; // Triangle RHS //int nTriangleLeft = (rect.right + rect.left - size.cx)/2; // Triangle middle //int nTriangleLeft = rect.left; // Triangle LHS int nTriangleLeft; if (bVertical) nTriangleLeft = (rect.right + rect.left - size.cx)/2; // Triangle middle else nTriangleLeft = rect.right - size.cx; // Triangle RHS CPen penShadow(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW)); CPen penLight(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT)); if (pGrid->GetSortAscending()) { // Draw triangle pointing upwards CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight); pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1); pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + 1 ); pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase + size.cy + 1); pDC->LineTo( nTriangleLeft + 1, nTriangleBase + size.cy + 1); pDC->SelectObject(&penShadow); pDC->MoveTo( nTriangleLeft, nTriangleBase + size.cy ); pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase ); pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase + size.cy ); pDC->LineTo( nTriangleLeft, nTriangleBase + size.cy ); pDC->SelectObject(pOldPen); } else { // Draw triangle pointing downwards CPen *pOldPen = (CPen*) pDC->SelectObject(&penLight); pDC->MoveTo( nTriangleLeft + 1, nTriangleBase + 1 ); pDC->LineTo( nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + size.cy + 1 ); pDC->LineTo( nTriangleLeft + size.cx + 1, nTriangleBase + 1 ); pDC->LineTo( nTriangleLeft + 1, nTriangleBase + 1 ); pDC->SelectObject(&penShadow); pDC->MoveTo( nTriangleLeft, nTriangleBase ); pDC->LineTo( nTriangleLeft + (size.cx / 2), nTriangleBase + size.cy ); pDC->LineTo( nTriangleLeft + size.cx, nTriangleBase ); pDC->LineTo( nTriangleLeft, nTriangleBase ); pDC->SelectObject(pOldPen); } if (!bVertical) rect.right -= size.cy; } } // We want to see '&' characters so use DT_NOPREFIX GetTextRect(rect); DrawText(pDC->m_hDC, GetText(), -1, rect, GetFormat() | DT_NOPREFIX); pDC->RestoreDC(nSavedDC); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Mouse and Cursor events // Not yet implemented void CGridCellBase::OnMouseEnter() { TRACE0("Mouse entered cell\n"); } void CGridCellBase::OnMouseOver() { //TRACE0("Mouse over cell\n"); } // Not Yet Implemented void CGridCellBase::OnMouseLeave() { TRACE0("Mouse left cell\n"); } void CGridCellBase::OnClick( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse Left btn up in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } void CGridCellBase::OnClickDown( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse Left btn down in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } void CGridCellBase::OnRClick( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse right-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } void CGridCellBase::OnDblClick( CPoint PointCellRelative) { UNUSED_ALWAYS(PointCellRelative); TRACE2("Mouse double-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y); } // Return TRUE if you set the cursor BOOL CGridCellBase::OnSetCursor() { #ifndef _WIN32_WCE_NO_CURSOR SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); #endif return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase editing void CGridCellBase::OnEndEdit() { ASSERT( FALSE); } BOOL CGridCellBase::ValidateEdit(LPCTSTR str) { UNUSED_ALWAYS(str); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CGridCellBase Sizing BOOL CGridCellBase::GetTextRect( LPRECT pRect) // i/o: i=dims of cell rect; o=dims of text rect { if (GetImage() >= 0) { IMAGEINFO Info; CGridCtrl* pGrid = GetGrid(); CImageList* pImageList = pGrid->GetImageList(); if (pImageList && pImageList->GetImageInfo( GetImage(), &Info)) { int nImageWidth = Info.rcImage.right-Info.rcImage.left+1; pRect->left += nImageWidth + GetMargin(); } } return TRUE; } // By default this uses the selected font (which is a bigger font) CSize CGridCellBase::GetTextExtent(LPCTSTR szText, CDC* pDC /*= NULL*/) { CGridCtrl* pGrid = GetGrid(); ASSERT(pGrid); BOOL bReleaseDC = FALSE; if (pDC == NULL || szText == NULL) { if (szText) pDC = pGrid->GetDC(); if (pDC == NULL || szText == NULL) { CGridDefaultCell* pDefCell = (CGridDefaultCell*) GetDefaultCell(); ASSERT(pDefCell); return CSize(pDefCell->GetWidth(), pDefCell->GetHeight()); } bReleaseDC = TRUE; } CFont *pOldFont = NULL, *pFont = GetFontObject(); if (pFont) pOldFont = pDC->SelectObject(pFont); CSize size; int nFormat = GetFormat(); // If the cell is a multiline cell, then use the width of the cell // to get the height if ((nFormat & DT_WORDBREAK) && !(nFormat & DT_SINGLELINE)) { CString str = szText; int nMaxWidth = 0; while (TRUE) { int nPos = str.Find(_T('\n')); CString TempStr = (nPos < 0)? str : str.Left(nPos); int nTempWidth = pDC->GetTextExtent(TempStr).cx; if (nTempWidth > nMaxWidth) nMaxWidth = nTempWidth; if (nPos < 0) break; str = str.Mid(nPos + 1); // Bug fix by Thomas Steinborn } CRect rect; rect.SetRect(0,0, nMaxWidth+1, 0); pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT); size = rect.Size(); } else size = pDC->GetTextExtent(szText, _tcslen(szText)); TEXTMETRIC tm; pDC->GetTextMetrics(&tm); size.cx += (tm.tmOverhang); if (pOldFont) pDC->SelectObject(pOldFont); size += CSize(4*GetMargin(), 2*GetMargin()); // Kludge for vertical text LOGFONT *pLF = GetFont(); if (pLF->lfEscapement == 900 || pLF->lfEscapement == -900) { int nTemp = size.cx; size.cx = size.cy; size.cy = nTemp; size += CSize(0, 4*GetMargin()); } if (bReleaseDC) pGrid->ReleaseDC(pDC); return size; } CSize CGridCellBase::GetCellExtent(CDC* pDC) { CSize size = GetTextExtent(GetText(), pDC); CSize ImageSize(0,0); int nImage = GetImage(); if (nImage >= 0) { CGridCtrl* pGrid = GetGrid(); ASSERT(pGrid); if (pGrid->GetImageList()) { IMAGEINFO Info; if (pGrid->GetImageList()->GetImageInfo(nImage, &Info)) ImageSize = CSize(Info.rcImage.right-Info.rcImage.left+1, Info.rcImage.bottom-Info.rcImage.top+1); } } return CSize(size.cx + ImageSize.cx, max(size.cy, ImageSize.cy)); } // EFW - Added to print cells so that grids that use different colors are // printed correctly. BOOL CGridCellBase::PrintCell(CDC* pDC, int /*nRow*/, int /*nCol*/, CRect rect) { //Used for merge cells //by Huang Wei if( m_Hide && !IsMerged()) { return TRUE; } #if defined(_WIN32_WCE_NO_PRINTING) || defined(GRIDCONTROL_NO_PRINTING) return FALSE; #else COLORREF crFG, crBG; GV_ITEM Item; CGridCtrl* pGrid = GetGrid(); if (!pGrid || !pDC) return FALSE; if( rect.Width() <= 0 || rect.Height() <= 0) // prevents imagelist item from drawing even return FALSE; // though cell is hidden int nSavedDC = pDC->SaveDC(); pDC->SetBkMode(TRANSPARENT); //Used for merge cells //by Huang Wei rect.InflateRect(1,1); pDC->Rectangle(rect); rect.DeflateRect(1,1); if (pGrid->GetShadedPrintOut()) { // Get the default cell implementation for this kind of cell. We use it if this cell // has anything marked as "default" CGridDefaultCell *pDefaultCell = (CGridDefaultCell*) GetDefaultCell(); if (!pDefaultCell) return FALSE; // Use custom color if it doesn't match the default color and the // default grid background color. If not, leave it alone. if(IsFixed()) crBG = (GetBackClr() != CLR_DEFAULT) ? GetBackClr() : pDefaultCell->GetBackClr(); else crBG = (GetBackClr() != CLR_DEFAULT && GetBackClr() != pDefaultCell->GetBackClr()) ? GetBackClr() : CLR_DEFAULT; // Use custom color if the background is different or if it doesn't // match the default color and the default grid text color. if(IsFixed()) crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() : pDefaultCell->GetTextClr(); else crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() : pDefaultCell->GetTextClr(); // If not printing on a color printer, adjust the foreground color // to a gray scale if the background color isn't used so that all // colors will be visible. If not, some colors turn to solid black // or white when printed and may not show up. This may be caused by // coarse dithering by the printer driver too (see image note below). if(pDC->GetDeviceCaps(NUMCOLORS) == 2 && crBG == CLR_DEFAULT) crFG = RGB(GetRValue(crFG) * 0.30, GetGValue(crFG) * 0.59, GetBValue(crFG) * 0.11); // Only erase the background if the color is not the default // grid background color. if(crBG != CLR_DEFAULT) { CBrush brush(crBG); rect.right++; rect.bottom++; pDC->FillRect(rect, &brush); rect.right--; rect.bottom--; } } else { crBG = CLR_DEFAULT; crFG = RGB(0, 0, 0); } pDC->SetTextColor(crFG); CFont *pFont = GetFontObject(); if (pFont) pDC->SelectObject(pFont); /* // *************************************************** // Disabled - if you need this functionality then you'll need to rewrite. // Create the appropriate font and select into DC. CFont Font; // Bold the fixed cells if not shading the print out. Use italic // font it it is enabled. const LOGFONT* plfFont = GetFont(); if(IsFixed() && !pGrid->GetShadedPrintOut()) { Font.CreateFont(plfFont->lfHeight, 0, 0, 0, FW_BOLD, plfFont->lfItalic, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, #ifndef _WIN32_WCE PROOF_QUALITY, #else DEFAULT_QUALITY, #endif VARIABLE_PITCH | FF_SWISS, plfFont->lfFaceName); } else Font.CreateFontIndirect(plfFont); pDC->SelectObject(&Font); // *************************************************** */ // Draw lines only when wanted on fixed cells. Normal cell grid lines // are handled in OnPrint. if(pGrid->GetGridLines() != GVL_NONE && IsFixed()) { CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)), darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)), *pOldPen = pDC->GetCurrentPen(); pDC->SelectObject(&lightpen); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.left, rect.top); pDC->LineTo(rect.left, rect.bottom); pDC->SelectObject(&darkpen); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.right, rect.bottom); pDC->LineTo(rect.left, rect.bottom); rect.DeflateRect(1,1); pDC->SelectObject(pOldPen); } else { // pDC->Rectangle(rect); } rect.DeflateRect(GetMargin(), 0); if(pGrid->GetImageList() && GetImage() >= 0) { // NOTE: If your printed images look like fuzzy garbage, check the // settings on your printer driver. If it's using coarse // dithering and/or vector graphics, they may print wrong. // Changing to fine dithering and raster graphics makes them // print properly. My HP 4L had that problem. IMAGEINFO Info; if(pGrid->GetImageList()->GetImageInfo(GetImage(), &Info)) { int nImageWidth = Info.rcImage.right-Info.rcImage.left; pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL); rect.left += nImageWidth+GetMargin(); } } // Draw without clipping so as not to lose text when printed for real // DT_NOCLIP removed 01.01.01. Slower, but who cares - we are printing! DrawText(pDC->m_hDC, GetText(), -1, rect, GetFormat() | /*DT_NOCLIP | */ DT_NOPREFIX); pDC->RestoreDC(nSavedDC); return TRUE; #endif } /***************************************************************************** Callable by derived classes, only *****************************************************************************/ LRESULT CGridCellBase::SendMessageToParent(int nRow, int nCol, int nMessage) { CGridCtrl* pGrid = GetGrid(); if( pGrid) return pGrid->SendMessageToParent(nRow, nCol, nMessage); else return 0; } //Used for merge cells //by Huang Wei void CGridCellBase::Show(bool IsShow) { m_Hide=!IsShow; } //Used for merge cells //by Huang Wei void CGridCellBase::SetMergeRange(CCellRange range) { m_MergeRange=range; } //Used for merge cells //by Huang Wei CCellRange CGridCellBase::GetMergeRange() { return m_MergeRange; } //Used for merge cells //by Huang Wei bool CGridCellBase::IsMerged() { return m_MergeRange.Count()>1; } //Used for merge cells //by Huang Wei void CGridCellBase::SetMergeCellID(CCellID cell) { m_MergeCellID=cell; if(cell.row!=-1) m_IsMergeWithOthers=true; else m_IsMergeWithOthers=false; } //Used for merge cells //by Huang Wei CCellID CGridCellBase::GetMergeCellID() { return m_MergeCellID; } //Used for merge cells //by Huang Wei bool CGridCellBase::IsMergeWithOthers() { return m_IsMergeWithOthers; } //Used for merge cells //by Huang Wei bool CGridCellBase::IsShow() { return !m_Hide; } //Used for merge cells //by Huang Wei void CGridCellBase::UnMerge() { m_Hide=false; m_MergeRange.Set(); m_IsMergeWithOthers=false; m_MergeCellID.row=-1; m_MergeCellID.col=-1; }