📄 advtreectrl.cpp
字号:
// ---------------------------------------------------------
//
// ( 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 + -