⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treelistctrl.cpp

📁 一个关于数据结结的
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		}
	}

	return;
}

void CTreeListCtrl::DrawBkgndBmp( CDC* pDC, CRect rcClip, CBitmap* pBkgnd )
{
	// draw bitmap background
	CRect rcClient;
	BITMAP bmBkgnd;
	
	GetClientRect( rcClient );
	pBkgnd->GetBitmap( &bmBkgnd );
	
	CDC dc;
	dc.CreateCompatibleDC( pDC );
	CBitmap* pBmp = dc.SelectObject( pBkgnd );

	pDC->IntersectClipRect( rcClip );

	int nPerfix = - ( GetScrollPos( SB_HORZ ) % bmBkgnd.bmWidth );
	for( int y = 0; y < rcClient.Height(); y += bmBkgnd.bmHeight )
		for( int x = nPerfix; x < rcClient.Width(); x += bmBkgnd.bmWidth )
			pDC->BitBlt( x, y, bmBkgnd.bmWidth, bmBkgnd.bmHeight, &dc, 0, 0, SRCCOPY);

	::ExtSelectClipRgn( pDC->m_hDC, DEFAULT_HRGN, RGN_COPY );

	dc.SelectObject( pBmp );
	dc.DeleteDC();

}

void CTreeListCtrl::DrawItems( CDC* pDC, CRect rcClip )
{
	// draw items
	CTreeListItem* pShowItem;
	
	pShowItem = GetFirstVisibleItem();
	if( pShowItem == NULL )
		return;

	CPen Pen( PS_SOLID, 1, m_crGrid );
	CPen* pOldPen	= pDC->SelectObject( &Pen );
	CFont* pOldFont	= pDC->SelectObject( &m_Font );
	int nOldMode = pDC->SetBkMode( TRANSPARENT );

	CRect rcClient;
	GetClientRect( rcClient );

	CRect rcItem;
	rcItem.SetRect( 0, 0, GetWidth(), GetItemHeight() );
	rcItem.OffsetRect( m_rcTreeList.left, m_rcTreeList.top );
	rcItem.OffsetRect( -GetScrollPos( SB_HORZ ), 0 );

	int nFirstRow;
	int nShowRows;

	nFirstRow	=	GetScrollPos( SB_VERT );
	nShowRows	=	m_rcTreeList.Height() / GetItemHeight() + 1;

	pShowItem	=	GetFirstShowItem( nFirstRow );

	for( int iRow=nFirstRow; iRow<= nFirstRow + nShowRows && iRow < GetVisibleCount(); iRow++, pShowItem = GetNextShowItem( pShowItem ) )
	{
		ASSERT( pShowItem != NULL );

		COLORREF crBkColor;

		if( !(m_dwStyle&TLC_BKGNDIMAGE) )
		{
			if( !(CWnd::GetStyle()&WS_DISABLED) )
			{
				if( m_dwStyle&TLC_DOUBLECOLOR )
				{
					if( iRow%2 == 1 )
						crBkColor = m_crBkColor_1;
					else
						crBkColor = m_crBkColor_2;
				}
				else
				{
					crBkColor = m_crBkColor_0;
				}
			}
			else
			{
				if( m_dwStyle&TLC_DOUBLECOLOR )
				{
					if( iRow%2 == 1 )
						crBkColor = m_crBkDisable_1;
					else
						crBkColor = m_crBkDisable_2;
				}
				else
				{
					crBkColor = m_crBkDisable_0;
				}
			}
			pDC->FillSolidRect( rcItem, crBkColor );
		}

		DrawItem( pDC, rcItem, pShowItem ); 
		
		if( m_dwStyle&TLC_HGRID_FULL && rcItem.right<rcClient.right )
		{
			pDC->MoveTo( rcItem.right, rcItem.bottom - 1);
			pDC->LineTo( rcClient.right, rcItem.bottom - 1);
		}

		rcItem.OffsetRect( 0, m_nItemHeight );
	}

	if( GetVisibleCount() > 0 )
	{
		if( m_dwStyle&TLC_HGRID && !(m_dwStyle&TLC_HGRID_EXT) && !(m_dwStyle&TLC_VGRID_EXT) )
		{
			pDC->MoveTo( rcItem.left, rcItem.top - 1);
			pDC->LineTo( rcItem.right-1, rcItem.top - 1);
		}
	}

	for( int iGrid=GetVisibleCount(); iGrid<= nFirstRow + nShowRows; iGrid++ )
	{
		COLORREF crBkColor;

		if( !(m_dwStyle&TLC_BKGNDIMAGE) )
		{
			if( !(CWnd::GetStyle()&WS_DISABLED) )
			{
				if( m_dwStyle&TLC_DOUBLECOLOR )
				{
					if( iGrid%2 == 1 )
						crBkColor = m_crBkColor_1;
					else
						crBkColor = m_crBkColor_2;
				}
				else
				{
					crBkColor = m_crBkColor_0;
				}
			}
			else
			{
				if( m_dwStyle&TLC_DOUBLECOLOR )
				{
					if( iGrid%2 == 1 )
						crBkColor = m_crBkDisable_1;
					else
						crBkColor = m_crBkDisable_2;
				}
				else
				{
					crBkColor = m_crBkDisable_0;
				}
			}
			pDC->FillSolidRect( rcItem, crBkColor );
		}

		DrawGrid( pDC, rcItem );

		if( m_dwStyle&TLC_HGRID_EXT && m_dwStyle&TLC_HGRID_FULL && rcItem.right<rcClient.right )
		{
			pDC->MoveTo( rcItem.right, rcItem.bottom - 1 );
			pDC->LineTo( rcClient.right, rcItem.bottom - 1 );
		}

		rcItem.OffsetRect( 0, m_nItemHeight );
	}

	pDC->SetBkMode( nOldMode );
	pDC->SelectObject( pOldFont );
	pDC->SelectObject( pOldPen );
	return;
}

void CTreeListCtrl::DrawItem( CDC* pDC, CRect rcItem, CTreeListItem* pItem )
{
	// draw item background
	DrawItemBkgnd( pDC, rcItem, pItem );

	// draw all columns
	CTreeListColumnInfo* pColumnInfo;
	int nColPos = 0;
	for( int iShow = 0; iShow < m_arShows.GetSize(); iShow++, nColPos += pColumnInfo->m_nWidth )
	{
		int iCol;
		
		// do NOT draw zero column;
		iCol = m_arShows[iShow];
		pColumnInfo = (CTreeListColumnInfo*)m_arColumns[iCol];
		if( pColumnInfo->m_nWidth == 0 )
			continue;

		CRect rcColumn;
		rcColumn.SetRect( 0, rcItem.top, pColumnInfo->m_nWidth, rcItem.bottom );
		rcColumn.OffsetRect( nColPos, 0 );
		rcColumn.OffsetRect( -GetScrollPos( SB_HORZ ), 0 );

		if( iCol == 0 )
		{
			if ( m_dwStyle&TLC_TREELIST )
				DrawItemTree( pDC, rcColumn, pItem, iCol );
			else
				DrawItemMain( pDC, rcColumn, pItem, iCol );
		}
		else
		{
			DrawItemList( pDC, rcColumn, pItem, iCol );
		}

	}

	CRect rcFocus;
	if( pItem == m_pFocusItem )
	{
		CPen pen;
		pen.CreatePen( PS_SOLID, 1, (COLORREF)0x000000 );
		CPen* ppen = pDC->SelectObject( &pen );

		CRect rcFocus;
		rcFocus.SetRect( 0, rcItem.top, GetWidth(), rcItem.bottom );
		rcFocus.OffsetRect( -GetScrollPos( SB_HORZ ), 0 );

		if( GetStyle()&TLC_HGRID )
			rcFocus.DeflateRect( 0, 0, 0, 1 );

		if( GetStyle()&TLC_VGRID )
			rcFocus.DeflateRect( 0, 0, 1, 0 );

		COLORREF crBkgnd, croldBkgnd;
		if( CWnd::GetStyle()&WS_DISABLED )
		{
			if( m_dwStyle&TLC_BKGNDIMAGE )
				crBkgnd = m_crBkDisable;
			else if( m_dwStyle&TLC_BKGNDCOLOR )
				crBkgnd = m_crBkDisable;
			else
				crBkgnd = m_crBkDisable_0;
		}
		else
		{
			if( m_dwStyle&TLC_BKGNDIMAGE )
				crBkgnd = m_crBkColor;
			else if( m_dwStyle&TLC_BKGNDCOLOR )
				crBkgnd = m_crBkColor;
			else
				crBkgnd = m_crBkColor_0;
		}

		croldBkgnd = pDC->SetBkColor( crBkgnd );
		pDC->SetTextColor( m_crText );
		pDC->DrawFocusRect( rcFocus );
		pDC->SetBkColor( croldBkgnd );

		pDC->SelectObject( ppen );
	}

	return;
}

void CTreeListCtrl::DrawGrid( CDC* pDC, CRect rcItem )
{
	// draw all grids
	CTreeListColumnInfo* pColumnInfo;
	int nColPos = 0;
	for( int iShow = 0; iShow < m_arShows.GetSize(); iShow++, nColPos += pColumnInfo->m_nWidth )
	{
		int iCol;
		
		iCol = m_arShows[iShow];
		pColumnInfo = (CTreeListColumnInfo*)m_arColumns[iCol];
		if( pColumnInfo->m_nWidth == 0 )
			continue;

		CRect rcColumn;
		rcColumn.SetRect( 0, rcItem.top, pColumnInfo->m_nWidth, rcItem.bottom );
		rcColumn.OffsetRect( nColPos, 0 );
		rcColumn.OffsetRect( -GetScrollPos( SB_HORZ ), 0 );

		if( iCol == 0 )
		{
			// draw vertical grid line of tree
			if( m_dwStyle&TLC_HGRID_EXT && m_dwStyle&TLC_TGRID )
			{
				pDC->MoveTo( rcColumn.left, rcColumn.bottom - 1);
				pDC->LineTo( rcColumn.right-1, rcColumn.bottom - 1);
			}

			if( m_dwStyle&TLC_VGRID_EXT )
			{
				pDC->MoveTo( rcColumn.right-1, rcColumn.bottom - 1);
				pDC->LineTo( rcColumn.right-1, rcColumn.top - 1 );
			}
		}
		else
		{
			// draw vertical grid line and horizonal grid lin
			if( m_dwStyle&TLC_HGRID_EXT )
			{
				pDC->MoveTo( rcColumn.left, rcColumn.bottom - 1);
				pDC->LineTo( rcColumn.right, rcColumn.bottom - 1);
			}

			if( m_dwStyle&TLC_VGRID_EXT )
			{
				pDC->MoveTo( rcColumn.right-1, rcColumn.bottom - 1);
				pDC->LineTo( rcColumn.right-1, rcColumn.top - 1 );
			}
		}
	}
}

void CTreeListCtrl::DrawItemBkgnd( CDC* pDC, CRect rcItem, CTreeListItem* pItem )
{
	// draw selected background
	CRect		rcBkgnd;
	COLORREF	crBkgnd;
	if( pItem == m_pTargetItem )
	{
		rcBkgnd.SetRect( 0, rcItem.top, GetWidth(), rcItem.bottom );
		rcBkgnd.OffsetRect( -GetScrollPos( SB_HORZ ), 0 );

		if( GetStyle()&TLC_HGRID )
			rcBkgnd.DeflateRect( 0, 0, 0, 1 );

		if( GetStyle()&TLC_VGRID )
			rcBkgnd.DeflateRect( 0, 0, 1, 0 );

		crBkgnd = m_crBkSelectedColumn;
		
		DrawItemExclude( pDC, rcItem, pItem );
		pDC->FillSolidRect( rcBkgnd, crBkgnd );
		::ExtSelectClipRgn( pDC->m_hDC, DEFAULT_HRGN, RGN_COPY );
	}
	else if( pItem->GetSelected() && GetStyle()&TLC_SHOWSELFULLROWS )
	{
		rcBkgnd.SetRect( 0, rcItem.top, GetWidth(), rcItem.bottom );
		rcBkgnd.OffsetRect( -GetScrollPos( SB_HORZ ), 0 );

		if( GetStyle()&TLC_HGRID )
			rcBkgnd.DeflateRect( 0, 0, 0, 1 );

		if( GetStyle()&TLC_VGRID )
			rcBkgnd.DeflateRect( 0, 0, 1, 0 );

		if( GetState( TLS_FOCUS ) )
		{
			if( !(m_dwStyle&TLC_MULTIPLESELECT) )
			{
				// single select
				crBkgnd = m_crBkSelectedRow;
			}
			else
			{
				// multiple select
				if( m_arSelects.GetSize() > 0 && pItem == (CTreeListItem*)m_arSelects[0] )
					crBkgnd = m_crBkSelectedRow;
				else
					crBkgnd = m_crBkSelected;
			}
			DrawItemExclude( pDC, rcItem, pItem );
			pDC->FillSolidRect( rcBkgnd, crBkgnd );
			::ExtSelectClipRgn( pDC->m_hDC, DEFAULT_HRGN, RGN_COPY );
		}
		else
		{
			if( m_dwStyle&TLC_SHOWSELALWAYS )
			{
				crBkgnd = m_crBkSelectedNoFocus;
				DrawItemExclude( pDC, rcItem, pItem );
				pDC->FillSolidRect( rcBkgnd, crBkgnd );
				::ExtSelectClipRgn( pDC->m_hDC, DEFAULT_HRGN, RGN_COPY );
			}
		}
	}
}

void CTreeListCtrl::DrawItemExclude( CDC* pDC, CRect rcItem, CTreeListItem* pItem )
{
	// exclude rects of selected item
	CTreeListColumnInfo* pColumnInfo;
	int nColPos = 0;

	if( !pItem->GetSelected() || !(GetStyle()&TLC_SHOWSELFULLROWS) )
		return;

	for( int iShow = 0; iShow < m_arShows.GetSize(); iShow++, nColPos += pColumnInfo->m_nWidth )
	{
		int iCol;
		
		iCol = m_arShows[iShow];
		pColumnInfo = (CTreeListColumnInfo*)m_arColumns[iCol];

		CRect rcColumn;
		rcColumn.SetRect( 0, rcItem.top, pColumnInfo->m_nWidth, rcItem.bottom );
		rcColumn.OffsetRect( nColPos, 0 );
		rcColumn.OffsetRect( -GetScrollPos( SB_HORZ ), 0 );

		if( iCol == 0 )
		{
			CRect rcExclude;
			int nPerfix = TLL_BORDER;
			if ( m_dwStyle&TLC_TREELIST )
			{
				nPerfix += TLL_WIDTH * ( pItem->m_nLevel - 1 );

				if( m_dwStyle&(TLC_TREELINE|TLC_BUTTON) )
					nPerfix += TLL_WIDTH;
			}

			if( m_dwStyle&TLC_CHECKBOX )
			{
				if( pItem->GetState()&TLIS_SHOWCHECKBOX )
				{
					CRect rcCheckBox;
					rcCheckBox.SetRect( 0, 0, TLL_WIDTH, TLL_WIDTH );
					rcCheckBox.OffsetRect( rcColumn.left + nPerfix, rcColumn.top + ( rcColumn.Height() - TLL_HEIGHT)/2 );
					rcExclude = rcColumn & rcCheckBox;

					if( !rcExclude.IsRectEmpty() )
						pDC->ExcludeClipRect( rcExclude );

					nPerfix += TLL_HEIGHT;
				}
			}

			if( m_dwStyle&TLC_LOCKBOX )
			{
				if( pItem->GetState()&TLIS_SHOWLOCKBOX )
				{
					CRect rcLockBox;
					rcLockBox.SetRect( 0, 0, TLL_WIDTH / 2, TLL_WIDTH );
					rcLockBox.OffsetRect( rcColumn.left + nPerfix, rcColumn.top + ( rcColumn.Height() - TLL_HEIGHT)/2 );
					rcExclude = rcColumn & rcLockBox;

					if( !rcExclude.IsRectEmpty() )
						pDC->ExcludeClipRect( rcExclude );

					nPerfix += TLL_HEIGHT / 2;
				}
			}
		
			if( m_dwStyle&TLC_IMAGE )
			{
				if( pItem->GetState()&TLIS_SHOWTREEIMAGE )
				{
					CRect rcImage;
					rcImage.SetRect( 0, 0, TLL_WIDTH, TLL_WIDTH );
					rcImage.OffsetRect( rcColumn.left + nPerfix, rcColumn.top + ( rcColumn.Height() - TLL_HEIGHT)/2 );
					rcExclude = rcColumn & rcImage;

					if( !rcExclude.IsRectEmpty() )
						pDC->ExcludeClipRect( rcExclude );

					nPerfix += TLL_HEIGHT;
				}
			}

			break;
		}
	}

}

void CTreeListCtrl::DrawItemTree( CDC* pDC, CRect rcColumn, CTreeListItem* pItem, int iCol )
{
	// draw tree column of treelist control
	CTreeListColumnInfo* pColumnInfo;
	pColumnInfo = (CTreeListColumnInfo*)m_arColumns[iCol];

	CRect rcGraph;
	rcGraph = rcColumn;
	rcGraph.DeflateRect( TLL_BORDER, 0, TLL_BORDER+1, 0 );
	if( rcGraph.Width() <= 0 )
		return;
	CRect rcTree;
	rcTree = rcGraph;
	rcTree.right = rcTree.left + TLL_WIDTH;

	int nPerfix = TLL_BORDER;
	// draw prefix vertical line
	for( int iLevel=1; iLevel<pItem->m_nLevel; iLevel++, nPerfix += TLL_WIDTH )
	{
		CTreeListItem* pCheckItem = pItem;
		while( pCheckItem->m_nLevel != iLevel )
		{
			pCheckItem = pCheckItem->m_pParent;
		}

		rcTree.left = rcColumn.left + nPerfix;
		rcTree.right = rcTree.left + TLL_WIDTH;

		if( pCheckItem->m_pNext != NULL )
		{
			if( iLevel != 1 || m_dwStyle&TLC_ROOTLINE )
			{
				DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_TOP | TLL_BOTTOM );				// ┃
			}
		}
	}

	// draw cross line
	if( m_dwStyle&(TLC_TREELINE|TLC_BUTTON) )
	{
		rcTree.left = rcColumn.left + nPerfix;
		rcTree.right = rcTree.left + TLL_WIDTH;
		if( pItem->m_nLevel == 1 )
		{
			// child item of root item
			if( m_dwStyle&TLC_ROOTLINE )
			{
				if( pItem->m_pPrev == NULL && pItem->m_pNext == NULL )
					DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_RIGHT );						// ━ ( right part )
				else if( pItem->m_pPrev == NULL )
					DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_RIGHT | TLL_BOTTOM );			// ┏
				else if( pItem->m_pNext == NULL )
					DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_RIGHT | TLL_TOP );				// ┗
				else
					DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_RIGHT | TLL_TOP | TLL_BOTTOM );	// ┣
			}
			else
			{
				DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_RIGHT );							// ━ ( right part )
			}
		}
		else
		{
			// child item of other items ( not root item )
			if( pItem->m_pNext == NULL )
				DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_RIGHT | TLL_TOP );					// ┗
			else
				DrawItemTreeLine( pDC, rcGraph, rcTree, TLL_RIGHT | TLL_TOP | TLL_BOTTOM );		// ┣
		}
		
		// draw button of child item of root item
		if( m_dwStyle&TLC_BUTTON )
		{
			if( pItem->GetState()&TLIS_EXPANDEDONCE )
			{
				if( pItem->m_pChild != NULL )
				{
					if( pItem->GetState()&TLIS_EXPANDED )
						DrawItemTreeButton( pDC, rcGraph, rcTree, TLB_MINUS );
					else
						DrawItemTreeButton( pDC, rcGraph, rcTree, TLB_PLUS );
				}				
			}
			else
			{
				DrawItemTreeButton( pDC, rcGraph, rcTree, TLB_UNKNOW );
			}
		}
		nPerfix += TLL_WIDTH;
	}

	// draw check box
	if( m_dwStyle&TLC_CHECKBOX )
	{
		if( pItem->GetState()&TLIS_SHOWCHECKBOX )
		{
			CRect rc

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -