// Hack for AutoSizeRowEx()... CSize CGridCellMultiLine::GetCellExtentEx(int width, CDC*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); } } CSize size = GetTextExtentEx(width - ImageSize.cx, GetText(), pDC); CSize retSize(size.cx + ImageSize.cx, max(size.cy, ImageSize.cy)); return retSize; }
int CGridTreeCellBase::GetTreeIndent() // returns: device units to indent within a cell for a tree at this level { ASSERT( m_pTreeColumn != NULL); CGridCtrl* pGridCtrl = GetGrid(); ASSERT( pGridCtrl != NULL); unsigned char ucLevel = GetLevel(); if( ucLevel == 0) return 0; if( !m_pTreeColumn->GetTreeLines() ) ucLevel--; return (m_pTreeColumn->GetDefTreeIndent() * ucLevel) + (pGridCtrl->GetDefCellMargin() * 2); }
int CGridBtnCellBase::RelPointInCtl( const CPoint& arPoint) // Relative point coords // returns: Index of control that this point is within bounds of or -1 if no control matches { CGridCtrl* pGrid = GetGrid(); ASSERT( pGrid); CRect RectCell; if( pGrid->GetCellRect( m_iRow, m_iCol, &RectCell) ) { ASSERT( MAX_NBR_CTLS_INCELL > GetDrawCtlNbrMax() ); // whoa! CRect RectAry[ MAX_NBR_CTLS_INCELL]; if( CalcDrawCtlRects( RectAry, // returns: CRects with coordinates // last entry has optional leftover rect // available for text, etc. MAX_NBR_CTLS_INCELL,// nbr of Rects in above array RectCell) ) // cell rectangle to work with { const int iCtlNbr = GetDrawCtlNbr(); // make point absolute coord CPoint pointAbs; pointAbs.x = arPoint.x + RectCell.left; pointAbs.y = arPoint.y + RectCell.top; for( int i1=0; i1 < iCtlNbr; i1++) { if( pointAbs.x >= RectAry[i1].left && pointAbs.x <= RectAry[i1].right && pointAbs.y >= RectAry[i1].top && pointAbs.y <= RectAry[i1].bottom) { return i1; // found it } } } } return -1; }
BOOL CGridBtnCellBase::HasCellText() // returns: F=auto-size buttons, only { CGridCtrl* pGrid = GetGrid(); ASSERT( pGrid); CRect RectCell; if( !pGrid->GetCellRect(m_iRow, m_iCol, &RectCell) ) return FALSE; // rather than see if there is text assigned, check if any // space allocated for text CRect RectText( RectCell); if( !GetTextRect( &RectText) ) // i/o: i=dims of cell rect; o=dims of text rect return FALSE; if( RectText.Width() > 0 ) return TRUE; return FALSE; }
void CGridBtnCellCombo::OnClick( CPoint PointCellRelative) { // immediately edit if user clicked on scroll down button picture int iCtlHit = RelPointInCtl( PointCellRelative); // Relative point coords // returns: Index of control that this point is within bounds of or -1 if no control matches BOOL bHitScrollDown = FALSE; if( iCtlHit >= 0) { // if user clicked on scroll down button picture, then show // the drop-down, too UINT uiType = GetDrawCtlType( iCtlHit); UINT uiState = GetDrawCtlState( iCtlHit); bHitScrollDown = ( uiType == DFC_SCROLL) && uiState & DFCS_SCROLLDOWN; } if( bHitScrollDown) { // invoke the edit, now -- similar to CGridCtl::OnEditCell() logic CGridCtrl* pGrid = GetGrid(); ASSERT( pGrid != NULL); CRect rect; if (!pGrid->GetCellRect( m_iRow, m_iCol, rect)) return; SendMessageToParent(m_iRow, m_iCol, GVN_BEGINLABELEDIT); Edit( m_iRow, m_iCol, rect, PointCellRelative, IDC_INPLACE_CONTROL, VK_LBUTTON); return; } CGridBtnCell::OnClick( PointCellRelative); }
// 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); - Removed by Yogurt }
/***************************************************************************** Called during all the mouse events associated with clicking a control embedded within a cell. Override to have more elaborate handling like implementing radio button logic. *****************************************************************************/ BOOL CGridBtnCellBase::ClickedCellCtl( UINT uMsg, // Command that invoked. e.g. WM_LBUTTONDOWN int aiWhich) // zero-based index of image to draw // returns: T=redraw occurred / F=no redraw { if( aiWhich < 0 || aiWhich >= GetDrawCtlNbrMax() ) { ASSERT( FALSE); return FALSE; } UINT uiState = GetDrawCtlState( aiWhich); if( uiState & DFCS_INACTIVE) return FALSE; // button is inactive -- don't do anything m_sLastCtlClicked = (short)aiWhich; UINT iType = GetDrawCtlType( aiWhich); switch( uMsg) { case WM_LBUTTONDOWN: // appears pushed in uiState |= DFCS_PUSHED; SetDrawCtlState( aiWhich, uiState); break; case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: // appears pushed out uiState &= (~DFCS_PUSHED); // auto check / uncheck controls, too if( iType == DFC_BUTTON ) { BOOL bIsMbrRadioGrp = GetDrawCtlIsMbrRadioGrp( aiWhich); if( uiState & DFCS_BUTTONRADIO || bIsMbrRadioGrp ) { // radio buttons or any button flagged as being part // of a radio group will be made to look pressed down // while pushing-up / unchecking all other members // of the radio group const int iCtlNbr = GetDrawCtlNbr(); UINT uiStateRadio; for( int i1=0; i1 < iCtlNbr; i1++) { if( i1 != aiWhich) { uiStateRadio = GetDrawCtlState( i1); bIsMbrRadioGrp = GetDrawCtlIsMbrRadioGrp( i1); if( uiStateRadio & DFCS_BUTTONRADIO || bIsMbrRadioGrp ) { uiStateRadio &= (~( DFCS_PUSHED | DFCS_CHECKED) ); // push out and uncheck SetDrawCtlState( i1, uiStateRadio); } } } uiState |= DFCS_CHECKED; // check if( !(uiState & DFCS_BUTTONRADIO) ) uiState |= DFCS_PUSHED; // press in if not real radio button } else if( !( uiState & ALL_BUT_BTN_CHK) ) { // not a pushbutton -- it's a check box // (can't check for DFCS_BUTTONCHECK directly since it is bit 0) if( uiState & DFCS_CHECKED) uiState &= (~DFCS_CHECKED); // uncheck else uiState |= DFCS_CHECKED; // check } } SetDrawCtlState( aiWhich, uiState); break; default: ASSERT( FALSE); // gotta handle new message return FALSE; } CGridCtrl* pGrid = GetGrid(); ASSERT( pGrid); pGrid->RedrawCell( m_iRow, m_iCol); return TRUE; }
// This hack allows you to determine the height that a cell should be in order to display // stuff properly in the given width. CSize CGridCellMultiLine::GetTextExtentEx(int width, LPCTSTR szText, CDC* pDC /*= NULL*/) { CGridCtrl* pGrid = GetGrid(); ASSERT(pGrid); BOOL bReleaseDC = FALSE; if (pDC == NULL) { pDC = pGrid->GetDC(); if (!pDC) { 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(); TEXTMETRIC tm; pDC->GetTextMetrics(&tm); int textWidth = width - (4*GetMargin ()); // corrects the bug if resizing column gives a text width smaller than (4*Getmargin()) if (textWidth <= 0) { textWidth = 1; } // 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)) { CRect rect; rect.SetRect(0, 0, textWidth, 0); pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT); size.cx = rect.Width (); size.cy = rect.Height (); } else size = pDC->GetTextExtent(szText, _tcslen(szText)); 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; }
BOOL CSListView::SetAverageItem( CGridCtrl &grid, CStockContainer & container, BOOL bRedraw ) { if( grid.GetColumnCount() <= 0 ) return FALSE; container.Lock(); // Get LPARAM CUIntArray anParams; anParams.SetSize( 0, grid.GetColumnCount() ); for( int nCol=0; nCol < grid.GetColumnCount(); nCol ++ ) { LPARAM lParam = grid.GetItemData( 0, nCol ); anParams.Add( lParam ); } // Set Average CStockInfo & infoAve = container.GetAverage( ); CStockInfo & infoWAve = container.GetWeightAverage( ); int iRowAve=0, iRowWAve=0; if( grid.GetRowCount() >= 3 && grid.GetItemData(grid.GetRowCount()-2,0) == (LPARAM)ID_STOCKCNTN_AVERAGE && grid.GetItemData(grid.GetRowCount()-1,0) == (LPARAM)ID_STOCKCNTN_WEIGHTAVERAGE ) { // get item id iRowAve = grid.GetRowCount()-2; iRowWAve = grid.GetRowCount()-1; } else { // Insert item iRowAve = grid.InsertRow( infoAve.GetStockName() ); grid.SetItemData( iRowAve, 0, (LPARAM)ID_STOCKCNTN_AVERAGE ); iRowWAve = grid.InsertRow( infoWAve.GetStockName() ); grid.SetItemData( iRowWAve, 0, (LPARAM)ID_STOCKCNTN_WEIGHTAVERAGE ); } // Set Average for( nCol=0; nCol<anParams.GetSize(); nCol++ ) { grid.SetItemText( iRowAve, nCol, AfxGetVariantDispString(anParams[nCol], infoAve, NULL) ); grid.SetItemBkColour( iRowAve, nCol, AfxGetProfile().GetColor(CColorClass::clrSListBK) ); grid.SetItemFgColour( iRowAve, nCol, AfxGetVariantColor( anParams[nCol], infoAve ) ); } // Set Weight Average for( nCol=0; nCol<anParams.GetSize(); nCol++ ) { grid.SetItemText( iRowWAve, nCol, AfxGetVariantDispString(anParams[nCol], infoWAve, NULL) ); grid.SetItemBkColour( iRowWAve, nCol, AfxGetProfile().GetColor(CColorClass::clrSListBK) ); grid.SetItemFgColour( iRowWAve, nCol, AfxGetVariantColor( anParams[nCol], infoWAve ) ); } // Set Param which is // SLH_MARKETVALUE, SLH_MARKETVALUEA, SLH_MARKETVALUEB and etc, and more than SLH_USERDEFINE_BEGIN for( nCol=0; nCol < anParams.GetSize(); nCol ++ ) { UINT lParam = anParams[nCol]; if( SLH_DIFF == lParam || SLH_DIFFPERCENT == lParam || SLH_SCOPE == lParam || SLH_DIFFPERCENT_MIN5 == lParam || SLH_PE == lParam || SLH_PMAININCOME == lParam || SLH_RATIO_PCASH == lParam || SLH_RATIO_CURRENCY == lParam || SLH_RATIO_CHANGEHAND == lParam || SLH_RATIO_VOLUME == lParam || SLH_RS == lParam || SLH_MARKETVALUE == lParam || SLH_MARKETVALUEA == lParam || SLH_MARKETVALUEB == lParam || lParam >= SLH_USERDEFINE_BEGIN ) { double dc = 0., average = 0.; double wsum = 0.0001, waverage = 0., w = 0.; for( int iRow=1; iRow<grid.GetRowCount(); iRow++ ) { if( iRow == iRowAve || iRow == iRowWAve ) continue; int id = grid.GetItemData(iRow,0); if( id < 0 || id > container.GetSize() ) continue; CStockInfo & info = container.ElementAt(id); w = info.m_fShare_count_total; double dValue = 0.; if( !AfxGetVariantValue( lParam, info, &dValue, &container ) ) continue; average = (average * dc + dValue)/(dc+1); waverage = (waverage * wsum + dValue * w)/(wsum+w); dc += 1; wsum += w; } CString strText; if( SLH_MARKETVALUE == lParam || SLH_MARKETVALUEA == lParam || SLH_MARKETVALUEB == lParam ) { strText.Format( "%u", (DWORD)average ); grid.SetItemText( iRowAve, nCol, strText ); grid.SetItemText( iRowWAve, nCol, "-" ); } else { strText.Format( "%.2f", average ); grid.SetItemText( iRowAve, nCol, strText ); strText.Format( "%.2f", waverage ); grid.SetItemText( iRowWAve, nCol, strText ); } } } container.UnLock(); if( bRedraw ) { grid.RedrawRow( iRowAve ); grid.RedrawRow( iRowWAve ); } return TRUE; }
/***************************************************************************** Allows Tree + Btn object to call drawing member *****************************************************************************/ BOOL CGridTreeCellBase::DrawTreeCell(CDC* pDC, int nRow, int nCol, CRect* prect, BOOL /* bEraseBkgnd */) { ASSERT( m_pTreeColumn != NULL); if( !m_pTreeColumn->GetAllowDraw()) return FALSE; CGridCtrl* pGrid = GetGrid(); if (!pGrid || !pDC) return FALSE; if( m_pTreeColumn->GetFixedRowCount() != pGrid->GetFixedRowCount() || m_pTreeColumn->GetRowCount() > pGrid->GetRowCount() ) { ASSERT( FALSE); // if ASSERT here, this means that you a tree in a column // but you called CGridCtrl::SetFixedRowCount() or // or CGridCtrl::SetRowCount() directly. You can't do this. // To change the layout of rows when you are using the tree, // you must call CTreeColumn::Setup(). return FALSE; } if( prect->Width() <= 0 || prect->Height() <= 0) // prevents imagelist item from drawing even return FALSE; // though cell is hidden // tree drawing graphic logic begins here int nSavedDC = pDC->SaveDC(); if( nCol == m_pTreeColumn->GetColumnWithTree()) { // this column has a tree // move text over to allow for level indentation if( IsViewable() ) { // if row is showing, draw the tree graphic if( m_pTreeColumn->GetTreeLines()) { TreeDrawGraphic( pDC, // current CDC *prect); // coordinates of bounding cell rectangle } else if( m_pTreeColumn->GetTreeUsesImages()) { TREE_IMAGE TreeImage = TREE_IMAGE_DOCUMENT; // is it not the very last row? if( nRow + m_pTreeColumn->GetFixedRowCount() < m_pTreeColumn->GetRowCount()) { // is it a plus or minus? BOOL bIsPlus; BOOL bIsMinus; BOOL bIsLastLeaf; if( m_pTreeColumn->TreeCellHasPlusMinus( nRow, // row of Cell to check &bIsPlus, // returns: T=Is a plus &bIsMinus, // returns: T=Is a minus &bIsLastLeaf) )// returns: T=Is Last Leaf { // returns: T=cell has a plus or minus; F=not if( bIsPlus) TreeImage = TREE_IMAGE_FOLDER_CLOSED; else TreeImage = TREE_IMAGE_FOLDER_OPEN; } } SetImage( TreeImage); } } prect->left += GetTreeIndent(); } pDC->RestoreDC(nSavedDC); return TRUE; }
/***************************************************************************** Draws "+", "-" and lines that show a tree graphic *****************************************************************************/ void CGridTreeCellBase::TreeDrawGraphic(CDC* apDC, // current CDC CRect aRect) // coordinates of bounding cell rectangle { ASSERT( apDC != NULL); ASSERT( m_pTreeColumn != NULL); ASSERT( m_pTreeColumn->GetAllowDraw()); int iNbrTreeElements = m_pTreeColumn->GetRowCount() - m_pTreeColumn->GetFixedRowCount(); // get current level unsigned char ucLevelCurrent = GetLevel(); ASSERT( IsViewable() ); // can't deal with hidden rows! if( ucLevelCurrent <= 0) { if( m_pTreeColumn->GetTreeUsesImages()) SetImage( TREE_IMAGE_DOCUMENT); return; // no + / - box if level 0 } BOOL bIsNextShowing; unsigned char ucLevelNext; int iLineStop; if( m_pTreeColumn->GetDefTreeIndent() < TREE_BOX_MARGIN * 3) return; // too small to draw the graphic CRect RectRel; TreeGetBoxRelCoords( &RectRel); // returns: relative coordinates CRect RectBox( RectRel); RectBox.OffsetRect( aRect.left, aRect.top); int iXCenter = RectBox.left + ( (RectBox.right - RectBox.left) / 2); int iYCenter = RectBox.top + ( (RectBox.bottom - RectBox.top) / 2); CPen psPen(PS_SOLID, 1, m_pTreeColumn->GetTreeLineColor() ); CPen* pOldPen = apDC->SelectObject(&psPen); TREE_IMAGE TreeImage = TREE_IMAGE_DOCUMENT; // is it the very last row? if( !GetForcePlus() && m_iRow >= m_pTreeColumn->GetRowCount() - 1) { iXCenter -= m_pTreeColumn->GetDefTreeIndent(); // draw |__ (with long horizontal) if( TryMoveTo( aRect, apDC, iXCenter, aRect.top) ) if( TryLineTo( aRect, apDC, iXCenter, iYCenter) ) TryLineTo( aRect, apDC, RectBox.right, iYCenter); apDC->SelectObject(pOldPen); if( m_pTreeColumn->GetTreeUsesImages()) SetImage( TreeImage); return; } // is it a plus or minus? Check up to all remaining entries for an answer BOOL bIsPlus; BOOL bIsMinus; BOOL bIsLastLeaf; CGridCtrl* pGrid = GetGrid(); ASSERT( pGrid != NULL); int iVertLineBottom = aRect.bottom + 1; // if drawing a horizontal line, // overwrite the grid line in case it is // not displayed BOOL bIsBranch = m_pTreeColumn->TreeCellHasPlusMinus( m_iRow, // row of Cell to check &bIsPlus, // returns: T=Is a plus &bIsMinus, // returns: T=Is a minus &bIsLastLeaf);// returns: T=Is Last Leaf if( bIsBranch ) { // returns: T=cell has a plus or minus; F=not if( bIsPlus) TreeImage = TREE_IMAGE_FOLDER_CLOSED; else TreeImage = TREE_IMAGE_FOLDER_OPEN; // draw a square box BOOL bCanDrawRectangle = aRect.PtInRect( CPoint( RectBox.left, RectBox.top )) && aRect.PtInRect( CPoint( RectBox.right, RectBox.bottom )); if( bCanDrawRectangle ) { apDC->Rectangle( RectBox.left, RectBox.top, RectBox.right, RectBox.bottom); } // draw a minus sign if( TryMoveTo( aRect, apDC, RectBox.left + TREE_BOX_MARGIN, iYCenter) ) TryLineTo( aRect, apDC, RectBox.right - TREE_BOX_MARGIN, iYCenter); // draw small horizontal tick just to the left of the box if not // level 1 if( ucLevelCurrent > 1) { // draw - if( TryMoveTo( aRect, apDC, iXCenter - m_pTreeColumn->GetDefTreeIndent(), iYCenter) ) TryLineTo( aRect, apDC, RectBox.left, iYCenter); } if( bIsPlus) { // ... make it into a plus sign if( TryMoveTo( aRect, apDC, iXCenter, RectBox.top + TREE_BOX_MARGIN) ) TryLineTo( aRect, apDC, iXCenter, RectBox.bottom - TREE_BOX_MARGIN); } else { // it's a minus sign, so draw vertical tick below box center // draw | if( TryMoveTo( aRect, apDC, iXCenter, RectBox.bottom) ) TryLineTo( aRect, apDC, iXCenter, iVertLineBottom); } } else if( ucLevelCurrent > 1) { // it's not a box, it's a leaf of the tree. Just draw a horizontal line CGridTreeCellBase* pGridTreeCellBase = (CGridTreeCellBase*)pGrid->GetCell( m_iRow + 1, m_pTreeColumn->GetColumnWithTree()); if( pGridTreeCellBase == NULL) return; bIsNextShowing = pGridTreeCellBase->IsViewable(); ucLevelNext = pGridTreeCellBase->GetLevel(); if( ucLevelCurrent > ucLevelNext) { bIsLastLeaf = TRUE; } // draw - if( TryMoveTo( aRect, apDC, iXCenter - m_pTreeColumn->GetDefTreeIndent(), iYCenter) ) TryLineTo( aRect, apDC, iXCenter, iYCenter); } // draw nearest to text vertical lines that appear to the left of the box for all // levels except level 1 if( ucLevelCurrent > 1) { iXCenter -= m_pTreeColumn->GetDefTreeIndent(); if( bIsLastLeaf) iLineStop = iYCenter; else iLineStop = iVertLineBottom; // draw | if( TryMoveTo( aRect, apDC, iXCenter, aRect.top) ) TryLineTo( aRect, apDC, iXCenter, iLineStop); } BOOL bFoundBranch; unsigned char ucLevelToCheck = ucLevelCurrent; // draw vertical lines that appear to the left of the box for all appropriate // levels except level 1 for( int i1=ucLevelCurrent - 1; i1 > 1; i1--) { bFoundBranch = FALSE; int iStartPt = m_iRow + 1; for( int i2=iStartPt; i2 <= iNbrTreeElements; i2++) { CGridTreeCellBase* pGridTreeCellBase = (CGridTreeCellBase*)pGrid->GetCell( i2, m_pTreeColumn->GetColumnWithTree()); if( pGridTreeCellBase == NULL) return; ucLevelNext = pGridTreeCellBase->GetLevel(); if( ucLevelNext + 1 < ucLevelToCheck) break; if( ucLevelNext + 1 == ucLevelToCheck) { bIsNextShowing = pGridTreeCellBase->IsViewable(); if( bIsNextShowing) bFoundBranch = TRUE; break; } } iXCenter -= m_pTreeColumn->GetDefTreeIndent(); if( bFoundBranch) { // draw | if( TryMoveTo( aRect, apDC, iXCenter, aRect.top) ) TryLineTo( aRect, apDC, iXCenter, iVertLineBottom); } ucLevelToCheck--; // each loop heads to level 1 } // cleanup apDC->SelectObject(pOldPen); if( m_pTreeColumn->GetTreeUsesImages()) SetImage( TreeImage); }