📄 treelistctrl.cpp
字号:
}
}
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 + -