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

📄 ctrlbrowsetree.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 CBrowseTreeCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	ScrollBy( zDelta * 3 * -ITEM_HEIGHT / WHEEL_DELTA );
	return TRUE;
}

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

void CBrowseTreeCtrl::ScrollTo(int nPosition)
{
	if ( nPosition == m_nScroll ) return;
	m_nScroll = nPosition;
	
	UpdateScroll();
	
	CRect rc;
	GetClientRect( &rc );
	RedrawWindow( &rc, NULL, RDW_INVALIDATE );
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeCtrl painting

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

void CBrowseTreeCtrl::OnPaint() 
{
	CPaintDC dc( this );
	
	CRect rcClient;
	GetClientRect( &rcClient );
	
	CPoint pt( rcClient.left, rcClient.top - m_nScroll );
	
	CBrowseTreeItem** 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 CBrowseTreeCtrl::Paint(CDC& dc, CRect& rcClient, CPoint& pt, CBrowseTreeItem* 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, FALSE );
			dc.ExcludeClipRect( &rc );
		}
		
		if ( pItem->m_bBold ) dc.SelectObject( &CoolInterface.m_fntNormal );
	}

	if ( pItem->m_bExpanded && pItem->m_nCount )
	{
		pt.x += 16;
		
		CBrowseTreeItem** 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;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeCtrl hit testing

CBrowseTreeItem* CBrowseTreeCtrl::HitTest(const POINT& point, RECT* pRect) const
{
	CRect rcClient;
	GetClientRect( &rcClient );
	
	CPoint pt( rcClient.left, rcClient.top - m_nScroll );
	
	CBrowseTreeItem** pChild = m_pRoot->m_pList;
	
	for ( int nCount = m_pRoot->m_nCount ; nCount && pt.y < rcClient.bottom ; nCount--, pChild++ )
	{
		CBrowseTreeItem* pItem = HitTest( rcClient, pt, *pChild, point, pRect );
		if ( pItem ) return pItem;
	}
	
	return NULL;
}

CBrowseTreeItem* CBrowseTreeCtrl::HitTest(CRect& rcClient, CPoint& pt, CBrowseTreeItem* 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;

		CBrowseTreeItem** pChild = pItem->m_pList;

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

		pt.x -= 16;
	}

	return NULL;
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeCtrl rect lookup

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

	CBrowseTreeItem** 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 CBrowseTreeCtrl::GetRect(CPoint& pt, CBrowseTreeItem* pItem, CBrowseTreeItem* 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;

		CBrowseTreeItem** 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;
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeCtrl virtual tree

void CBrowseTreeCtrl::OnTreePacket(CG2Packet* pPacket)
{
	BOOL bNotify = m_nSelected != 0;
	Clear();
	
	pPacket->Seek( 0 );
	OnTreePacket( pPacket, pPacket->m_nLength, m_pRoot );
	m_nTotal = m_pRoot->GetChildCount();
	
	Invalidate();
	if ( bNotify ) NotifySelection();
}

void CBrowseTreeCtrl::OnTreePacket(CG2Packet* pPacket, DWORD nFinish, CBrowseTreeItem* pItem)
{
	BOOL bCompound;
	CHAR szType[9];
	DWORD nLength;
	
	while (	pPacket->m_nPosition < nFinish &&
			pPacket->ReadPacket( szType, nLength, &bCompound ) )
	{
		DWORD nNext = pPacket->m_nPosition + nLength;
		
		if ( ( strcmp( szType, "PF" ) == 0 || strcmp( szType, "VF" ) == 0 ) && bCompound == TRUE )
		{
			CBrowseTreeItem* pChild = new CBrowseTreeItem( pItem );
			OnTreePacket( pPacket, nNext, pChild );
			pChild->m_bExpanded = ( pItem == m_pRoot );
			pItem->Add( pChild );
		}
		else if ( strcmp( szType, "DN" ) == 0 && bCompound == FALSE )
		{
			pItem->m_sText = pPacket->ReadString( nLength );
		}
		else if ( strcmp( szType, "MD" ) == 0 && bCompound == FALSE )
		{
			CXMLElement* pXML = CXMLElement::FromString( pPacket->ReadString( nLength ) );
			if ( pXML != NULL ) pItem->AddXML( pXML );
		}
		else if ( strcmp( szType, "FILES" ) == 0 && bCompound == FALSE )
		{
			if ( pItem->m_pFiles != NULL ) delete [] pItem->m_pFiles;
			
			pItem->m_nFiles = nLength / 4;
			pItem->m_pFiles = new DWORD[ pItem->m_nFiles ];
			
			for ( DWORD nCount = pItem->m_nFiles ; nCount ; nCount-- )
			{
				pItem->m_pFiles[ nCount - 1 ] = pPacket->ReadLongBE();
			}
		}
		
		pPacket->m_nPosition = nNext;
	}
}


/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeItem construction

CBrowseTreeItem::CBrowseTreeItem(CBrowseTreeItem* 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_nCookie		= 0;
	m_bBold			= FALSE;
	m_nIcon16		= -1;
	
	m_pSchema		= NULL;
	m_pFiles		= NULL;
	m_nFiles		= 0;
}

CBrowseTreeItem::~CBrowseTreeItem()
{
	if ( m_pFiles != NULL )
	{
		delete [] m_pFiles;
	}
	
	if ( m_pList != NULL )
	{
		Clear();
		delete [] m_pList;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeItem add

CBrowseTreeItem* CBrowseTreeItem::Add(LPCTSTR pszName)
{
	if ( m_nCount == m_nBuffer )
	{
		if ( m_nBuffer ) m_nBuffer += min( m_nBuffer, 16 ); else m_nBuffer = 4;
		
		CBrowseTreeItem** pList = new CBrowseTreeItem*[ 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 CBrowseTreeItem( this );
	
	for ( int nFirst = 0, nLast = m_nCount - 1 ; nLast >= nFirst ; )
	{
		int nMiddle = ( nFirst + nLast ) >> 1;
		
		CBrowseTreeItem* 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 CBrowseTreeItem( this );
}

CBrowseTreeItem* CBrowseTreeItem::Add(CBrowseTreeItem* pNewItem)
{
	if ( m_nCount == m_nBuffer )
	{
		if ( m_nBuffer ) m_nBuffer += min( m_nBuffer, 16 ); else m_nBuffer = 4;
		
		CBrowseTreeItem** pList = new CBrowseTreeItem*[ 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++ ] = pNewItem;
	
	for ( int nFirst = 0, nLast = m_nCount - 1 ; nLast >= nFirst ; )
	{
		int nMiddle = ( nFirst + nLast ) >> 1;
		
		CBrowseTreeItem* pItem = m_pList[ nMiddle ];
		
		if ( _tcsicoll( pNewItem->m_sText, 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 ] = pNewItem;
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeItem delete

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

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

	CBrowseTreeItem** 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 CBrowseTreeItem::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--;
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeItem clear

void CBrowseTreeItem::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;
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeItem visibility

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

	return TRUE;
}

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

	CBrowseTreeItem** pChild = m_pList;

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

	return nCount;
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeItem paint

void CBrowseTreeItem::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;
	
	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;
}

/////////////////////////////////////////////////////////////////////////////
// CBrowseTreeItem add XML

void CBrowseTreeItem::AddXML(CXMLElement* pXML)
{
	CString strURI = pXML->GetAttributeValue( CXMLAttribute::schemaName );
	
	if ( m_pSchema = SchemaCache.Get( strURI ) )
	{
		m_bBold		= strURI == CSchema::uriFavouritesFolder;
		m_nIcon16	= m_pSchema->m_nIcon16;
		
		if ( CXMLElement* pBody = pXML->GetFirstElement() )
		{
			m_sText = pBody->GetAttributeValue( m_pSchema->GetFirstMemberName() );
		}
	}
	
	if ( m_sText.IsEmpty() ) m_sText = _T("Unnamed");
	
	if ( pXML != NULL ) delete pXML;
}

⌨️ 快捷键说明

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