www.pudn.com > ÍøÂç¶Ë¿Ú¼àÊÓ.rar > BCGPButton.cpp


//******************************************************************************* 
// COPYRIGHT NOTES 
// --------------- 
// This is a part of the BCGControlBar Library 
// Copyright (C) 1998-2000 BCGSoft Ltd. 
// All rights reserved. 
// 
// This source code can be used, distributed or modified 
// only under terms and conditions  
// of the accompanying license agreement. 
//******************************************************************************* 
 
// BCGPButton.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "BCGCBPro.h" 
#include "BCGPLocalResource.h" 
#include "bcgprores.h" 
#include "BCGPButton.h" 
#include "BCGGlobals.h" 
#include "BCGPToolBarImages.h" 
#include "BCGPPopupMenu.h" 
#include "BCGPWinXPVisualManager.h" 
#include "BCGPVisualManager2003.h" 
#include "BCGPDrawManager.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
static const int nImageHorzMargin = 10; 
static const int nVertMargin = 5; 
static const COLORREF clrDefault = (COLORREF) -1; 
static const UINT IdAutoCommand = 1; 
 
BOOL CBCGPButton::m_bWinXPTheme = FALSE; 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPButton 
 
IMPLEMENT_DYNCREATE(CBCGPButton, CButton) 
 
CBCGPButton::CBCGPButton() 
{ 
	m_bPushed			= FALSE; 
	m_bClickiedInside	= FALSE; 
	m_bHighlighted		= FALSE; 
	m_bCaptured			= FALSE; 
	m_nFlatStyle		= BUTTONSTYLE_3D; 
	m_nAlignStyle		= ALIGN_CENTER; 
	m_sizeImage			= CSize (0, 0); 
	m_nStdImageId		= (CMenuImages::IMAGES_IDS) -1; 
	m_nStdImageDisabledId = (CMenuImages::IMAGES_IDS) -1; 
	m_StdImageState		= CMenuImages::ImageBlack; 
	m_bFullTextTooltip	= FALSE; 
	m_bRighImage		= FALSE; 
	m_hCursor			= NULL; 
	m_sizePushOffset	= CSize (2, 2); 
	m_bHover			= FALSE; 
	m_clrRegular		= clrDefault; 
	m_clrHover			= clrDefault; 
	m_clrFace			= (COLORREF)-1; 
	m_bDrawFocus		= TRUE; 
	m_bTransparent		= FALSE; 
	m_hFont				= NULL; 
	m_bDelayFullTextTooltipSet = FALSE; 
	m_bGrayDisabled		= TRUE; 
	m_bChecked			= FALSE; 
	m_bCheckButton		= FALSE; 
	m_bRadioButton		= FALSE; 
	m_bAutoCheck		= FALSE; 
	m_bHighlightChecked	= TRUE; 
	m_nAutoRepeatTimeDelay = 0; 
	m_bResponseOnButtonDown = FALSE; 
} 
//**************************************************************************** 
CBCGPButton::~CBCGPButton() 
{ 
	CleanUp (); 
} 
//**************************************************************************** 
void CBCGPButton::CleanUp () 
{ 
	m_nStdImageId = (CMenuImages::IMAGES_IDS) -1; 
	m_nStdImageDisabledId = (CMenuImages::IMAGES_IDS) -1; 
 
	m_sizeImage = CSize (0, 0); 
 
	m_Image.DeleteImageList (); 
	m_ImageHot.DeleteImageList (); 
	m_ImageDisabled.DeleteImageList (); 
 
	m_ImageChecked.DeleteImageList (); 
	m_ImageCheckedHot.DeleteImageList (); 
	m_ImageCheckedDisabled.DeleteImageList (); 
} 
 
 
BEGIN_MESSAGE_MAP(CBCGPButton, CButton) 
	//{{AFX_MSG_MAP(CBCGPButton) 
	ON_WM_ERASEBKGND() 
	ON_WM_CANCELMODE() 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_WM_SETCURSOR() 
	ON_WM_ENABLE() 
	ON_WM_SIZE() 
	ON_WM_KILLFOCUS() 
	ON_WM_LBUTTONDBLCLK() 
	ON_WM_TIMER() 
	//}}AFX_MSG_MAP 
	ON_MESSAGE(WM_SETFONT, OnSetFont) 
	ON_MESSAGE(WM_GETFONT, OnGetFont) 
	ON_MESSAGE(BM_GETCHECK, OnGetCheck) 
	ON_MESSAGE(BM_SETCHECK, OnSetCheck) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPButton message handlers 
 
void CBCGPButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)  
{ 
	ASSERT (lpDIS != NULL); 
	ASSERT (lpDIS->CtlType == ODT_BUTTON); 
 
	CDC* pDC = CDC::FromHandle (lpDIS->hDC); 
	ASSERT_VALID (pDC); 
 
	CRect rectClient = lpDIS->rcItem; 
 
	OnFillBackground (pDC, rectClient); 
	OnDrawBorder (pDC, rectClient, lpDIS->itemState); 
 
	//--------------------- 
	// Draw button content: 
	//--------------------- 
	OnDraw (pDC, rectClient, lpDIS->itemState); 
 
	if ((lpDIS->itemState & ODS_FOCUS) && m_bDrawFocus) 
	{ 
		OnDrawFocusRect (pDC, rectClient); 
	} 
} 
//**************************************************************************** 
void CBCGPButton::PreSubclassWindow()  
{ 
	InitStyle (GetStyle ()); 
 
	ModifyStyle (BS_DEFPUSHBUTTON, BS_OWNERDRAW); 
	CButton::PreSubclassWindow(); 
} 
//**************************************************************************** 
BOOL CBCGPButton::PreCreateWindow(CREATESTRUCT& cs)  
{ 
	InitStyle (cs.style); 
 
	cs.style |= BS_OWNERDRAW; 
	cs.style &= ~BS_DEFPUSHBUTTON; 
 
	return CButton::PreCreateWindow(cs); 
} 
//**************************************************************************** 
void CBCGPButton::InitStyle (DWORD dwStyle) 
{ 
	switch (dwStyle & 0x0F) { 
	case BS_CHECKBOX: 
		m_bCheckButton = TRUE	; 
		break	; 
	case BS_AUTOCHECKBOX: 
		m_bCheckButton = 
			m_bAutoCheck = TRUE	; 
		break	; 
	case BS_RADIOBUTTON: 
		m_bRadioButton = TRUE	; 
		break	; 
	case BS_AUTORADIOBUTTON: 
		m_bRadioButton = 
			m_bAutoCheck = TRUE	; 
		break	; 
	} 
	if (m_bCheckButton || m_bRadioButton) { 
		switch (dwStyle & BS_CENTER) { 
		case BS_LEFT: 
			m_nAlignStyle = CBCGPButton::ALIGN_LEFT	; 
			break	; 
		case BS_RIGHT: 
			m_nAlignStyle = CBCGPButton::ALIGN_RIGHT	; 
			break	; 
		case BS_CENTER: 
			m_nAlignStyle = CBCGPButton::ALIGN_CENTER	; 
			break	; 
		} 
	} 
} 
//**************************************************************************** 
BOOL CBCGPButton::OnEraseBkgnd(CDC* /*pDC*/)  
{ 
	return TRUE; 
} 
//**************************************************************************** 
void CBCGPButton::OnFillBackground (CDC* pDC, const CRect& rectClient) 
{ 
	if (m_bTransparent) 
	{ 
		// Copy background from the parent window 
		globalData.DrawParentBackground (this, pDC); 
	} 
	else 
	{ 
		if (m_clrFace == (COLORREF)-1) 
		{ 
			pDC->FillRect (rectClient, &globalData.brBtnFace); 
		} 
		else 
		{ 
			pDC->FillSolidRect (rectClient, m_clrFace); 
		} 
	} 
 
	if (m_bChecked && m_bHighlightChecked && !(m_bPushed && m_bHighlighted)) 
	{ 
		CBCGPDrawManager dm (*pDC); 
		dm.HighlightRect (rectClient); 
	} 
} 
//**************************************************************************** 
void CBCGPButton::OnDraw (CDC* pDC, const CRect& rect, UINT uiState) 
{ 
	CRect rectText = rect; 
	CRect rectImage = rect; 
 
	CString strText; 
	GetWindowText (strText); 
 
	if (m_sizeImage.cx != 0) 
	{ 
		if (!strText.IsEmpty ()) 
		{ 
			if (m_bRighImage) 
			{ 
				rectText.right -= m_sizeImage.cx + nImageHorzMargin / 2; 
				rectImage.left = rectText.right; 
				rectImage.right -= nImageHorzMargin / 2; 
			} 
			else 
			{ 
				rectText.left +=  m_sizeImage.cx + nImageHorzMargin / 2; 
				rectImage.left += nImageHorzMargin / 2; 
				rectImage.right = rectText.left; 
			} 
		} 
 
		// Center image: 
		rectImage.DeflateRect ((rectImage.Width () - m_sizeImage.cx) / 2, 
			max (0, (rect.Height () - m_sizeImage.cy) / 2)); 
	} 
	else 
	{ 
		rectImage.SetRectEmpty (); 
	} 
 
	//----------- 
	// Draw text: 
	//----------- 
	CFont* pOldFont = SelectFont (pDC); 
	ASSERT(pOldFont != NULL); 
 
	pDC->SetBkMode (TRANSPARENT); 
	COLORREF clrText = m_clrRegular == clrDefault ?  
		globalData.clrBtnText : m_clrRegular; 
	 
	if (m_bHighlighted && m_clrHover != clrDefault) 
	{ 
		clrText = m_clrHover; 
	} 
 
	UINT uiDTFlags = DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS; 
	switch (m_nAlignStyle) 
	{ 
	case ALIGN_LEFT: 
		uiDTFlags |= DT_LEFT; 
		rectText.left += nImageHorzMargin / 2; 
		break; 
 
	case ALIGN_RIGHT: 
		uiDTFlags |= DT_RIGHT; 
		rectText.right -= nImageHorzMargin / 2; 
		break; 
 
	case ALIGN_CENTER: 
		uiDTFlags |= DT_CENTER; 
	} 
 
	if ((uiState & ODS_DISABLED) && m_bGrayDisabled) 
	{ 
		pDC->SetTextColor (globalData.clrBtnHilite); 
 
		CRect rectShft = rectText; 
		rectShft.OffsetRect (1, 1); 
		pDC->DrawText (strText, rectShft, uiDTFlags); 
 
		clrText = globalData.clrGrayedText; 
	} 
 
	pDC->SetTextColor (clrText); 
 
	if (m_bDelayFullTextTooltipSet) 
	{ 
		BOOL bIsFullText = pDC->GetTextExtent (strText).cx <= rectText.Width (); 
		SetTooltip (bIsFullText ? NULL : (LPCTSTR) strText); 
		m_bDelayFullTextTooltipSet = FALSE; 
	} 
 
	OnDrawText (pDC, rectText, strText, uiDTFlags, uiState); 
 
	//------------ 
	// Draw image: 
	//------------ 
	if (!rectImage.IsRectEmpty ()) 
	{ 
		if (m_nStdImageId != (CMenuImages::IMAGES_IDS) -1) 
		{ 
			CMenuImages::IMAGES_IDS id = m_nStdImageId; 
 
			if ((uiState & ODS_DISABLED) && m_bGrayDisabled && 
				m_nStdImageDisabledId != 0) 
			{ 
				id = m_nStdImageDisabledId; 
			} 
 
			CMenuImages::Draw (pDC, id, rectImage.TopLeft (), m_StdImageState); 
		} 
		else 
		{ 
			CImageList& imageChecked =  
				(((uiState & ODS_DISABLED) && m_bGrayDisabled && m_ImageCheckedDisabled.GetSafeHandle () != NULL) ? 
				m_ImageCheckedDisabled : 
				(m_bHighlighted && m_ImageCheckedHot.GetSafeHandle () != NULL) ? 
				m_ImageCheckedHot : m_ImageChecked); 
 
			CImageList& image =  
				(((uiState & ODS_DISABLED) && m_bGrayDisabled && m_ImageDisabled.GetSafeHandle () != NULL) ? 
				m_ImageDisabled : 
				(m_bHighlighted && m_ImageHot.GetSafeHandle () != NULL) ? 
				m_ImageHot : m_Image); 
 
			if (m_bChecked && imageChecked.GetSafeHandle () != NULL && imageChecked.GetImageCount () > 0) 
			{ 
				imageChecked.Draw (pDC, 0, rectImage.TopLeft (), ILD_NORMAL); 
			} 
			else if (image.GetSafeHandle () != NULL && image.GetImageCount () > 0) 
			{ 
				image.Draw (pDC, 0, rectImage.TopLeft (), ILD_NORMAL); 
			} 
		} 
	} 
 
	pDC->SelectObject (pOldFont); 
} 
//**************************************************************************** 
void CBCGPButton::OnDrawText (CDC* pDC, const CRect& rect, const CString& strText, 
							 UINT uiDTFlags, UINT /*uiState*/) 
{ 
	ASSERT_VALID (pDC); 
 
	CRect rectText = rect; 
	pDC->DrawText (strText, rectText, uiDTFlags); 
} 
//**************************************************************************** 
void CBCGPButton::SetImage (HICON hIconCold, BOOL bAutoDestroy, HICON hIconHot, HICON hIconDisabled) 
{ 
	SetImageInternal (hIconCold, bAutoDestroy, hIconHot, FALSE /* Not checked */, hIconDisabled); 
} 
//**************************************************************************** 
void CBCGPButton::SetImage (HBITMAP hBitmapCold, BOOL bAutoDestroy, HBITMAP hBitmapHot, BOOL bMap3dColors, 
							HBITMAP hBitmapDisabled) 
{ 
	SetImageInternal (hBitmapCold, bAutoDestroy, hBitmapHot, bMap3dColors, FALSE /* Not checked */, 
		hBitmapDisabled); 
} 
//**************************************************************************** 
void CBCGPButton::SetImage (UINT uiBmpResId, UINT uiBmpHotResId, UINT uiBmpDsblResID) 
{ 
	SetImageInternal (uiBmpResId, uiBmpHotResId, FALSE /* Not checked */, uiBmpDsblResID); 
} 
//**************************************************************************** 
void CBCGPButton::SetCheckedImage (HICON hIconCold, BOOL bAutoDestroy, HICON hIconHot, HICON hIconDisabled) 
{ 
	SetImageInternal (hIconCold, bAutoDestroy, hIconHot, TRUE /* Checked */, hIconDisabled); 
} 
//**************************************************************************** 
void CBCGPButton::SetCheckedImage (HBITMAP hBitmapCold, BOOL bAutoDestroy, HBITMAP hBitmapHot, BOOL bMap3dColors, HBITMAP hBitmapDisabled) 
{ 
	SetImageInternal (hBitmapCold, bAutoDestroy, hBitmapHot, bMap3dColors, TRUE /* Checked */, hBitmapDisabled); 
} 
//**************************************************************************** 
void CBCGPButton::SetCheckedImage (UINT uiBmpResId, UINT uiBmpHotResId, UINT uiBmpDsblResID) 
{ 
	SetImageInternal (uiBmpResId, uiBmpHotResId, TRUE /* Checked */, uiBmpDsblResID); 
} 
//**************************************************************************** 
void CBCGPButton::SetImageInternal (HICON hIconCold, BOOL bAutoDestroy, HICON hIconHot, BOOL bChecked, HICON hIconDisabled) 
{ 
	ClearImages (bChecked); 
 
	if (hIconCold == NULL) 
	{ 
		return; 
	} 
 
	const int nCount = hIconDisabled == NULL ? 2 : 3; 
 
	for (int i = 0; i < nCount; i++) 
	{ 
		HICON hIcon = (i == 0) ? hIconCold : (i == 1) ? hIconHot : hIconDisabled; 
		CImageList& image = bChecked ? ((i == 0) ?  
			m_ImageChecked : (i == 1) ? m_ImageCheckedHot : m_ImageCheckedDisabled) :  
			((i == 0) ? m_Image : (i == 1) ? m_ImageHot : m_ImageDisabled); 
 
		if (hIcon == 0) 
		{ 
			break; 
		} 
 
		ICONINFO info; 
		::GetIconInfo (hIcon, &info); 
 
		BITMAP bmp; 
		::GetObject (info.hbmColor, sizeof (BITMAP), (LPVOID) &bmp); 
 
		m_sizeImage.cx = bmp.bmWidth; 
		m_sizeImage.cy = bmp.bmHeight; 
 
		if (i == 0) 
		{ 
			//-------------------------------------------- 
			// Create disabled image from the "cold" icon: 
			//-------------------------------------------- 
			CDC dcMem; 
			dcMem.CreateCompatibleDC (NULL); 
 
			HBITMAP hBmp = (HBITMAP) ::CopyImage (info.hbmColor, IMAGE_BITMAP, 0, 0, 0); 
			if (hBmp == NULL) 
			{ 
				ASSERT (FALSE); 
			} 
			else 
			{ 
				HBITMAP hOldBmp = (HBITMAP) dcMem.SelectObject (hBmp); 
 
				dcMem.FillRect (CRect (0, 0, m_sizeImage.cx, m_sizeImage.cy),  
									&globalData.brBtnFace); 
 
				::DrawIconEx (dcMem.GetSafeHdc (), 0, 0, hIcon, m_sizeImage.cx, m_sizeImage.cy, 
								0, NULL, DI_NORMAL); 
 
				dcMem.SelectObject (hOldBmp); 
 
				if (hIconDisabled == NULL) 
				{ 
					CreateDisabledImage (hBmp, bChecked); 
				} 
 
				::DeleteObject (hBmp); 
			} 
		} 
 
		::DeleteObject (info.hbmColor); 
		::DeleteObject (info.hbmMask); 
 
		UINT nFlags = ILC_MASK; 
 
		switch (bmp.bmBitsPixel) 
		{ 
		case 4: 
		default: 
			nFlags |= ILC_COLOR4; 
			break; 
 
		case 8: 
			nFlags |= ILC_COLOR8; 
			break; 
 
		case 16: 
			nFlags |= ILC_COLOR16; 
			break; 
 
		case 24: 
			nFlags |= ILC_COLOR24; 
			break; 
 
		case 32: 
			nFlags |= ILC_COLOR32; 
			break; 
		} 
 
		image.Create (bmp.bmWidth, bmp.bmHeight, nFlags, 0, 0); 
		image.Add (hIcon); 
	} 
 
	if (bAutoDestroy) 
	{ 
		if (hIconCold != NULL) 
		{ 
			::DestroyIcon (hIconCold); 
		} 
 
		if (hIconHot != NULL) 
		{ 
			::DestroyIcon (hIconHot); 
		} 
	} 
} 
//**************************************************************************** 
void CBCGPButton::SetImageInternal (HBITMAP hBitmapCold, BOOL bAutoDestroy, HBITMAP hBitmapHot, BOOL bMap3dColors, BOOL bChecked, 
									HBITMAP hBitmapDisabled) 
{ 
	ClearImages (bChecked); 
 
	if (hBitmapCold == NULL) 
	{ 
		return; 
	} 
 
	const int nCount = hBitmapDisabled == NULL ? 2 : 3; 
 
	for (int i = 0; i < nCount; i++) 
	{ 
		HBITMAP hBitmap = (i == 0) ? hBitmapCold : (i == 1) ? hBitmapHot : hBitmapDisabled; 
		CImageList& image = bChecked ? ((i == 0) ?  
			m_ImageChecked : (i == 1) ? m_ImageCheckedHot : m_ImageCheckedDisabled) :  
			((i == 0) ? m_Image : (i == 1) ? m_ImageHot : m_ImageDisabled); 
 
		if (hBitmap == NULL) 
		{ 
			break; 
		} 
 
		BITMAP bmp; 
		::GetObject (hBitmap, sizeof (BITMAP), (LPVOID) &bmp); 
 
		if (i == 0) 
		{ 
			m_sizeImage.cx = bmp.bmWidth; 
			m_sizeImage.cy = bmp.bmHeight; 
		} 
		else 
		{ 
			// Hot and cold bitmaps should have the same size! 
			ASSERT (m_sizeImage.cx == bmp.bmWidth); 
			ASSERT (m_sizeImage.cy == bmp.bmHeight); 
		} 
 
		UINT nFlags = ILC_MASK; 
 
		switch (bmp.bmBitsPixel) 
		{ 
		case 4: 
		default: 
			nFlags |= ILC_COLOR4; 
			break; 
 
		case 8: 
			nFlags |= ILC_COLOR8; 
			break; 
 
		case 16: 
			nFlags |= ILC_COLOR16; 
			break; 
 
		case 24: 
			nFlags |= ILC_COLOR24; 
			break; 
 
		case 32: 
			nFlags |= ILC_COLOR32; 
			break; 
		} 
 
		image.Create (bmp.bmWidth, bmp.bmHeight, nFlags, 0, 0); 
 
		HBITMAP hbmpCopy = (HBITMAP) ::CopyImage (hBitmap, IMAGE_BITMAP, 0, 0, 0); 
		image.Add (CBitmap::FromHandle (hbmpCopy),  
			bMap3dColors ? RGB (192, 192, 192) : globalData.clrBtnFace); 
		::DeleteObject (hbmpCopy); 
	} 
 
	if (hBitmapDisabled == NULL) 
	{ 
		CreateDisabledImage (hBitmapCold, bChecked); 
	} 
 
	if (bAutoDestroy) 
	{ 
		if (hBitmapHot != NULL) 
		{ 
			::DeleteObject (hBitmapHot); 
		} 
 
		if (hBitmapCold != NULL) 
		{ 
			::DeleteObject (hBitmapCold); 
		} 
	} 
} 
//**************************************************************************** 
static HBITMAP ButtonLoadBitmap (UINT uiBmpResId) 
{ 
	if (uiBmpResId == 0) 
	{ 
		return NULL; 
	} 
 
 
	CBCGPToolBarImages images; 
	if (!images.Load (uiBmpResId)) 
	{ 
		ASSERT (FALSE); 
		return NULL; 
	} 
 
	return (HBITMAP) ::CopyImage (images.GetImageWell (), IMAGE_BITMAP, 0, 0, 0); 
} 
//******************************************************************************** 
void CBCGPButton::SetImageInternal (UINT uiBmpResId, UINT uiBmpHotResId, BOOL bChecked, UINT uiBmpDsblResID) 
{ 
	ClearImages (bChecked); 
 
	if (uiBmpResId == 0) 
	{ 
		return; 
	} 
 
	HBITMAP hbmp = ButtonLoadBitmap (uiBmpResId); 
	HBITMAP hbmpHot = ButtonLoadBitmap (uiBmpHotResId); 
	HBITMAP hbmpDisabled = ButtonLoadBitmap (uiBmpDsblResID); 
 
	SetImageInternal (hbmp, TRUE /* AutoDestroy */, hbmpHot, FALSE, bChecked, hbmpDisabled); 
} 
//**************************************************************************** 
void CBCGPButton::SetStdImage (CMenuImages::IMAGES_IDS id, CMenuImages::IMAGE_STATE state, 
							   CMenuImages::IMAGES_IDS idDisabled) 
{ 
	CleanUp (); 
 
	m_sizeImage = CMenuImages::Size (); 
	m_nStdImageId = id; 
	m_nStdImageDisabledId = idDisabled; 
	m_StdImageState = state; 
} 
//**************************************************************************** 
void CBCGPButton::OnCancelMode()  
{ 
	CButton::OnCancelMode(); 
	 
	if (m_bCaptured) 
	{ 
		ReleaseCapture (); 
 
		m_bCaptured = FALSE; 
		m_bPushed = FALSE; 
		m_bClickiedInside = FALSE; 
		m_bHighlighted = FALSE; 
		m_bHover = FALSE; 
 
		Invalidate (); 
		UpdateWindow (); 
	} 
 
	if (m_nAutoRepeatTimeDelay >= 0) 
	{ 
		KillTimer (IdAutoCommand); 
	} 
} 
//**************************************************************************** 
void CBCGPButton::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	m_bHover = FALSE; 
 
	if ((nFlags & MK_LBUTTON) || m_nFlatStyle != BUTTONSTYLE_3D || 
		m_bWinXPTheme) 
	{ 
		BOOL bRedraw = FALSE; 
 
		CRect rectClient; 
		GetClientRect (rectClient); 
 
		if (rectClient.PtInRect (point)) 
		{ 
			m_bHover = TRUE; 
 
			if (!m_bHighlighted) 
			{ 
				m_bHighlighted = TRUE; 
				bRedraw = TRUE; 
			} 
 
			if ((nFlags & MK_LBUTTON) && !m_bPushed && m_bClickiedInside) 
			{ 
				m_bPushed = TRUE; 
				bRedraw = TRUE; 
			} 
 
			if (!m_bCaptured) 
			{ 
				SetCapture (); 
				m_bCaptured = TRUE; 
				bRedraw = TRUE; 
			} 
		} 
		else 
		{ 
			if (nFlags & MK_LBUTTON) 
			{ 
				if (m_bPushed) 
				{ 
					m_bPushed = FALSE; 
					bRedraw = TRUE; 
				} 
			} 
			else if (m_bHighlighted) 
			{ 
				m_bHighlighted = FALSE; 
				bRedraw = TRUE; 
			} 
 
			if (m_bCaptured && (!nFlags & MK_LBUTTON)) 
			{ 
				ReleaseCapture (); 
				m_bCaptured = FALSE; 
 
				bRedraw = TRUE; 
			} 
		} 
 
		if (bRedraw) 
		{ 
			Invalidate (); 
			UpdateWindow (); 
		} 
	} 
	 
	CButton::OnMouseMove(nFlags, point); 
} 
//**************************************************************************** 
void CBCGPButton::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	if (m_bResponseOnButtonDown) 
	{ 
		CWnd* pParent = GetParent (); 
		if (pParent != NULL) 
		{ 
			pParent->SendMessage (	WM_COMMAND, 
									MAKEWPARAM (GetDlgCtrlID (), BN_CLICKED), 
									(LPARAM) m_hWnd); 
		} 
	} 
	else 
	{ 
		m_bPushed = TRUE; 
		m_bClickiedInside = TRUE; 
		m_bHighlighted = TRUE; 
 
		if (!m_bCaptured) 
		{ 
			SetCapture (); 
			m_bCaptured = TRUE; 
		} 
 
		Invalidate (); 
		UpdateWindow (); 
 
		if (m_nAutoRepeatTimeDelay > 0) 
		{ 
			SetTimer (IdAutoCommand, m_nAutoRepeatTimeDelay, NULL); 
		} 
	} 
 
	CButton::OnLButtonDown(nFlags, point); 
} 
//**************************************************************************** 
void CBCGPButton::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	BOOL bClicked = m_bPushed && m_bClickiedInside && m_bHighlighted; 
 
	m_bPushed = FALSE; 
	m_bClickiedInside = FALSE; 
	m_bHighlighted = FALSE; 
 
	if (bClicked && m_bAutoCheck) 
	{ 
		if (m_bCheckButton) 
		{ 
			m_bChecked = !m_bChecked; 
		} 
		else if (m_bRadioButton && !m_bChecked) 
		{ 
			m_bChecked = TRUE; 
			UncheckRadioButtonsInGroup (); 
		} 
	} 
 
	RedrawWindow (); 
	CButton::OnLButtonUp(nFlags, point); 
 
	if (m_bCaptured) 
	{ 
		ReleaseCapture (); 
		m_bCaptured = FALSE; 
	} 
 
	if (m_nAutoRepeatTimeDelay > 0) 
	{ 
		KillTimer (IdAutoCommand); 
	} 
 
	if (m_wndToolTip.GetSafeHwnd () != NULL) 
	{ 
		m_wndToolTip.Pop (); 
 
		CString str; 
		m_wndToolTip.GetText (str, this); 
		m_wndToolTip.UpdateTipText (str, this); 
	} 
} 
//**************************************************************************** 
CSize CBCGPButton::SizeToContent (BOOL bCalcOnly) 
{ 
	ASSERT (GetSafeHwnd () != NULL); 
 
	CClientDC dc (this); 
 
	CFont* pOldFont = SelectFont (&dc); 
	ASSERT(pOldFont != NULL); 
 
	CString strText; 
	GetWindowText (strText); 
	CSize sizeText = dc.GetTextExtent (strText); 
 
	int cx = sizeText.cx + m_sizeImage.cx + nImageHorzMargin; 
	if (sizeText.cx > 0) 
	{ 
		cx += nImageHorzMargin; 
	} 
 
	int cy = max (sizeText.cy, m_sizeImage.cy) + nVertMargin * 2; 
 
	if (!bCalcOnly) 
	{ 
		SetWindowPos (NULL, -1, -1, cx, cy, 
			SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); 
	} 
 
	dc.SelectObject (pOldFont); 
 
	return CSize (cx, cy); 
} 
//**************************************************************************** 
BOOL CBCGPButton::PreTranslateMessage(MSG* pMsg)  
{ 
	if (m_wndToolTip.GetSafeHwnd () != NULL) 
	{ 
		if (pMsg->message == WM_LBUTTONDOWN || 
			pMsg->message == WM_LBUTTONUP || 
			pMsg->message == WM_MOUSEMOVE) 
		{ 
			m_wndToolTip.RelayEvent(pMsg); 
		} 
	} 
 
	if (pMsg->message == WM_KEYDOWN && 
		pMsg->wParam == VK_RETURN && 
		CBCGPPopupMenu::GetActiveMenu () == NULL) 
	{ 
		CWnd* pParent = GetParent (); 
		if (pParent != NULL) 
		{ 
			pParent->SendMessage (	WM_COMMAND, 
									MAKEWPARAM (GetDlgCtrlID (), BN_CLICKED), 
									(LPARAM) m_hWnd); 
			return TRUE; 
		} 
	} 
	 
	if (pMsg->message == WM_KEYDOWN && m_bAutoCheck && GetParent () != NULL) 
	{ 
		switch (pMsg->wParam)  
		{ 
		case VK_SPACE: 
			if (m_bCheckButton)  
			{ 
				m_bChecked = !m_bChecked; 
 
				RedrawWindow (); 
 
				CWnd* pWndParent = GetParent (); 
				ASSERT_VALID (pWndParent); 
 
				::SendMessage (pWndParent->GetSafeHwnd(), WM_COMMAND,  
					MAKELONG (::GetWindowLong(m_hWnd, GWL_ID), BN_CLICKED),  
					(LPARAM) m_hWnd); 
 
				return TRUE	; 
			} 
			break; 
 
		case VK_UP: 
		case VK_LEFT: 
			if (CheckNextPrevRadioButton (FALSE)) 
			{ 
				return TRUE; 
			} 
			break; 
 
		case VK_DOWN: 
		case VK_RIGHT: 
			if (CheckNextPrevRadioButton (TRUE)) 
			{ 
				return TRUE; 
			} 
			break	; 
		} 
	} 
 
	return CButton::PreTranslateMessage(pMsg); 
} 
//**************************************************************************** 
void CBCGPButton::SetTooltip (LPCTSTR lpszToolTipText) 
{ 
	ASSERT (GetSafeHwnd () != NULL); 
 
	if (lpszToolTipText == NULL) 
	{ 
		if (m_wndToolTip.GetSafeHwnd () != NULL) 
		{ 
			m_wndToolTip.Activate (FALSE); 
		} 
	} 
	else 
	{ 
		if (m_wndToolTip.GetSafeHwnd () != NULL) 
		{ 
			m_wndToolTip.UpdateTipText (lpszToolTipText, this); 
		} 
		else 
		{ 
			m_wndToolTip.Create (NULL, TTS_ALWAYSTIP); 
 
			if (globalData.m_nMaxToolTipWidth != -1) 
			{ 
				m_wndToolTip.SetMaxTipWidth (globalData.m_nMaxToolTipWidth); 
			} 
 
			m_wndToolTip.AddTool (this, lpszToolTipText); 
		} 
 
		m_wndToolTip.Activate (TRUE); 
	} 
} 
//**************************************************************************** 
void CBCGPButton::SetMouseCursor (HCURSOR hcursor) 
{ 
	m_hCursor = hcursor; 
} 
//**************************************************************************** 
void CBCGPButton::SetMouseCursorHand () 
{ 
	if (globalData.m_hcurHand == NULL) 
	{ 
		CBCGPLocalResource locaRes; 
		globalData.m_hcurHand = AfxGetApp ()->LoadCursor (IDC_BCGBARRES_HAND); 
	} 
 
	SetMouseCursor (globalData.m_hcurHand); 
} 
//***************************************************************************** 
BOOL CBCGPButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)  
{ 
	if (m_hCursor != NULL) 
	{ 
		CRect rectClient; 
		GetClientRect (rectClient); 
 
		CPoint ptCursor; 
		::GetCursorPos (&ptCursor); 
		ScreenToClient (&ptCursor); 
 
		if (rectClient.PtInRect (ptCursor)) 
		{ 
			::SetCursor (m_hCursor); 
			return TRUE; 
		} 
	} 
	 
	return CButton::OnSetCursor(pWnd, nHitTest, message); 
} 
//***************************************************************************** 
void CBCGPButton::OnDrawFocusRect (CDC* pDC, const CRect& rectClient) 
{ 
	ASSERT_VALID (pDC); 
 
	CRect rectFocus = rectClient; 
	rectFocus.DeflateRect (2, 2); 
 
	COLORREF clrBckgr = (m_clrFace == (COLORREF)-1) ? globalData.clrBtnFace : m_clrFace; 
 
	pDC->Draw3dRect (rectFocus, clrBckgr, clrBckgr); 
	pDC->DrawFocusRect (rectFocus); 
} 
//****************************************************************************** 
BOOL CBCGPButton::CreateDisabledImage (HBITMAP hBitmapOrig, BOOL bChecked) 
{ 
	CImageList& imagesDisabled = bChecked ? m_ImageCheckedDisabled : m_ImageDisabled; 
 
	if (imagesDisabled.GetSafeHandle () != NULL) 
	{ 
		imagesDisabled.DeleteImageList (); 
	} 
 
	//------------------------------- 
	// Get original bitmap attrbutes: 
	//------------------------------- 
	BITMAP bmp; 
	if (::GetObject (hBitmapOrig, sizeof (BITMAP), &bmp) == 0) 
	{ 
		return FALSE; 
	} 
 
	int iBitmapWidth = bmp.bmWidth; 
	int iBitmapHeight = bmp.bmHeight; 
 
	//------------------------------ 
	// Create memory destination DC: 
	//------------------------------ 
	CDC memDCDst; 
	memDCDst.CreateCompatibleDC (NULL); 
	 
	HBITMAP hBitmapDisabled = (HBITMAP) ::CopyImage (hBitmapOrig, IMAGE_BITMAP, 0, 0, 0); 
	if (hBitmapDisabled == NULL) 
	{ 
		return FALSE; 
	} 
 
	HBITMAP hOldBitmapDst = (HBITMAP) memDCDst.SelectObject (hBitmapDisabled); 
	if (hOldBitmapDst == NULL) 
	{ 
		::DeleteObject (hBitmapDisabled); 
		return FALSE; 
	} 
 
	memDCDst.FillRect (CRect (0, 0, iBitmapWidth, iBitmapHeight),  
		&globalData.brBtnFace); 
 
	CBCGPToolBarImages images; 
	images.MapTo3dColors (); 
	images.SetImageSize (CSize (iBitmapWidth, iBitmapHeight)); 
	images.AddImage (hBitmapOrig); 
 
	CBCGPDrawState ds; 
	images.PrepareDrawImage (ds); 
	images.Draw (&memDCDst, 0, 0, 0, FALSE, TRUE); 
	images.EndDrawImage (ds); 
 
	memDCDst.SelectObject (hOldBitmapDst); 
 
	UINT nFlags = ILC_MASK; 
 
	switch (bmp.bmBitsPixel) 
	{ 
	case 4: 
	default: 
		nFlags |= ILC_COLOR4; 
		break; 
 
	case 8: 
		nFlags |= ILC_COLOR8; 
		break; 
 
	case 16: 
		nFlags |= ILC_COLOR16; 
		break; 
 
	case 24: 
		nFlags |= ILC_COLOR24; 
		break; 
 
	case 32: 
		nFlags |= ILC_COLOR32; 
		break; 
	} 
 
	imagesDisabled.Create (iBitmapWidth, iBitmapHeight, nFlags, 0, 0); 
	imagesDisabled.Add (CBitmap::FromHandle (hBitmapDisabled), globalData.clrBtnFace); 
 
	::DeleteObject (hBitmapDisabled); 
 
	return TRUE; 
} 
//****************************************************************************** 
void CBCGPButton::OnEnable(BOOL bEnable)  
{ 
	// By Yury Goltsman 
	if (!bEnable) 
	{ 
		// control disabled 
		m_bPushed = FALSE; 
		m_bClickiedInside = FALSE; 
		m_bHighlighted = FALSE; 
		 
		if (m_bCaptured) 
		{ 
			ReleaseCapture (); 
			m_bCaptured = FALSE; 
		} 
	} 
	 
	RedrawWindow (); 
	CButton::OnEnable(bEnable); 
} 
//****************************************************************************** 
void CBCGPButton::SetFaceColor (COLORREF crFace, BOOL bRedraw) 
{ 
	m_clrFace = crFace; 
 
	if (bRedraw && GetSafeHwnd () != NULL) 
	{ 
		Invalidate (); 
		UpdateWindow (); 
	} 
} 
//***************************************************************************** 
CFont* CBCGPButton::SelectFont (CDC* pDC) 
{ 
	ASSERT_VALID (pDC); 
 
	CFont* pOldFont = m_hFont == NULL ? 
		(CFont*) pDC->SelectStockObject (DEFAULT_GUI_FONT) : 
		pDC->SelectObject (CFont::FromHandle (m_hFont)); 
 
	ASSERT(pOldFont != NULL); 
	return pOldFont; 
} 
//***************************************************************************** 
afx_msg LRESULT CBCGPButton::OnSetFont (WPARAM wParam, LPARAM lParam) 
{ 
	BOOL bRedraw = (BOOL) LOWORD (lParam); 
 
	m_hFont = (HFONT) wParam; 
 
	if (bRedraw) 
	{ 
		Invalidate (); 
		UpdateWindow (); 
	} 
 
	return 0; 
} 
//***************************************************************************** 
afx_msg LRESULT CBCGPButton::OnGetFont (WPARAM, LPARAM) 
{ 
	return (LRESULT) m_hFont; 
} 
//***************************************************************************** 
void CBCGPButton::EnableMenuFont (BOOL bOn, BOOL bRedraw) 
{ 
	m_hFont = bOn ? (HFONT) globalData.fontRegular.GetSafeHandle () : NULL; 
 
	if (bRedraw && GetSafeHwnd () != NULL) 
	{ 
		Invalidate (); 
		UpdateWindow (); 
	} 
} 
//****************************************************************************** 
void CBCGPButton::EnableFullTextTooltip (BOOL bOn) 
{ 
	m_bFullTextTooltip = bOn; 
	m_bDelayFullTextTooltipSet = bOn; 
} 
//****************************************************************************** 
void CBCGPButton::OnSize(UINT nType, int cx, int cy)  
{ 
	m_bDelayFullTextTooltipSet = m_bFullTextTooltip; 
	CButton::OnSize(nType, cx, cy); 
} 
//****************************************************************************** 
void CBCGPButton::OnDrawBorder (CDC* pDC, CRect& rectClient, UINT uiState) 
{ 
	DrawBorder (pDC, rectClient, uiState); 
} 
//**************************************************************************************** 
void CBCGPButton::OnKillFocus(CWnd* pNewWnd)  
{ 
	CButton::OnKillFocus(pNewWnd); 
	 
	if (m_bCaptured) 
	{ 
		ReleaseCapture (); 
		m_bCaptured = FALSE; 
	} 
	 
	m_bPushed = FALSE; 
	m_bClickiedInside = FALSE; 
	m_bHighlighted = FALSE; 
	m_bHover = FALSE; 
 
	Invalidate (); 
	UpdateWindow (); 
} 
//***************************************************************************************** 
void CBCGPButton::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	m_bPushed = TRUE; 
	m_bClickiedInside = TRUE; 
	m_bHighlighted = TRUE; 
 
	Invalidate (); 
	UpdateWindow (); 
 
	CButton::OnLButtonDblClk(nFlags, point); 
} 
//*************************************************************************************** 
void CBCGPButton::EnableWinXPTheme (BOOL bEnable/* = TRUE*/) 
{ 
	m_bWinXPTheme = bEnable; 
} 
//*************************************************************************************** 
LRESULT CBCGPButton::OnGetCheck(WPARAM, LPARAM) 
{ 
	if (m_bCheckButton || m_bRadioButton) 
	{ 
		return m_bChecked ? BST_CHECKED	: BST_UNCHECKED; 
	} 
 
	return 0; 
} 
//*************************************************************************************** 
LRESULT CBCGPButton::OnSetCheck(WPARAM fCheck, LPARAM) 
{ 
	ASSERT (fCheck != BST_INDETERMINATE); 
 
	if ((m_bCheckButton || m_bRadioButton) && (!m_bChecked) != (fCheck == BST_UNCHECKED))  
	{ 
		m_bChecked = fCheck != BST_UNCHECKED; 
		 
		if (m_bRadioButton) 
		{ 
			UncheckRadioButtonsInGroup (); 
		} 
 
		Invalidate(); 
		UpdateWindow(); 
	} 
 
	return 0	; 
} 
//**************************************************************************************** 
void CBCGPButton::ClearImages (BOOL bChecked) 
{ 
	m_nStdImageId = (CMenuImages::IMAGES_IDS) -1; 
	m_nStdImageDisabledId = (CMenuImages::IMAGES_IDS) -1; 
	m_sizeImage = CSize (0, 0); 
 
	if (bChecked) 
	{ 
		m_ImageChecked.DeleteImageList (); 
		m_ImageCheckedHot.DeleteImageList (); 
		m_ImageCheckedDisabled.DeleteImageList (); 
	} 
	else 
	{ 
		m_Image.DeleteImageList (); 
		m_ImageHot.DeleteImageList (); 
		m_ImageDisabled.DeleteImageList (); 
	} 
} 
//**************************************************************************************** 
BOOL CBCGPButton::CheckNextPrevRadioButton (BOOL bNext) 
{ 
	ASSERT_VALID (this); 
 
	if (!m_bRadioButton) 
	{ 
		return FALSE; 
	} 
 
	CWnd* pWndParent = GetParent (); 
	ASSERT_VALID (pWndParent); 
 
	CBCGPButton* pBtn = NULL; 
 
	for (CWnd* pWnd = pWndParent->GetNextDlgGroupItem (this, !bNext);  
		pWnd != this;  
		pWnd = pWndParent->GetNextDlgGroupItem (pWnd, !bNext)) 
	{ 
		if ((pBtn = DYNAMIC_DOWNCAST(CBCGPButton, pWnd)) != NULL && 
			pBtn->m_bRadioButton && 
			(pBtn->GetStyle() & (WS_DISABLED | WS_VISIBLE)) == WS_VISIBLE) 
		{ 
			break; 
		} 
	} 
 
	if (pBtn != NULL && pBtn != this && !pBtn->m_bChecked) 
	{ 
		pBtn->SetCheck (TRUE); 
		pBtn->SetFocus (); 
 
		::SendMessage (pBtn->GetParent()->GetSafeHwnd(), WM_COMMAND, 
			MAKELONG (::GetWindowLong(pBtn->m_hWnd, GWL_ID), BN_CLICKED), 
			(LPARAM) pBtn->m_hWnd); 
		return TRUE; 
	} 
 
	return FALSE; 
} 
//**************************************************************************************** 
void CBCGPButton::UncheckRadioButtonsInGroup () 
{ 
	CWnd* pWndParent = GetParent (); 
	if (pWndParent == NULL) 
	{ 
		return; 
	} 
 
	ASSERT_VALID (pWndParent); 
 
	//-------------------------------------------------------- 
	// Walk through group and clear radio buttons check state 
	//-------------------------------------------------------- 
	for (CWnd * pCtl = pWndParent->GetNextDlgGroupItem (this);  
		pCtl != this && pCtl != NULL; 
		pCtl = pWndParent->GetNextDlgGroupItem (pCtl)) 
	{ 
		CBCGPButton* pBtn = DYNAMIC_DOWNCAST (CBCGPButton, pCtl); 
 
		if (pBtn != NULL && pBtn->m_bRadioButton && pBtn->m_bChecked)  
		{ 
			pBtn->m_bChecked = FALSE; 
			pBtn->RedrawWindow (); 
		} 
	} 
} 
//*********************************************************************************** 
void CBCGPButton::SetAutorepeatMode (int nTimeDelay) 
{ 
	ASSERT (nTimeDelay >= 0); 
	m_nAutoRepeatTimeDelay = nTimeDelay; 
} 
//*********************************************************************************** 
void CBCGPButton::OnTimer(UINT nIDEvent)  
{ 
	if (nIDEvent == IdAutoCommand) 
	{ 
		if (m_bPushed && m_bHighlighted) 
		{ 
			CWnd* pParent = GetParent (); 
			if (pParent != NULL) 
			{ 
				pParent->SendMessage (	WM_COMMAND, 
										MAKEWPARAM (GetDlgCtrlID (), BN_CLICKED), 
										(LPARAM) m_hWnd); 
			} 
		} 
	} 
 
	CButton::OnTimer(nIDEvent); 
} 
//**************************************************************************************** 
void CBCGPButton::DrawBorder (CDC* pDC, CRect& rectClient, UINT uiState) 
{ 
	ASSERT_VALID (pDC); 
 
	BOOL bBorderIsReady = FALSE; 
 
	//---------------- 
	// Draw 3d border: 
	//---------------- 
	if (m_nFlatStyle != BUTTONSTYLE_NOBORDERS) 
	{ 
		if (m_bWinXPTheme) 
		{ 
			// Draw borders using current WinXP theme 
			CBCGPWinXPVisualManager* pWinXPManager = 
				DYNAMIC_DOWNCAST (CBCGPWinXPVisualManager, CBCGPVisualManager::GetInstance ()); 
			if (pWinXPManager != NULL && 
				pWinXPManager->DrawPushButton (pDC, rectClient, this, uiState)) 
			{ 
				bBorderIsReady = TRUE; 
			} 
 
			CBCGPVisualManager2003* pManager2003 = 
				DYNAMIC_DOWNCAST (CBCGPVisualManager2003, CBCGPVisualManager::GetInstance ()); 
			if (pManager2003 != NULL && 
				pManager2003->DrawPushButton (pDC, rectClient, this, uiState)) 
			{ 
				bBorderIsReady = TRUE; 
			} 
		} 
 
		if (m_bPushed && m_bHighlighted || (uiState & ODS_SELECTED) || m_bChecked) 
		{ 
			if (!bBorderIsReady) 
			{ 
				pDC->Draw3dRect (rectClient, 
							globalData.clrBtnDkShadow, globalData.clrBtnHilite); 
 
				rectClient.DeflateRect (1, 1); 
 
				if (m_nFlatStyle != BUTTONSTYLE_FLAT) 
				{ 
					pDC->Draw3dRect (rectClient, 
								globalData.clrBtnShadow, globalData.clrBtnLight); 
				} 
 
				rectClient.DeflateRect (1, 1); 
			} 
			else 
			{ 
				rectClient.DeflateRect (2, 2); 
			} 
 
			rectClient.left += m_sizePushOffset.cx; 
			rectClient.top += m_sizePushOffset.cy; 
		} 
		else if (!bBorderIsReady && (m_nFlatStyle != BUTTONSTYLE_FLAT || m_bHighlighted)) 
		{ 
			pDC->Draw3dRect (rectClient, 
						globalData.clrBtnHilite,  
						globalData.clrBtnDkShadow); 
			rectClient.DeflateRect (1, 1); 
 
			if (m_nFlatStyle == BUTTONSTYLE_3D || 
				(m_nFlatStyle == BUTTONSTYLE_SEMIFLAT && m_bHighlighted)) 
			{ 
				pDC->Draw3dRect (rectClient, 
							globalData.clrBtnLight, globalData.clrBtnShadow); 
			} 
 
			rectClient.DeflateRect (1, 1); 
		} 
		else 
		{ 
			rectClient.DeflateRect (2, 2); 
		} 
	} 
	else 
	{ 
		rectClient.DeflateRect (2, 2); 
	} 
}