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

📄 advtreectrl.cpp

📁 我自己整理的一些VC源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//  ---------------------------------------------------------
//
//      ( C )     Copyright C - Channel Eng. AG 1998
//      Use or copying of all or any part of the document,
//      except as permitted by the License Agreement is
//      prohibited.
//
//      Author  : Michael Wild, 5063  C - Channel Eng. AG
//
//      Purpose : 
//      This File contains the class CAdvancedTreeCtrl
// 
//      Creation date: April 28, 1998
//
//  ---------------------------------------------------------

#include "stdafx.h"
#include "SellMan.h"
#include "AdvTreeCtrl.h"

#include "winerror.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAdvancedTreeCtrl

CAdvancedTreeCtrl::CAdvancedTreeCtrl()
    : m_imglDrives()
     ,m_PagingInfos()
{
    m_bContinuePrinting             = FALSE;
    m_lNumberOfItems                = 0;
    m_lPageStart                    = 0;
    m_hPageStartingItem             = NULL;
    m_ActualPage.m_hStartItem       = NULL;
    m_ActualPage.m_iNumberOfItems   = 0;
    m_dwLastError                   = 0;
}

CAdvancedTreeCtrl::~CAdvancedTreeCtrl()
{}

BEGIN_MESSAGE_MAP(CAdvancedTreeCtrl, CTreeCtrl)
    //{{AFX_MSG_MAP(CAdvancedTreeCtrl)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAdvancedTreeCtrl message handlers

void CAdvancedTreeCtrl::InitImageList( CImageList * pImageList )
{
	//	Load Icons an generate a iconlist
	if( pImageList )
	{
		m_imglDrives.Create( pImageList );
	}
	else
	{
		m_imglDrives.Create (IDR_DRIVEIMAGES, 16, 1, RGB (255, 0, 255));
		SetImageList(&m_imglDrives, TVSIL_NORMAL);
	}
}

void CAdvancedTreeCtrl::MakePaging( CDC* pDC, CPrintInfo* pInfo )
{
    // Must be true
    assert( NULL != pInfo );
    assert( NULL != pDC );

    // Remove all Items from the Array first
    m_PagingInfos.RemoveAll();

    // Get first visible Item
    HTREEITEM hItem = GetRootItem();

    // Reset Class-Members
    m_lNumberOfItems    = 0;

    // Set the first Item as the first Pagestarting-item
    m_hPageStartingItem  = hItem;

    // Save the Top of the Pagestarting-item
    CRect  itemRect;
    GetItemRect( hItem, &itemRect, FALSE );
    m_lPageStart = itemRect.top;

    // Do the Paging stuff
    StartPaging( pDC, pInfo, hItem );

    // End and Clean up after Paging 
    EndPaging( pInfo );
}

void CAdvancedTreeCtrl::StartPaging( CDC* pDC, CPrintInfo* pInfo, HTREEITEM hItem )
{
    // Must be true
    assert( NULL != pInfo );
    assert( NULL != pDC );

    // Local variables
    CRect       itemRect;

    // Loop until ItemHandle is NULL == End of the Tree
    while( hItem )
    {
        // Count the Numbers of Items
        ++m_lNumberOfItems;

        // Get Item-Rect
        GetItemRect( hItem, &itemRect, FALSE );

        // Convert coordinates of DrawRectangle 
        CRect pagingRect = pInfo->m_rectDraw;
        pDC->DPtoLP( &pagingRect );

        // Make Rect with paged Area
        CRect pagedRect = itemRect;
        pagedRect.top   = m_lPageStart;

        // Is the Page full
        if( pagingRect.Height() < ( pagedRect.Height() ) )
        {
            // Fill the PageInfos into the Array
            PagingInfos locInfo;
            locInfo.m_hStartItem        = m_hPageStartingItem;
            locInfo.m_iNumberOfItems    = m_lNumberOfItems-1;
            m_PagingInfos.Add( locInfo );

            // Reset the Paging parameters
            m_lNumberOfItems            = 1;
            m_hPageStartingItem         = hItem;
            m_lPageStart                = itemRect.top;
        }
        
        // Get Child Item of actual Item
        HTREEITEM hChildItem = GetChildItem( hItem );

        // Only go to Subtree if visible 
        if( hChildItem == GetNextVisibleItem( hItem )&&( NULL != hChildItem ) )
        {
            StartPaging( pDC, pInfo, hChildItem );
        }

        // Get next Item
        hItem = GetNextItem( hItem, TVGN_NEXT );
    }
}

void CAdvancedTreeCtrl::EndPaging( CPrintInfo* pInfo )
{
    // Locals
    PagingInfos locInfo;

    // Fill up the Infos of the last Page
    locInfo.m_hStartItem        = m_hPageStartingItem;
    locInfo.m_iNumberOfItems    = m_lNumberOfItems;

    // Reset Number
    m_lNumberOfItems            = 0;

    // Add the last Page
    m_PagingInfos.Add( locInfo );

    // Set Pagenumber
    pInfo->SetMaxPage( m_PagingInfos.GetSize() );
}

void CAdvancedTreeCtrl::DrawTreeCtrl( CDC * pDC, CPrintInfo* pInfo )
{
    // Must be true
    assert( NULL != pDC );

    // Local Variables
    CRect rcBounds;
    HTREEITEM hItem = NULL;

    // Don't print Pages without Information in the Paging-Array
    if( pInfo->m_nCurPage <= (UINT)m_PagingInfos.GetSize() )
    {
        // Othervise it won't start printing
        m_bContinuePrinting = TRUE;

        // Get Infos of the actual Page
        m_ActualPage = m_PagingInfos.GetAt( pInfo->m_nCurPage-1 );

        // Set Handle for the actual Page
        hItem = m_ActualPage.m_hStartItem;

        // Offset for the scrolled Part of the Tree. 
        // Othervise it only prints from the first visible Item
        GetItemRect( hItem, &rcBounds, FALSE );
        pDC->OffsetWindowOrg( rcBounds.left, rcBounds.top );

        // Loop until Number of Items is printed
        while( 0 != m_ActualPage.m_iNumberOfItems )
        {
            // Iterate through the Tree
            DrawNodes( pDC, pInfo, hItem );

            // If you were trap on a Childnode, you have to go
            // back to the next Parent and Print further.
            if( 0 != m_ActualPage.m_iNumberOfItems )
            {
                HTREEITEM hNextParentItem = NULL;

                // Get the next valid Parent-Node
                while( NULL == hNextParentItem ) 
                {
                    hItem = GetParentItem( hItem );
                    hNextParentItem = GetNextItem( hItem, TVGN_NEXT );
                }

                // Set Hadle to continue
                hItem = hNextParentItem;
            }
        }

        // If all Pages are printed
        if( pInfo->m_nCurPage == (UINT)m_PagingInfos.GetSize() )
        {
            // Stop printing
            m_bContinuePrinting = FALSE;
        }
    }
    else
    {
        // Should never happen
        assert( pInfo->m_nCurPage <= (UINT)m_PagingInfos.GetSize() );
    }
}

void CAdvancedTreeCtrl::DrawNodes( CDC * pDC, CPrintInfo* pInfo, HTREEITEM actualItem )
{
    // Loop until Handle is NULL
    while( ( NULL != actualItem ) && ( 0 != m_ActualPage.m_iNumberOfItems ) )
    {
        // Must be true
        assert( NULL != actualItem );
        assert( NULL != pDC );
        assert( 0    != m_ActualPage.m_iNumberOfItems );

        // Locals
        CRect       rect;
        CFont       itemFont;
        CFont*      pOldFont;
        LOGFONT     logfont;
        BOOL        bResult;

        // Text Output to DC
            // Use window font
            CFont *pFont = GetFont();
            pFont->GetLogFont( &logfont );

            // Create Font with local Font-Struct
            bResult = itemFont.CreateFontIndirect( &logfont );

            // Could not create the Font
            assert( bResult );

            // Set new Font
            pOldFont = pDC->SelectObject( &itemFont );

            // Must be true
            assert( NULL != pOldFont );

            // Get Item Text
            CString sItem = GetItemText( actualItem );
            
            // Get Item-Rect
            GetItemRect( actualItem, &rect, TRUE );

            // Set Background-Color
            pDC->SetBkColor( GetSysColor( COLOR_WINDOW ) );

            // Write Item-Text to DC
            pDC->TextOut( rect.left+2, rect.top, sItem );
            
            // Set Old Font
            pOldFont = pDC->SelectObject( pOldFont );

            // Must be true
            assert( NULL != pOldFont );

        // Icon Output to DC
        if( 0 == m_dwLastError )
        {
            int     nImage, nSelectedImage;

            // Get Image of the Node
            GetItemImage( actualItem, nImage, nSelectedImage );

            // Is Overlay-Image set???
            if( GetItemState( actualItem, TVIS_OVERLAYMASK ) & TVIS_OVERLAYMASK )
            {
                // If Overlay-Image is set
                HANDLE hDib = ImageToDIB( &m_imglDrives, nImage, FromHandle( m_hWnd ), TRUE, actualItem );

                if( 0 == hDib )
                {
                    // Load String from Resource
                    CString locStr1, locStr2;
                    locStr1.LoadString( IDS_DIB_CONVERT_FAILED );
                    locStr2.Format( locStr1, m_dwLastError );
                    if( 0 == m_dwLastError )
                        m_dwLastError = ERROR_CAN_NOT_COMPLETE; 

                    AfxMessageBox( locStr2 );
                    return;
                }

                // Print DIBs
                if( FALSE == PrintDIB( pDC->m_hDC, hDib, rect.left-16, rect.top ) )
                {
                    AfxMessageBox( IDS_DIB_PRINT_FAILED );
                }

                // Free GlobalMemory
                GlobalFree( hDib );
            }
            else
            {
                // Print DIBs
                if( FALSE == PrintDIB( pDC->m_hDC, m_dibArray[nImage], rect.left-16, rect.top ) )
                {
                    AfxMessageBox( IDS_DIB_PRINT_FAILED );
                }
            }

            // Line Output to DC
            DrawTreeLines( pDC, actualItem, rect ); 

            // Buttons Output to DC
            DrawTreeButtons( pDC, actualItem, rect ); 
        }

        // Decrement the number of Items still to Print
        --m_ActualPage.m_iNumberOfItems;

        HTREEITEM hChildItem = NULL;

        // If all Items are printed, the stop
        if( 0 == m_ActualPage.m_iNumberOfItems )
        {
            break;
        }
        else
        {
            // Get Child Item of actual Item
            hChildItem = GetChildItem( actualItem );

            // Only go to Subtree if visible 
            if( hChildItem == GetNextVisibleItem( actualItem ) )
            {
                // Iterate to Subtree
                DrawNodes( pDC, pInfo, hChildItem );
            }

            // Get next Item
            actualItem = GetNextItem( actualItem, TVGN_NEXT );
        }
    }
}

HANDLE CAdvancedTreeCtrl::DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal ) 
{
    // Local Variables
    BITMAP                  bm;
    BITMAPINFOHEADER        bi;
    LPBITMAPINFOHEADER      lpbi;
    DWORD                   dwLen;
    HANDLE                  hDIB;
    HDC                     hDC;
    HPALETTE                hPal;

    // Always a safe Handle
    ASSERT( bitmap.GetSafeHandle() );

    // The function has no arg for bitfields
    if( BI_BITFIELDS == dwCompression )
        return NULL;

    // If a palette has not been supplied use defaul palette
    hPal = (HPALETTE)pPal->GetSafeHandle();
    if( NULL == hPal )
    {
        hPal = (HPALETTE)GetStockObject( DEFAULT_PALETTE );
    }

    // If fails no resource available
    ASSERT( NULL != hPal );

    // Get bitmap information
    bitmap.GetObject( sizeof(bm), (LPSTR)&bm );

    // Initialize the bitmapinfoheader
    bi.biSize               = sizeof(BITMAPINFOHEADER);
    bi.biWidth              = bm.bmWidth;
    bi.biHeight             = bm.bmHeight;
    bi.biPlanes             = 1;
    bi.biBitCount           = (unsigned short)( bm.bmPlanes * bm.bmBitsPixel );
    bi.biCompression        = dwCompression;
    bi.biSizeImage          = 0;
    bi.biXPelsPerMeter      = 0;
    bi.biYPelsPerMeter      = 0;
    bi.biClrUsed            = 0;
    bi.biClrImportant       = 0;

    // Compute the size of the  infoheader and the color table
    int nColors = ( 1 << bi.biBitCount );
    if( 256 < nColors )
    {
        nColors = 0;
    }

    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);

    // We need a device context to get the DIB from
    hDC = ::GetDC( NULL );
    hPal = SelectPalette( hDC, hPal, FALSE );
    RealizePalette( hDC );

    // If fails no resource available
    ASSERT( NULL != hPal );
    ASSERT( NULL != hDC );

    // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc( GMEM_FIXED, dwLen );

    // Memory allocation failed
    if( NULL == hDIB )
    {
        // Get the ErrorCode
        m_dwLastError = GetLastError();

        SelectPalette( hDC, hPal, FALSE );
        ::ReleaseDC( NULL, hDC );
        return NULL;
    }

    lpbi = (LPBITMAPINFOHEADER)hDIB;
    *lpbi = bi;

⌨️ 快捷键说明

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