www.pudn.com > FTPServerSrc.rar > IconButton.cpp


/********************************************************************/ 
/*																	*/ 
/*  IconButton.cpp													*/ 
/*																	*/ 
/*  Implementation of the CIconButton.								*/ 
/*																	*/ 
/*	This class make it possible to display an icon and text on a	*/ 
/*	button, which unfortunately can't be done with CButton...		*/ 
/*																	*/ 
/*  Programmed by Pablo van der Meer								*/ 
/*  Copyright Pablo Software Solutions 2002							*/ 
/*	http://www.pablovandermeer.nl									*/ 
/*																	*/ 
/*  Last updated: 05 september 2002									*/ 
/*																	*/ 
/********************************************************************/ 
 
#include "stdafx.h" 
#include "IconButton.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
CIconButton::CIconButton() 
{ 
	m_hIcon = NULL; 
} 
 
CIconButton::~CIconButton() 
{ 
	if(m_hIcon != NULL) 
		DeleteObject(m_hIcon); 
} 
 
 
BEGIN_MESSAGE_MAP(CIconButton, CButton) 
	//{{AFX_MSG_MAP(CIconButton) 
		// NOTE - the ClassWizard will add and remove mapping macros here. 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : DrawItem											*/ 
/* Description   : Called by the framework when a visual aspect of	*/ 
/*				   an owner-draw button changes.					*/ 
/*																	*/ 
/********************************************************************/ 
void CIconButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); 
	 
	UINT uStyle = DFCS_BUTTONPUSH; 
 
	// if button is pushed, add the pushed style to DrawFrameControl 
	if (lpDrawItemStruct->itemState & ODS_SELECTED) 
		uStyle |= DFCS_PUSHED; 
 
	// is button flat ? 
	if (GetStyle() & BS_FLAT) 
		uStyle |= DFCS_FLAT; 
 
	// clear background 
	pDC->FillSolidRect(&lpDrawItemStruct->rcItem, ::GetSysColor(COLOR_BTNFACE)); 
 
	// draw the button frame 
	::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle); 
 
	// get button text 
	CString strText; 
	GetWindowText(strText); 
 
	// set default button colors 
	pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT)); 
	pDC->SetBkColor(::GetSysColor(COLOR_BTNFACE)); 
	pDC->SetBkMode(TRANSPARENT); 
 
	// is button disabled ? 
	BOOL bDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED); 
 
	CRect rcIcon(0,0,0,0); 
	// icon loaded ? 
	if(m_hIcon) 
	{ 
		// calculate icon's rectangle 
		rcIcon = lpDrawItemStruct->rcItem; 
		CalcIconRect(pDC, rcIcon); 
 
		CPoint pt = rcIcon.TopLeft(); 
 
		if (lpDrawItemStruct->itemState & ODS_SELECTED) 
			pt.Offset(1, 1); 
 
		// draw icon 
		pDC->DrawState(pt, CSize(m_nIconWidth, m_nIconHeight), (HICON)m_hIcon, DST_ICON | (bDisabled ? DSS_DISABLED : DSS_NORMAL), (CBrush *)NULL); 
	} 
	else 
	{ 
		// if no icon is loaded, just display text 
	} 
 
	// calculate text's rectangle 
	CRect rcText = lpDrawItemStruct->rcItem; 
	CalcTextRect(pDC, strText, rcText, rcIcon); 
 
	if (lpDrawItemStruct->itemState & ODS_SELECTED) 
		rcText.OffsetRect(1, 1); 
 
	// draw text 
	pDC->DrawState(rcText.TopLeft(), rcText.Size(), (LPCTSTR)strText, (bDisabled ? DSS_DISABLED : DSS_NORMAL), TRUE, 0, (CBrush*)NULL); 
 
	// and finally draw the focus rectangle 
	if(lpDrawItemStruct->itemState & ODS_FOCUS) 
	{ 
		rcText = lpDrawItemStruct->rcItem; 
		::InflateRect(&rcText, -2 * ::GetSystemMetrics(SM_CXEDGE), -2 * ::GetSystemMetrics(SM_CYEDGE)); 
		pDC->DrawFocusRect(&rcText); 
	} 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : PreSubclassWindow								*/ 
/* Description   : Initialize some stuff							*/ 
/*																	*/ 
/********************************************************************/ 
void CIconButton::PreSubclassWindow()  
{ 
	// set default style 
	ModifyStyle(NULL, BS_OWNERDRAW | BS_ICON | BS_VCENTER | BS_LEFT); 
	CButton::PreSubclassWindow(); 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : SetIcon											*/ 
/* Description   : Set button's icon								*/ 
/*																	*/ 
/********************************************************************/ 
BOOL CIconButton::SetIcon(UINT nID, int nWidth, int nHeight) 
{ 
	HINSTANCE hInstance = AfxFindResourceHandle(MAKEINTRESOURCE(nID), RT_GROUP_ICON); 
	m_hIcon = (HICON)::LoadImage(hInstance, MAKEINTRESOURCE(nID), IMAGE_ICON, nWidth, nHeight, 0); 
 
	if (m_hIcon == NULL) 
		return FALSE; 
 
	m_nIconWidth = nWidth; 
	m_nIconHeight = nHeight; 
	return TRUE; 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : CalcIconRect										*/ 
/* Description   : Calculate icon's rectangle depending on button	*/ 
/*				   style.											*/ 
/*																	*/ 
/********************************************************************/ 
BOOL CIconButton::CalcIconRect(CDC *pDC, CRect &rcIcon) 
{ 
	DWORD dwStyle = GetStyle(); 
	CRect rc = rcIcon; 
 
	// calculate icon rectangle  
	rc.right  = rc.left + m_nIconWidth; 
	rc.bottom = rc.top  + m_nIconHeight; 
 
	int nOffset; 
	switch(dwStyle & (BS_CENTER|BS_RIGHT)) 
	{ 
		case BS_LEFT:     
			rc.left += 4;   
			rc.right += 4;   
			break; 
 
		case BS_CENTER:   
			nOffset = rc.right - rc.left; 
            rc.left = rcIcon.left + ((rcIcon.right - rcIcon.left) - nOffset) / 2; 
            rc.right = rc.left + nOffset;  
			break; 
		 
		case BS_RIGHT:    
			nOffset = rc.right - rc.left; 
            rc.right = rcIcon.right - 4; 
            rc.left = rc.right - nOffset; 
            break; 
	} 
 
   	switch (dwStyle & (BS_VCENTER|BS_BOTTOM)) 
	{ 
		case BS_TOP:      
			rc.top += 3;   
			rc.bottom += 3;   
			break; 
		 
		case BS_VCENTER:  
			nOffset = rc.bottom - rc.top; 
            rc.top = rcIcon.top + ((rcIcon.bottom - rcIcon.top) - nOffset) / 2; 
            rc.bottom = rc.top + nOffset; 
			break; 
		 
		case BS_BOTTOM:   
			nOffset = rc.bottom - rc.top; 
            rc.bottom = rcIcon.bottom - 3; 
            rc.top = rc.bottom - nOffset; 
            break; 
	} 
	rcIcon = rc; 
	return TRUE; 
} 
 
 
/********************************************************************/ 
/*																	*/ 
/* Function name : CalcTextRect										*/ 
/* Description   : Calculate text's rectangle depending on button	*/ 
/*				   style.											*/ 
/*																	*/ 
/********************************************************************/ 
BOOL CIconButton::CalcTextRect(CDC *pDC, LPCTSTR lpszText, CRect &rcText, CRect &rcIcon) 
{ 
	DWORD dwStyle = GetStyle(); 
 
	CRect rc = rcText; 
 
	switch(dwStyle & (BS_CENTER|BS_RIGHT)) 
	{ 
		case BS_LEFT:     
			rc.left = rcIcon.right;   
			break; 
 
		case BS_CENTER:   
			rc.top = rcIcon.bottom; 
			break; 
		 
		case BS_RIGHT:    
			rc.right = rcIcon.left; 
            break; 
	} 
 
	rcText = rc; 
 
	// calculate text size	 
	pDC->DrawText(lpszText, -1, &rc, DT_SINGLELINE | DT_CALCRECT); 
 
   	switch (dwStyle & (BS_VCENTER|BS_BOTTOM)) 
	{ 
		case BS_TOP:      
			rc.OffsetRect((rcText.Width() - rc.Width())/2, rcIcon.top + rcIcon.Height()/2 - rc.Height()/2); 
			break; 
		 
		case BS_VCENTER:  
			rc.OffsetRect((rcText.Width() - rc.Width())/2, (rcText.Height() - rc.Height())/2); 
			rc.OffsetRect(0, -1); 
			break; 
		 
		case BS_BOTTOM:   
			rc.OffsetRect((rcText.Width() - rc.Width())/2, rcIcon.top + rcIcon.Height()/2 - rc.Height()/2); 
			break; 
	} 
 
	rcText = rc; 
	return TRUE; 
}