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

📄 ctrllibrarytree.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					Select( m_pFocus, TS_TRUE, FALSE );
					Highlight( m_pFocus );
					NotifySelection();
					return;
				}
			}
		}
	}
	
	if ( pTo != NULL )
	{
		if ( ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0 || m_pFocus == NULL )
		{
			bChanged |= DeselectAll( m_pFocus = pTo );
			bChanged |= Select( m_pFocus );
		}
		else
		{
			bChanged |= Select( m_pFocus = pTo );
		}

		Highlight( m_pFocus );
	}

	if ( bChanged ) NotifySelection();
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeCtrl scrolling

void CLibraryTreeCtrl::UpdateScroll()
{
	SCROLLINFO pInfo;

	pInfo.cbSize	= sizeof(pInfo);
	pInfo.fMask		= SIF_ALL & ~SIF_TRACKPOS;
	pInfo.nMin		= 0;
	pInfo.nMax		= m_nTotal * ITEM_HEIGHT;
	pInfo.nPage		= m_nVisible;
	pInfo.nPos		= m_nScroll = max( 0, min( m_nScroll, pInfo.nMax - (int)pInfo.nPage + 1 ) );
	
	SetScrollInfo( SB_VERT, &pInfo, TRUE );
}

void CLibraryTreeCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	switch ( nSBCode )
	{
	case SB_BOTTOM:
		ScrollTo( 0xFFFFFFFF );
		break;
	case SB_LINEDOWN:
		ScrollBy( 16 );
		break;
	case SB_LINEUP:
		ScrollBy( -16 );
		break;
	case SB_PAGEDOWN:
		ScrollBy( m_nVisible );
		break;
	case SB_PAGEUP:
		ScrollBy( -m_nVisible );
		break;
	case SB_THUMBPOSITION:
	case SB_THUMBTRACK:
		ScrollTo( nPos );
		break;
	case SB_TOP:
		ScrollTo( 0 );
		break;
	}
}

BOOL CLibraryTreeCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	ScrollBy( zDelta * 3 * -ITEM_HEIGHT / WHEEL_DELTA );
	return TRUE;
}

void CLibraryTreeCtrl::ScrollBy(int nDelta)
{
	ScrollTo( max( 0, m_nScroll + nDelta ) );
}

void CLibraryTreeCtrl::ScrollTo(int nPosition)
{
	if ( nPosition == m_nScroll ) return;
	m_nScroll = nPosition;

	UpdateScroll();

	CRect rc;
	GetClientRect( &rc );
	RedrawWindow( &rc, NULL, RDW_INVALIDATE );
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeCtrl painting

BOOL CLibraryTreeCtrl::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

void CLibraryTreeCtrl::OnPaint() 
{
	CPaintDC dc( this );
	
	CRect rcClient;
	GetClientRect( &rcClient );
	
	CPoint pt( rcClient.left, rcClient.top - m_nScroll );

	CLibraryTreeItem** pChild = m_pRoot->m_pList;

	CFont* pOldFont = (CFont*)dc.SelectObject( &CoolInterface.m_fntNormal );

	for ( int nCount = m_pRoot->m_nCount ; nCount && pt.y < rcClient.bottom ; nCount--, pChild++ )
	{
		Paint( dc, rcClient, pt, *pChild );
	}

	dc.SelectObject( pOldFont );

	dc.FillSolidRect( &rcClient, CoolInterface.m_crWindow );
}

void CLibraryTreeCtrl::Paint(CDC& dc, CRect& rcClient, CPoint& pt, CLibraryTreeItem* pItem)
{
	CRect rc( pt.x, pt.y, pt.x, pt.y + ITEM_HEIGHT );
	pt.y += ITEM_HEIGHT;

	if ( rc.top >= rcClient.bottom )
	{
		return;
	}
	else if ( rc.bottom >= rcClient.top )
	{
		if ( pItem->m_bBold ) dc.SelectObject( &CoolInterface.m_fntBold );

		rc.right += 32 + dc.GetTextExtent( pItem->m_sText ).cx + 6;

		if ( dc.RectVisible( &rc ) )
		{
			pItem->Paint( dc, rc, m_pDropItem == pItem );
			dc.ExcludeClipRect( &rc );
		}

		if ( pItem->m_bBold ) dc.SelectObject( &CoolInterface.m_fntNormal );
	}

	if ( pItem->m_bExpanded && pItem->m_nCount )
	{
		pt.x += 16;

		CLibraryTreeItem** pChild = pItem->m_pList;

		for ( int nCount = pItem->m_nCount ; nCount ; nCount--, pChild++ )
		{
			Paint( dc, rcClient, pt, *pChild );
			if ( pt.y >= rcClient.bottom ) break;
		}

		pt.x -= 16;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeCtrl hit testing

CLibraryTreeItem* CLibraryTreeCtrl::HitTest(const POINT& point, RECT* pRect) const
{
	CRect rcClient;
	GetClientRect( &rcClient );
	
	CPoint pt( rcClient.left, rcClient.top - m_nScroll );

	CLibraryTreeItem** pChild = m_pRoot->m_pList;

	for ( int nCount = m_pRoot->m_nCount ; nCount && pt.y < rcClient.bottom ; nCount--, pChild++ )
	{
		CLibraryTreeItem* pItem = HitTest( rcClient, pt, *pChild, point, pRect );
		if ( pItem ) return pItem;
	}

	return NULL;
}

CLibraryTreeItem* CLibraryTreeCtrl::HitTest(CRect& rcClient, CPoint& pt, CLibraryTreeItem* pItem, const POINT& point, RECT* pRect) const
{
	CRect rc( rcClient.left, pt.y, rcClient.right, pt.y + ITEM_HEIGHT );
	pt.y += ITEM_HEIGHT;

	if ( rc.top >= rcClient.bottom + ITEM_HEIGHT )
	{
		return NULL;
	}
	else if ( rc.bottom >= rcClient.top - ITEM_HEIGHT )
	{
		if ( rc.PtInRect( point ) )
		{
			if ( pRect )
			{
				CopyMemory( pRect, &rc, sizeof(RECT) );
				pRect->left = pt.x;
			}
			return pItem;
		}
	}

	if ( pItem->m_bExpanded && pItem->m_nCount )
	{
		pt.x += 16;

		CLibraryTreeItem** pChild = pItem->m_pList;

		for ( int nCount = pItem->m_nCount ; nCount ; nCount--, pChild++ )
		{
			CLibraryTreeItem* pItem = HitTest( rcClient, pt, *pChild, point, pRect );
			if ( pItem ) return pItem;
			if ( pt.y >= rcClient.bottom + ITEM_HEIGHT ) break;
		}

		pt.x -= 16;
	}

	return NULL;
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeCtrl rect lookup

BOOL CLibraryTreeCtrl::GetRect(CLibraryTreeItem* pItem, RECT* pRect)
{
	CRect rcClient;
	GetClientRect( &rcClient );
	
	CPoint pt( rcClient.left, rcClient.top - m_nScroll );

	CLibraryTreeItem** pChild = m_pRoot->m_pList;

	for ( int nCount = m_pRoot->m_nCount ; nCount ; nCount--, pChild++ )
	{
		if ( GetRect( pt, *pChild, pItem, pRect ) ) return TRUE;
	}

	return FALSE;
}

BOOL CLibraryTreeCtrl::GetRect(CPoint& pt, CLibraryTreeItem* pItem, CLibraryTreeItem* pFind, RECT* pRect)
{
	if ( pItem == pFind )
	{
		pRect->left		= pt.x;
		pRect->top		= pt.y;
		pRect->right	= pt.x;
		pRect->bottom	= pt.y = pRect->top + ITEM_HEIGHT;

		CClientDC dc( this );
		CFont* pOld = (CFont*)dc.SelectObject( pItem->m_bBold ?
			&CoolInterface.m_fntBold : &CoolInterface.m_fntNormal );
		pRect->right += 33 + dc.GetTextExtent( pItem->m_sText ).cx + 4;
		dc.SelectObject( pOld );

		return TRUE;
	}
	else
	{
		pt.y += ITEM_HEIGHT;
	}

	if ( pItem->m_bExpanded && pItem->m_nCount )
	{
		pt.x += 16;

		CLibraryTreeItem** pChild = pItem->m_pList;

		for ( int nCount = pItem->m_nCount ; nCount ; nCount--, pChild++ )
		{
			if ( GetRect( pt, *pChild, pFind, pRect ) ) return TRUE;
		}

		pt.x -= 16;
	}

	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeCtrl drag setup

#define MAX_DRAG_SIZE	256
#define MAX_DRAG_SIZE_2	128

void CLibraryTreeCtrl::StartDragging(CPoint& ptMouse)
{
	CImageList* pImage = CreateDragImage( ptMouse );
	if ( pImage == NULL ) return;

	ReleaseCapture();
	ClientToScreen( &ptMouse );

	CLibraryFrame* pFrame	= (CLibraryFrame*)GetOwner();
	CLibraryList* pList		= new CLibraryList( m_nSelected );
	
	for (	CLibraryTreeItem* pItem = m_pSelFirst ; pItem ;
			pItem = pItem->m_pSelNext )
	{
		if ( pItem->m_pVirtual ) pList->AddTail( (DWORD)pItem->m_pVirtual );
	}

	pFrame->DragObjects( pList, pImage, ptMouse );
}

CImageList* CLibraryTreeCtrl::CreateDragImage(const CPoint& ptMouse)
{
	CRect rcClient, rcOne, rcAll( 32000, 32000, -32000, -32000 );

	GetClientRect( &rcClient );

	for (	CLibraryTreeItem* pItem = m_pSelFirst ; pItem ;
			pItem = pItem->m_pSelNext )
	{
		GetRect( pItem, &rcOne );
		
		if ( rcOne.IntersectRect( &rcClient, &rcOne ) )
		{
			rcAll.left		= min( rcAll.left, rcOne.left );
			rcAll.top		= min( rcAll.top, rcOne.top );
			rcAll.right		= max( rcAll.right, rcOne.right );
			rcAll.bottom	= max( rcAll.bottom, rcOne.bottom );
		}
	}

	BOOL bClipped = rcAll.Height() > MAX_DRAG_SIZE;

	if ( bClipped )
	{
		rcAll.left		= max( rcAll.left, ptMouse.x - MAX_DRAG_SIZE_2 );
		rcAll.right		= max( rcAll.right, ptMouse.x + MAX_DRAG_SIZE_2 );
		rcAll.top		= max( rcAll.top, ptMouse.y - MAX_DRAG_SIZE_2 );
		rcAll.bottom	= max( rcAll.bottom, ptMouse.y + MAX_DRAG_SIZE_2 );
	}

	CClientDC dcClient( this );
	CDC dcMem, dcDrag;
	CBitmap bmDrag;
				
	if ( ! dcMem.CreateCompatibleDC( &dcClient ) )
		return NULL;
	if ( ! dcDrag.CreateCompatibleDC( &dcClient ) )
		return NULL;
	if ( ! bmDrag.CreateCompatibleBitmap( &dcClient, rcAll.Width(), rcAll.Height() ) )
		return NULL;

	CBitmap *pOldDrag = dcDrag.SelectObject( &bmDrag );

	dcDrag.FillSolidRect( 0, 0, rcAll.Width(), rcAll.Height(), RGB( 250, 255, 250 ) );
	
	CRgn pRgn;

	if ( bClipped )
	{
		CPoint ptMiddle( ptMouse.x - rcAll.left, ptMouse.y - rcAll.top );
		pRgn.CreateEllipticRgn(	ptMiddle.x - MAX_DRAG_SIZE_2, ptMiddle.y - MAX_DRAG_SIZE_2,
								ptMiddle.x + MAX_DRAG_SIZE_2, ptMiddle.y + MAX_DRAG_SIZE_2 );
		dcDrag.SelectClipRgn( &pRgn );
	}

	CFont* pOldFont = (CFont*)dcDrag.SelectObject( &CoolInterface.m_fntNormal );

	for (	pItem = m_pSelFirst ; pItem ; pItem = pItem->m_pSelNext )
	{
		GetRect( pItem, &rcOne );
		CRect rcDummy;
		
		if ( rcDummy.IntersectRect( &rcAll, &rcOne ) )
		{
			rcOne.OffsetRect( -rcAll.left, -rcAll.top );
			pItem->Paint( dcDrag, rcOne, FALSE, RGB( 250, 255, 250 ) );
		}
	}

	dcDrag.SelectObject( pOldFont );
	dcDrag.SelectObject( pOldDrag );
	dcDrag.DeleteDC();
	
	CImageList* pAll = new CImageList();
	pAll->Create( rcAll.Width(), rcAll.Height(), ILC_COLOR16|ILC_MASK, 1, 1 );
	pAll->Add( &bmDrag, RGB( 250, 255, 250 ) ); 

	bmDrag.DeleteObject();

	pAll->BeginDrag( 0, ptMouse - rcAll.TopLeft() );

	return pAll;
}


/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeItem construction

CLibraryTreeItem::CLibraryTreeItem(CLibraryTreeItem* pParent)
{
	m_pParent		= pParent;
	m_pList			= NULL;
	m_nCount		= 0;
	m_nBuffer		= 0;
	m_pSelPrev		= NULL;
	m_pSelNext		= NULL;
	m_nCleanCookie	= 0;
	
	m_bExpanded		= FALSE;
	m_bSelected		= FALSE;
	m_bContract1	= FALSE;
	m_bContract2	= FALSE;

	m_pPhysical		= NULL;
	m_pVirtual		= NULL;
	m_nCookie		= 0;
	m_bBold			= FALSE;
    m_bShared		= TRUE;
	m_bCollection	= FALSE;
	m_nIcon16		= -1;
}

CLibraryTreeItem::~CLibraryTreeItem()
{
	if ( m_pList )
	{
		Clear();
		delete [] m_pList;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeItem add

CLibraryTreeItem* CLibraryTreeItem::Add(LPCTSTR pszName)
{
	if ( m_nCount == m_nBuffer )
	{
		if ( m_nBuffer ) m_nBuffer += min( m_nBuffer, 16 ); else m_nBuffer = 4;

		CLibraryTreeItem** pList = new CLibraryTreeItem*[ m_nBuffer ];

		if ( m_nCount ) CopyMemory( pList, m_pList, m_nCount * 4 );
		if ( m_pList ) delete [] m_pList;

		m_pList = pList;
	}

	if ( m_nCount == 0 ) return m_pList[ m_nCount++ ] = new CLibraryTreeItem( this );
	
	for ( int nFirst = 0, nLast = m_nCount - 1 ; nLast >= nFirst ; )
	{
		int nMiddle = ( nFirst + nLast ) >> 1;

		CLibraryTreeItem* pItem = m_pList[ nMiddle ];

		if ( _tcsicoll( pszName, pItem->m_sText ) >= 0 )
		{
			nFirst = nMiddle + 1;
		}
		else
		{
			nLast = nMiddle - 1;
		}
	}

	MoveMemory( m_pList + nFirst + 1, m_pList + nFirst, ( m_nCount - nFirst ) << 2 );
	m_nCount++;

	return m_pList[ nFirst ] = new CLibraryTreeItem( this );
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeItem delete

void CLibraryTreeItem::Delete()
{
	m_pParent->Delete( this );
}

void CLibraryTreeItem::Delete(CLibraryTreeItem* pItem)
{
	ASSERT( pItem->m_bSelected == FALSE );

	CLibraryTreeItem** pChild = m_pList;

	for ( int nChild = m_nCount ; nChild ; nChild--, pChild++ )
	{
		if ( *pChild == pItem )
		{
			MoveMemory( pChild, pChild + 1, 4 * ( nChild - 1 ) );
			m_nCount--;
			break;
		}
	}

	delete pItem;
}

void CLibraryTreeItem::Delete(int nItem)
{
	if ( nItem < 0 || nItem >= m_nCount ) return;

	ASSERT( m_pList[ nItem ]->m_bSelected == FALSE );
	delete m_pList[ nItem ];
	MoveMemory( m_pList + nItem, m_pList + nItem + 1, 4 * ( m_nCount - nItem - 1 ) );
	m_nCount--;
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeItem clear

void CLibraryTreeItem::Clear()
{
	if ( m_pList )
	{
		for ( int nChild = 0 ; nChild < m_nCount ; nChild++ ) delete m_pList[ nChild ];
		delete [] m_pList;
	}
	
	m_pList		= NULL;
	m_nCount	= 0;
	m_nBuffer	= 0;
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeItem visibility

BOOL CLibraryTreeItem::IsVisible() const
{
	for ( CLibraryTreeItem* pRoot = m_pParent ; pRoot ; pRoot = pRoot->m_pParent )
	{
		if ( ! pRoot->m_bExpanded ) return FALSE;
	}

	return TRUE;
}

int CLibraryTreeItem::GetChildCount() const
{
	int nCount = m_nCount;

	CLibraryTreeItem** pChild = m_pList;

	for ( int nChild = m_nCount ; nChild ; nChild--, pChild++ )
	{
		if ( (*pChild)->m_bExpanded ) nCount += (*pChild)->GetChildCount();
	}

	return nCount;
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeItem paint

void CLibraryTreeItem::Paint(CDC& dc, CRect& rc, BOOL bTarget, COLORREF crBack) const
{
	if ( crBack == CLR_NONE ) crBack = CoolInterface.m_crWindow;

	if ( m_nCount )
	{
		ImageList_DrawEx( ShellIcons.GetHandle( 16 ),
			m_bExpanded ? SHI_MINUS : SHI_PLUS,
			dc.GetSafeHdc(), rc.left, rc.top, 16, 16,
			crBack, CLR_NONE, ILD_NORMAL );
	}
	else
	{
		dc.FillSolidRect( rc.left, rc.top, 16, 16, crBack );
	}

	int nImage = ( m_bExpanded && m_nCount ) ? SHI_FOLDER_OPEN : SHI_FOLDER_CLOSED;
	if ( m_nIcon16 >= 0 ) nImage = m_nIcon16;

	UINT nIconStyle = ( m_bSelected || bTarget ) ? ILD_SELECTED : ILD_NORMAL;

	if ( ! m_bShared ) nIconStyle |= INDEXTOOVERLAYMASK( SHI_O_LOCKED );
	if ( m_bCollection ) nIconStyle |= INDEXTOOVERLAYMASK( SHI_O_COLLECTION );
	
	ImageList_DrawEx( ShellIcons.GetHandle( 16 ), nImage,
		dc.GetSafeHdc(), rc.left + 16, rc.top, 16, 16,
		crBack, CLR_DEFAULT, nIconStyle );
	
	crBack = ( m_bSelected || bTarget ) ? CoolInterface.m_crHighlight : crBack;
	COLORREF crText = ( m_bSelected || bTarget ) ? CoolInterface.m_crHiText : CoolInterface.m_crText;

	dc.SetTextColor( crText );
	dc.SetBkColor( crBack );
	dc.SetBkMode( OPAQUE );

	rc.left += 32;
	dc.ExtTextOut( rc.left + 3, rc.top + 1, ETO_OPAQUE|ETO_CLIPPED, &rc,
		m_sText, NULL );
	rc.left -= 32;
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeItem get child files

int CLibraryTreeItem::GetFileList(CLibraryList* pList, BOOL bRecursive) const
{
	if ( LibraryFolders.CheckFolder( m_pPhysical, TRUE ) )
	{
		return m_pPhysical->GetFileList( pList, bRecursive );
	}
	else if ( LibraryFolders.CheckAlbum( m_pVirtual ) )
	{
		return m_pVirtual->GetFileList( pList, bRecursive );
	}
	
	return 0;
}

⌨️ 快捷键说明

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