www.pudn.com > mu_explorer.rar > CJToolBarBase.cpp


// CJToolBarBase.cpp : implementation file 
// Copyright © 1998-1999 CodeJock.com, All Rights Reserved. 
// See ReadMe.txt for TERMS OF USE. 
// 
// Copied from MFC, Visual C++ 6, to extend functionality to Visual C++ 5  
// users, with some ideas taken from Luis Barreira's article 'Classes for new IE4 controls' 
// http://www.codeguru.com/controls/ie4_controls_classes.shtml 
// 
///////////////////////////////////////////////////////////////////////////// 
/**************************************************************************** 
 * 
 * $Date: 8/31/99 1:11a $ 
 * $Revision: 5 $ 
 * $Archive: /CodeJockey/CJLibrary/CJToolBarBase.cpp $ 
 * 
 * $History: CJToolBarBase.cpp $ 
 *  
 * *****************  Version 5  ***************** 
 * User: Kirk Stowell Date: 8/31/99    Time: 1:11a 
 * Updated in $/CodeJockey/CJLibrary 
 * Updated copyright and contact information. 
 *  
 * *****************  Version 4  ***************** 
 * User: Kirk Stowell Date: 7/28/99    Time: 12:38a 
 * Updated in $/CodeJockey/CJLibrary 
 * Final pass for release 6.08. 
 *  
 * *****************  Version 3  ***************** 
 * User: Kirk Stowell Date: 7/25/99    Time: 12:30a 
 * Updated in $/CodeJockey/CJLibrary 
 *  
 * *****************  Version 2  ***************** 
 * User: Kirk Stowell Date: 6/23/99    Time: 12:33a 
 * Updated in $/CodeJockey/CJLibrary 
 *  
 * *****************  Version 1  ***************** 
 * User: Kirk Stowell Date: 7/14/99    Time: 10:29p 
 * Created in $/CodeJockey/CJLibrary 
 * Copied from MFC v6 and techno preview for v5. Added to extend 
 * functionality to Visual C++ 5.0 users. 
 * 
 ***************************************************************************/ 
 
#include "stdafx.h" 
#include "CJToolBarBase.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CCJToolBarBase 
 
CCJToolBarBase::CCJToolBarBase() 
{ 
	m_bInReBar = false; 
	m_bExStyle = false; 
} 
 
CCJToolBarBase::~CCJToolBarBase() 
{ 
 
} 
 
BEGIN_MESSAGE_MAP(CCJToolBarBase, CControlBar) 
	//{{AFX_MSG_MAP(CCJToolBarBase) 
	ON_WM_PAINT() 
	ON_WM_WINDOWPOSCHANGING() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
void CCJToolBarBase::SetBorders(int cxLeft, int cyTop, int cxRight, int cyBottom) 
{ 
	ASSERT(cxLeft >= 0); 
	ASSERT(cyTop >= 0); 
	ASSERT(cxRight >= 0); 
	ASSERT(cyBottom >= 0); 
 
	m_cxLeftBorder = cxLeft; 
	m_cyTopBorder = cyTop; 
	m_cxRightBorder = cxRight; 
	m_cyBottomBorder = cyBottom; 
} 
 
LRESULT CCJToolBarBase::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam) 
{ 
	ASSERT_VALID(this); 
 
	LRESULT lResult; 
	switch (nMsg) 
	{ 
	case WM_NOTIFY: 
	case WM_COMMAND: 
	case WM_DRAWITEM: 
	case WM_MEASUREITEM: 
	case WM_DELETEITEM: 
	case WM_COMPAREITEM: 
	case WM_VKEYTOITEM: 
	case WM_CHARTOITEM: 
		// send these messages to the owner if not handled 
		if (OnWndMsg(nMsg, wParam, lParam, &lResult)) 
			return lResult; 
		else 
		{ 
			// try owner next 
			lResult = GetOwner()->SendMessage(nMsg, wParam, lParam); 
 
			// special case for TTN_NEEDTEXTA and TTN_NEEDTEXTW 
			if(nMsg == WM_NOTIFY) 
			{ 
				NMHDR* pNMHDR = (NMHDR*)lParam; 
				if (pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW) 
				{ 
					TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; 
					TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; 
					if ((pNMHDR->code == TTN_NEEDTEXTA && (!pTTTA->lpszText || !*pTTTA->lpszText)) || 
						(pNMHDR->code == TTN_NEEDTEXTW && (!pTTTW->lpszText || !*pTTTW->lpszText))) 
					{ 
						// not handled by owner, so let bar itself handle it 
						lResult = CWnd::WindowProc(nMsg, wParam, lParam); 
					} 
				} 
			} 
			return lResult; 
		} 
	} 
 
	// otherwise, just handle in default way 
	lResult = CWnd::WindowProc(nMsg, wParam, lParam); 
	return lResult; 
} 
 
void CCJToolBarBase::OnWindowPosChanging(LPWINDOWPOS lpWndPos) 
{ 
	// WINBUG: We call DefWindowProc here instead of CWnd::OnWindowPosChanging 
	//  (which calls CWnd::Default, which calls through the super wndproc) 
	//  because certain control bars that are system implemented (such as 
	//  CToolBar with TBSTYLE_FLAT) do not implement WM_WINDOWPOSCHANGING 
	//  correctly, causing repaint problems.  This code bypasses that whole 
	//  mess. 
	::DefWindowProc(m_hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)lpWndPos); 
 
	if (lpWndPos->flags & SWP_NOSIZE) 
		return; 
 
	// invalidate borders on the right 
	CRect rect; 
	GetWindowRect(&rect); 
	CSize sizePrev = rect.Size(); 
	int cx = lpWndPos->cx; 
	int cy = lpWndPos->cy; 
	if (cx != sizePrev.cx && (m_dwStyle & CBRS_BORDER_RIGHT)) 
	{ 
		rect.SetRect(cx-afxData.cxBorder2, 0, cx, cy); 
		InvalidateRect(&rect); 
		rect.SetRect(sizePrev.cx-afxData.cxBorder2, 0, sizePrev.cx, cy); 
		InvalidateRect(&rect); 
	} 
 
	// invalidate borders on the bottom 
	if (cy != sizePrev.cy && (m_dwStyle & CBRS_BORDER_BOTTOM)) 
	{ 
		rect.SetRect(0, cy-afxData.cyBorder2, cx, cy); 
		InvalidateRect(&rect); 
		rect.SetRect(0, sizePrev.cy-afxData.cyBorder2, cx, sizePrev.cy); 
		InvalidateRect(&rect); 
	} 
} 
 
void CCJToolBarBase::OnPaint() 
{ 
	// background is already filled in gray 
	CPaintDC dc(this); 
 
	// erase background now 
	if (IsVisible()) 
		DoPaint(&dc);       // delegate to paint helper 
} 
 
void CCJToolBarBase::EraseNonClient() 
{ 
	// get window DC that is clipped to the non-client area 
	CWindowDC dc(this); 
	CRect rectClient; 
	GetClientRect(rectClient); 
	CRect rectWindow; 
	GetWindowRect(rectWindow); 
	ScreenToClient(rectWindow); 
	rectClient.OffsetRect(-rectWindow.left, -rectWindow.top); 
	dc.ExcludeClipRect(rectClient); 
 
	// draw borders in non-client area 
	rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top); 
	DrawBorders(&dc, rectWindow); 
 
	// erase parts not drawn 
	dc.IntersectClipRect(rectWindow); 
	SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC); 
 
	// draw gripper in non-client area 
	DrawGripper(&dc, rectWindow); 
} 
 
void CCJToolBarBase::DoPaint(CDC* pDC) 
{ 
	ASSERT_VALID(this); 
	ASSERT_VALID(pDC); 
 
	// paint inside client area 
	CRect rect; 
	GetClientRect(rect); 
	DrawBorders(pDC, rect); 
	DrawGripper(pDC, rect); 
} 
 
void CCJToolBarBase::DrawBorders(CDC* pDC, CRect& rect) 
{ 
	ASSERT_VALID(this); 
	ASSERT_VALID(pDC); 
 
	DWORD dwStyle = m_dwStyle; 
	if (!(dwStyle & CBRS_BORDER_ANY)) 
		return; 
 
	// prepare for dark lines 
	ASSERT(rect.top == 0 && rect.left == 0); 
	if(m_bInReBar) 
	{ 
		CRect rect1, rect2; 
		rect1 = rect; 
		rect2 = rect; 
		COLORREF clr = afxData.bWin4 ? afxData.clrBtnShadow : afxData.clrWindowFrame; 
		 
		// draw dark line one pixel back/up 
		if (dwStyle & CBRS_BORDER_3D) 
		{ 
			rect1.right -= CX_BORDER; 
			rect1.bottom -= CY_BORDER; 
		} 
		if (dwStyle & CBRS_BORDER_TOP) 
			rect2.top += afxData.cyBorder2; 
		if (dwStyle & CBRS_BORDER_BOTTOM) 
			rect2.bottom -= afxData.cyBorder2; 
		 
		// draw left and top 
		if (dwStyle & CBRS_BORDER_LEFT) 
			pDC->FillSolidRect(0, rect2.top, CX_BORDER, rect2.Height(), clr); 
		if (dwStyle & CBRS_BORDER_TOP) 
			pDC->FillSolidRect(0, 0, rect.right, CY_BORDER, clr); 
		 
		// draw right and bottom 
		if (dwStyle & CBRS_BORDER_RIGHT) 
			pDC->FillSolidRect(rect1.right, rect2.top, -CX_BORDER, rect2.Height(), clr); 
		if (dwStyle & CBRS_BORDER_BOTTOM) 
			pDC->FillSolidRect(0, rect1.bottom, rect.right, -CY_BORDER, clr); 
		 
		if (dwStyle & CBRS_BORDER_3D) 
		{ 
			// prepare for hilite lines 
			clr = afxData.clrBtnHilite; 
			 
			// draw left and top 
			if (dwStyle & CBRS_BORDER_LEFT) 
				pDC->FillSolidRect(1, rect2.top, CX_BORDER, rect2.Height(), clr); 
			if (dwStyle & CBRS_BORDER_TOP) 
				pDC->FillSolidRect(0, 1, rect.right, CY_BORDER, clr); 
			 
			// draw right and bottom 
			if (dwStyle & CBRS_BORDER_RIGHT) 
				pDC->FillSolidRect(rect.right, rect2.top, -CX_BORDER, rect2.Height(), clr); 
			if (dwStyle & CBRS_BORDER_BOTTOM) 
				pDC->FillSolidRect(0, rect.bottom, rect.right, -CY_BORDER, clr); 
		} 
		 
		if (dwStyle & CBRS_BORDER_LEFT) 
			rect.left += afxData.cxBorder2; 
		if (dwStyle & CBRS_BORDER_TOP) 
			rect.top += afxData.cyBorder2; 
		if (dwStyle & CBRS_BORDER_RIGHT) 
			rect.right -= afxData.cxBorder2; 
		if (dwStyle & CBRS_BORDER_BOTTOM) 
			rect.bottom -= afxData.cyBorder2; 
	} 
	else 
	{ 
		if(dwStyle & CBRS_BORDER_RIGHT) { 
			pDC->FillSolidRect(rect.right-1, 0, rect.right, rect.bottom, afxData.clrBtnShadow); 
			rect.right--; 
		} 
		if(dwStyle & CBRS_BORDER_BOTTOM) { 
			pDC->FillSolidRect(0, rect.bottom-1, rect.right, rect.bottom, afxData.clrBtnShadow); 
			rect.bottom--; 
		} 
		if(dwStyle & CBRS_BORDER_TOP) { 
			pDC->FillSolidRect(0, 0, rect.right, 1, afxData.clrBtnHilite); 
			rect.top++; 
		} 
		if(dwStyle & CBRS_BORDER_LEFT) { 
			pDC->FillSolidRect(0, 0, 1, rect.bottom, afxData.clrBtnHilite); 
			rect.left++; 
		} 
	} 
} 
 
#define CX_GRIPPER			3 
#define CY_GRIPPER			3 
#define CX_BORDER_GRIPPER	2 
#define CY_BORDER_GRIPPER	2 
 
void CCJToolBarBase::DrawGripper(CDC* pDC, const CRect& rect) 
{ 
	// if we are floating return. 
	if( m_dwStyle & CBRS_FLOATING ) { 
		return; 
	} 
 
	// if we are to draw the extended "office" style gripper. 
	if(( m_dwStyle & CBRS_GRIPPER ) && ( m_bExStyle == true )) 
	{ 
		// draw the gripper in the border 
		if (m_dwStyle & CBRS_ORIENT_HORZ) 
		{ 
			// Draw the first gripper. 
			pDC->Draw3dRect( rect.left+3, rect.top+2, 3, rect.Height()-4, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
			 
			pDC->SetPixel( rect.left+3, rect.top+2+rect.Height()-5, 
				afxData.clrBtnHilite); 
 
			// Draw the second gripper. 
			pDC->Draw3dRect( rect.left+6, rect.top+2, 3, rect.Height()-4, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
			 
			pDC->SetPixel( rect.left+6, rect.top+2+rect.Height()-5, 
				afxData.clrBtnHilite); 
		} 
		else 
		{ 
			// Draw the first gripper. 
			pDC->Draw3dRect( rect.left+2, rect.top+3, rect.Width()-4, 3, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
 
			pDC->SetPixel( rect.left+2+rect.Width()-5, rect.top+3, 
				afxData.clrBtnHilite); 
			 
			// Draw the second gripper. 
			pDC->Draw3dRect( rect.left+2, rect.top+6, rect.Width()-4, 3, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
			 
			pDC->SetPixel( rect.left+2+rect.Width()-5, rect.top+6, 
				afxData.clrBtnHilite); 
		} 
 
		GdiFlush(); 
	} 
 
	// if we are to draw the "ReBar" style gripper. 
	else 
	if(( m_dwStyle & CBRS_GRIPPER ) && ( m_bInReBar == true )) 
	{ 
		// draw the gripper in the border 
		if (m_dwStyle & CBRS_ORIENT_HORZ) 
		{ 
			// Draw the first gripper. 
			pDC->Draw3dRect( rect.left+CX_BORDER_GRIPPER, rect.top+m_cyTopBorder, 
				CX_GRIPPER, rect.Height()-m_cyTopBorder-m_cyBottomBorder, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
		} 
		else 
		{ 
			// Draw the first gripper. 
			pDC->Draw3dRect( rect.left+m_cyTopBorder, rect.top+CY_BORDER_GRIPPER, 
				rect.Width()-m_cyTopBorder-m_cyBottomBorder, CY_GRIPPER, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
		} 
 
		GdiFlush(); 
	} 
 
	// by default, we will draw the "visual studio" style gripper. 
	else 
	if( m_dwStyle & CBRS_GRIPPER ) 
	{ 
		// draw the gripper in the border 
		if (m_dwStyle & CBRS_ORIENT_HORZ) 
		{ 
			// Draw the first gripper. 
			pDC->Draw3dRect( rect.left+1, rect.top+2, 3, rect.Height()-4, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
 
			// Draw the second gripper. 
			pDC->Draw3dRect( rect.left+5, rect.top+2, 3, rect.Height()-4, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
		} 
		else 
		{ 
			// Draw the first gripper. 
			pDC->Draw3dRect( rect.left+2, rect.top+1, rect.Width()-4, 3, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
			 
			// Draw the second gripper. 
			pDC->Draw3dRect( rect.left+2, rect.top+5, rect.Width()-4, 3, 
				afxData.clrBtnHilite, afxData.clrBtnShadow); 
		} 
 
		GdiFlush(); 
	} 
} 
 
// input CRect should be client rectangle size 
void CCJToolBarBase::CalcInsideRect(CRect& rect, BOOL bHorz) const 
{ 
	ASSERT_VALID(this); 
	DWORD dwStyle = m_dwStyle; 
	 
	if (dwStyle & CBRS_BORDER_LEFT) 
		rect.left += afxData.cxBorder2; 
	if (dwStyle & CBRS_BORDER_TOP) 
		rect.top += afxData.cyBorder2; 
	if (dwStyle & CBRS_BORDER_RIGHT) 
		rect.right -= afxData.cxBorder2; 
	if (dwStyle & CBRS_BORDER_BOTTOM) 
		rect.bottom -= afxData.cyBorder2; 
	 
	// inset the top and bottom. 
	if (bHorz) 
	{ 
		rect.left += m_cxLeftBorder; 
		rect.top += m_cyTopBorder; 
		rect.right -= m_cxRightBorder; 
		rect.bottom -= m_cyBottomBorder; 
		if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER) 
		{ 
			rect.left += CX_BORDER_GRIPPER+CX_GRIPPER+CX_BORDER_GRIPPER; 
		 
			if( m_bExStyle == true ) { 
				rect.left += CX_GRIPPER; 
			} 
 
			if(( m_bExStyle == false ) && ( m_bInReBar == false )) { 
				rect.left -= CX_BORDER_GRIPPER+CX_GRIPPER; 
			} 
		} 
	} 
	else 
	{ 
		rect.left += m_cyTopBorder; 
		rect.top += m_cxLeftBorder; 
		rect.right -= m_cyBottomBorder; 
		rect.bottom -= m_cxRightBorder; 
		if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER) 
		{ 
			rect.top += CY_BORDER_GRIPPER+CY_GRIPPER+CY_BORDER_GRIPPER; 
		 
			if( m_bExStyle == true ) { 
				rect.top += CY_GRIPPER; 
			} 
 
			if(( m_bExStyle == false ) && ( m_bInReBar == false )) { 
				rect.top -= CY_BORDER_GRIPPER+CY_GRIPPER; 
			} 
		} 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
 
IMPLEMENT_DYNAMIC(CCJToolBarBase, CControlBar) 
 
/////////////////////////////////////////////////////////////////////////////