www.pudn.com > 200308141526117224仿MSN(网易泡泡)界面.rar > IMTree.cpp


// IMTree.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "CNIcq.h" 
#include "IMTree.h" 
 
#pragma warning(push) 
#pragma warning(disable: 4201) 
#include  
#pragma warning(pop) 
 
#pragma comment(lib, "winmm.lib") 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CIMTree 
 
CIMTree::CIMTree() 
{ 
	BgColor = RGB(255, 255, 255); 
	FontColor = RGB(0, 0, 0); 
	m_bBgStretch = FALSE; 
} 
 
CIMTree::~CIMTree() 
{ 
	if( m_bitmap.m_hObject != NULL ) 
		m_bitmap.DeleteObject(); 
	if( m_pal.m_hObject != NULL ) 
		m_pal.DeleteObject(); 
} 
 
 
BEGIN_MESSAGE_MAP(CIMTree, CTreeCtrl) 
	//{{AFX_MSG_MAP(CIMTree) 
	ON_WM_PAINT() 
	ON_WM_VSCROLL() 
	ON_WM_HSCROLL() 
	ON_WM_ERASEBKGND() 
	ON_WM_QUERYNEWPALETTE() 
	ON_WM_PALETTECHANGED() 
	ON_WM_SIZE() 
	ON_WM_DRAWITEM() 
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CIMTree message handlers 
BOOL CIMTree::SetBkImage(HBITMAP hBmp) 
{ 
	if( m_bitmap.m_hObject != NULL ) 
		m_bitmap.DeleteObject(); 
	if( m_pal.m_hObject != NULL ) 
		m_pal.DeleteObject(); 
 
	if( hBmp == NULL )  
		return FALSE; 
 
	m_bitmap.Attach( hBmp ); 
	BITMAP bm; 
	m_bitmap.GetBitmap( &bm ); 
	m_cxBitmap = bm.bmWidth; 
	m_cyBitmap = bm.bmHeight; 
 
 
	// Create a logical palette for the bitmap 
	DIBSECTION ds; 
	BITMAPINFOHEADER &bmInfo = ds.dsBmih; 
	m_bitmap.GetObject( sizeof(ds), &ds ); 
 
	int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount; 
 
	// Create a halftone palette if colors > 256.  
	CClientDC dc(NULL);			// Desktop DC 
	if( nColors > 256 ) 
		m_pal.CreateHalftonePalette( &dc ); 
	else 
	{ 
		// Create the palette 
 
		RGBQUAD *pRGB = new RGBQUAD[nColors]; 
		CDC memDC; 
		memDC.CreateCompatibleDC(&dc); 
 
		memDC.SelectObject( &m_bitmap ); 
		::GetDIBColorTable( memDC, 0, nColors, pRGB ); 
 
		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors); 
		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; 
 
		pLP->palVersion = 0x300; 
		pLP->palNumEntries = nColors; 
 
		for( int i=0; i < nColors; i++) 
		{ 
			pLP->palPalEntry[i].peRed = pRGB[i].rgbRed; 
			pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen; 
			pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue; 
			pLP->palPalEntry[i].peFlags = 0; 
		} 
 
		m_pal.CreatePalette( pLP ); 
 
		delete[] pLP; 
		delete[] pRGB; 
	} 
	Invalidate(); 
 
	return TRUE; 
} 
 
BOOL CIMTree::SetBkImage(UINT nIDResource) 
{ 
	return SetBkImage( (LPCTSTR)nIDResource ); 
} 
 
BOOL CIMTree::SetBkImage(LPCTSTR lpszResourceName) 
{ 
	HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),  
			lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION ); 
	 
	return SetBkImage(hBmp); 
} 
 
 
void CIMTree::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
 
	CRect rcClip, rcClient; 
	dc.GetClipBox( &rcClip ); 
	GetClientRect(&rcClient); 
 
	// Create a compatible memory DC  
	CDC memDC; 
	memDC.CreateCompatibleDC( &dc ); 
	 
	// Select a compatible bitmap into the memory DC 
	CBitmap bitmap, bmpImage; 
	bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() ); 
	CBitmap *OldBitmap = memDC.SelectObject( &bitmap ); 
 
	// First let the control do its default drawing. 
	CTreeCtrl::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); 
 
 
/* 
	// create the font 
	CFont *pFontDC; 
	CFont fontDC, boldFontDC; 
	LOGFONT logfont; 
 
	CFont *pFont = GetFont(); 
	pFont->GetLogFont( &logfont ); 
 
	fontDC.CreateFontIndirect( &logfont );		//普通字体 
	pFontDC = memDC.SelectObject( &fontDC ); 
 
	logfont.lfWeight = 700; 
	boldFontDC.CreateFontIndirect( &logfont );	//粗体字 
 
	// and now let's get to the painting itself 
	HTREEITEM hItem = GetFirstVisibleItem(); 
 
	int n = GetVisibleCount(); 
 
	hItem = GetFirstVisibleItem(); 
	n = GetVisibleCount(); 
 
	while(hItem!=NULL && n>=0) 
	{ 
		CRect rect; 
		CRect m_labelRect; 
 
		UINT selflag = TVIS_SELECTED ; // |TVIS_DROPHILITED; 
	 
		CString ItemText = GetItemText(hItem); 
 
		GetItemRect( hItem, &m_labelRect, TRUE );	//文字 
		GetItemRect( hItem, &rect, FALSE ); 
 
		if ( !(GetItemState( hItem, selflag ) & selflag )) //选中状态 
		{ 
			memDC.SetBkMode(TRANSPARENT); 
 
			memDC.SetTextColor(::GetSysColor (COLOR_WINDOWTEXT )); 
 
			DrawItemText(&memDC,ItemText,m_labelRect,LVCFMT_LEFT); 
		} 
		else 
		{ 
			COLORREF m_highlightColor = ::GetSysColor (COLOR_HIGHLIGHT); 
 
			CBrush brush(m_highlightColor); 
 
			memDC.FillRect (m_labelRect, &brush); 
			// draw a dotted focus rectangle 
			memDC.DrawFocusRect (m_labelRect); 
 
			memDC.SetBkColor(m_highlightColor); 
 
			memDC.SetTextColor(::GetSysColor (COLOR_HIGHLIGHTTEXT)); 
 
			memDC.SelectObject( &boldFontDC ); 
 
			DrawItemText(&memDC,ItemText,m_labelRect,LVCFMT_LEFT); 
 
			memDC.SelectObject( &pFontDC ); 
		} 
 
		hItem = GetNextVisibleItem( hItem ); 
		n--; 
	} 
 
	memDC.SelectObject( pFontDC ); 
 
*/ 
 
	// Draw bitmap in the background if one has been set 
	if( m_bitmap.m_hObject != NULL ) 
	{ 
		// Now create a mask 
		CDC maskDC; 
		maskDC.CreateCompatibleDC(&dc); 
		CBitmap maskBitmap; 
 
		// Create monochrome bitmap for the mask 
		maskBitmap.CreateBitmap( rcClient.Width(), rcClient.Height(),  
					1, 1, NULL ); 
 
		CBitmap *OldMask = maskDC.SelectObject( &maskBitmap ); 
		memDC.SetBkColor( ::GetSysColor( COLOR_WINDOW ) ); 
 
		// Create the mask from the memory DC 
		maskDC.BitBlt( 0, 0,  
			rcClient.Width(), rcClient.Height(),  
			&memDC,  
			rcClient.left, rcClient.top,  
			SRCCOPY ); 
 
		 
		CDC tempDC; 
		tempDC.CreateCompatibleDC(&dc); 
		CBitmap *Oldtemp = tempDC.SelectObject( &m_bitmap ); 
 
		CDC imageDC; 
		CBitmap bmpImage; 
		imageDC.CreateCompatibleDC( &dc ); 
 
		bmpImage.CreateCompatibleBitmap( &dc, rcClient.Width(),  
						rcClient.Height() ); 
		CBitmap *OldImage = imageDC.SelectObject( &bmpImage ); 
 
		if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL ) 
		{ 
			dc.SelectPalette( &m_pal, FALSE ); 
			dc.RealizePalette(); 
 
			imageDC.SelectPalette( &m_pal, FALSE ); 
		} 
 
		// Get x and y offset 
		CRect rcRoot; 
		GetItemRect( GetRootItem(), rcRoot, FALSE ); 
		rcRoot.left = -GetScrollPos( SB_HORZ ); 
 
		imageDC.FillSolidRect(CRect(0,0,rcClient.right,rcClient.bottom),BgColor); 
 
		if( m_bBgStretch ) 
		{ 
			imageDC.SetStretchBltMode(COLORONCOLOR); 
			imageDC.StretchBlt( 
				0,0,rcClient.right,rcClient.bottom, 
				&tempDC, 
				0,0,m_cxBitmap,m_cyBitmap, 
				SRCCOPY 
			); 
		} 
		else 
		{	 
			imageDC.BitBlt(  
				rcClient.right-m_cxBitmap,rcClient.bottom-m_cyBitmap, 
				m_cxBitmap,m_cyBitmap, 
				&tempDC, 
				0, 0,  
				SRCCOPY ); 
			/* 
			// Draw bitmap in tiled manner to imageDC 
			for( int i = rcRoot.left; i < rcClient.right; i += m_cxBitmap ) 
			for( int j = rcRoot.top; j < rcClient.bottom; j += m_cyBitmap ) 
			{ 
				imageDC.BitBlt( i, j, m_cxBitmap, m_cyBitmap,  
					&tempDC,0, 0, SRCCOPY ); 
			} 
			*/ 
		} 
		 
		// Set the background in memDC to black. Using SRCPAINT with black and any other 
		// color results in the other color, thus making black the transparent color 
		memDC.SetBkColor(RGB(0,0,0));         
		memDC.SetTextColor(RGB(255,255,255)); 
 
		memDC.BitBlt(	rcClip.left, rcClip.top,  
				rcClip.Width(), rcClip.Height(),  
				&maskDC,  
				rcClip.left, rcClip.top,  
				SRCAND); 
 
		// Set the foreground to black. See comment above. 
		imageDC.SetBkColor(RGB(255,255,255)); 
		imageDC.SetTextColor(RGB(0,0,0)); 
 
		imageDC.BitBlt(	rcClip.left, rcClip.top,  
				rcClip.Width(), rcClip.Height(),  
				&maskDC,  
				rcClip.left, rcClip.top,  
				SRCAND); 
 
		// Combine the foreground with the background 
		imageDC.BitBlt(	rcClip.left, rcClip.top,  
				rcClip.Width(), rcClip.Height(),  
				&memDC,  
				rcClip.left, rcClip.top, 
				SRCPAINT); 
		 
		// Draw the final image to the screen		 
		dc.BitBlt(	rcClip.left, rcClip.top,  
				rcClip.Width(), rcClip.Height(),  
				&imageDC,  
				rcClip.left, rcClip.top, SRCCOPY ); 
 
		//释放对象 
		maskDC.SelectObject(OldMask); 
		imageDC.SelectObject(OldImage); 
		tempDC.SelectObject(Oldtemp); 
 
		maskBitmap.DeleteObject(); 
		bmpImage.DeleteObject(); 
 
		maskDC.DeleteDC(); 
		imageDC.DeleteDC(); 
		tempDC.DeleteDC(); 
	} 
	else 
	{ 
		dc.BitBlt(	rcClip.left, rcClip.top,  
				rcClip.Width(),  
				rcClip.Height(),  
				&memDC,  
				rcClip.left, rcClip.top, SRCCOPY ); 
	} 
 
	memDC.SelectObject(OldBitmap); 
	bitmap.DeleteObject(); 
	memDC.DeleteDC(); 
} 
 
void CIMTree::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)  
{ 
	if( m_bitmap.m_hObject != NULL ) 
		InvalidateRect(NULL); 
 
	CTreeCtrl::OnVScroll(nSBCode, nPos, pScrollBar); 
} 
 
void CIMTree::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)  
{ 
	if( m_bitmap.m_hObject != NULL ) 
		InvalidateRect(NULL); 
 
	CTreeCtrl::OnHScroll(nSBCode, nPos, pScrollBar); 
} 
void CIMTree::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; 
 
	if( m_bitmap.m_hObject != NULL ) 
		InvalidateRect(NULL); 
 
	*pResult = 0; 
} 
 
 
 
BOOL CIMTree::OnEraseBkgnd(CDC* pDC)  
{ 
	if( m_bitmap.m_hObject != NULL ) 
		return TRUE; 
 
	return CTreeCtrl::OnEraseBkgnd(pDC); 
} 
 
BOOL CIMTree::OnQueryNewPalette()  
{ 
	CClientDC dc(this); 
 
	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL ) 
	{ 
		dc.SelectPalette( &m_pal, FALSE ); 
		BOOL result = dc.RealizePalette(); 
		if( result ) 
			Invalidate(); 
		return result; 
	} 
	 
	return CTreeCtrl::OnQueryNewPalette(); 
} 
 
void CIMTree::OnPaletteChanged(CWnd* pFocusWnd)  
{ 
	CTreeCtrl::OnPaletteChanged(pFocusWnd); 
	 
	if( pFocusWnd == this ) 
		return; 
 
	CTreeCtrl::OnPaletteChanged(pFocusWnd); 
 
} 
 
void CIMTree::SetBgStretch(BOOL Flag) 
{ 
	m_bBgStretch = Flag; 
} 
 
void CIMTree::OnSize(UINT nType, int cx, int cy)  
{ 
	CTreeCtrl::OnSize(nType, cx, cy); 
	 
	Invalidate(); 
} 
 
 
void CIMTree::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
	CTreeCtrl::OnDrawItem(nIDCtl, lpDrawItemStruct); 
} 
 
void CIMTree::PreSubclassWindow()  
{ 
	CTreeCtrl::PreSubclassWindow(); 
} 
 
void CIMTree::DrawItemText(CDC *pDC, CString text, CRect rect, int nFormat) 
{ 
	UINT nStyle = DT_VCENTER | DT_SINGLELINE; 
	if (nFormat == LVCFMT_LEFT) 
		nStyle |= DT_LEFT; 
	else if (nFormat == LVCFMT_CENTER) 
		nStyle |= DT_CENTER; 
	else // nFormat == LVCFMT_RIGHT 
		nStyle |= DT_RIGHT; 
 
	if((text.GetLength()>0) && (rect.right>rect.left)) 
	{ 
		pDC->DrawText (text, rect, nStyle); 
	} 
}