www.pudn.com > Switcher_demo.zip > SwitcherButton.cpp


// SwitcherButton.cpp 
// 
// Programmed by: JIMMY BRUSH (Kathy007@email.msn.com) 
//  
// Legal: 
// 
// THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. 
// You may use and distribute this code provided that you do not 
// remove this title header and that you do not charge money for 
// it. If you want to update the code, feel free to do so, as long 
// as you *mark your changes* in code AND in the revision log below 
// (and send it to me ;) 
// 
// 
// 
// Version: 1.0 revision 1 
// 
// Revision Log: 
// 
// SUN MAR 14 1999 - JIMMY BRUSH -  Finished Writing version 1.0 
// MON MAR 15 1999 - JIMMY BRUSH -  Fixed RemoveButton to correctly decrement selected button 
//									Added CMemDC by Keith Rule 
//									Fixed up Animation a bit 
// 
// 
// 
// In the next version \ Wish List: 
// 
// 1. Tool Tips in CSwitcherButton 
// 2. Support for more buttons than can display (with the up/down button at the right) 
 
#include "stdafx.h" 
#include "SwitcherWnd.h" 
#include "SwitcherButton.h" 
 
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CSwitcherButton 
 
CSwitcherButton::CSwitcherButton() 
{ 
	m_nState = SWITCHBUTTON_UP; 
	HasCapture = false; 
	m_iIcon = NULL; 
	m_iID = -1; 
 
	// Win95/98 balks at creating & deleting the font in OnPaint 
	// so put it here 
	m_fNormal.CreateFont(10,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_QUALITY|FF_DONTCARE,"MS Sans Serif"); 
	m_fBold.CreateFont(10,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_QUALITY|FF_DONTCARE,"MS Sans Serif"); 
} 
 
CSwitcherButton::~CSwitcherButton() 
{ 
	m_fNormal.DeleteObject(); 
	m_fBold.DeleteObject(); 
} 
 
 
BEGIN_MESSAGE_MAP(CSwitcherButton, CWnd) 
	//{{AFX_MSG_MAP(CSwitcherButton) 
	ON_WM_PAINT() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_WM_MOUSEMOVE() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CSwitcherButton message handlers 
 
void CSwitcherButton::OnPaint()  
{ 
	CPaintDC paintdc(this); // device context for painting 
	CRect rect; 
	GetClientRect(&rect); 
 
	CMemDC dc(&paintdc, &rect); 
	 
	// center the icon 
	int icontop = (rect.Height() / 2) - (16 / 2); 
 
	CString text; 
	GetWindowText(text); 
 
	dc.SetBkMode(TRANSPARENT); 
	dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT)); 
 
	CBrush brush; 
	if (m_nState == SWITCHBUTTON_UP) 
	{ 
		brush.CreateSolidBrush(::GetSysColor(COLOR_3DFACE)); 
		dc.FillRect(&rect, &brush); 
		dc.Draw3dRect(&rect, ::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW)); 
		rect.DeflateRect(1, 1); 
		dc.Draw3dRect(&rect, ::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW)); 
	} 
	else if (m_nState == SWITCHBUTTON_DOWN) 
	{ 
		brush.CreateSolidBrush(::GetSysColor(COLOR_3DFACE)); 
		dc.FillRect(&rect, &brush); 
		dc.Draw3dRect(&rect, ::GetSysColor(COLOR_3DDKSHADOW), ::GetSysColor(COLOR_3DHIGHLIGHT)); 
		rect.DeflateRect(1,1); 
		dc.Draw3dRect(&rect, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT)); 
		// make it look pressed 
		rect.top += 1; 
		icontop += 1; 
	} 
	else if (m_nState == SWITCHBUTTON_SELECTED) 
	{ 
		brush.CreateSolidBrush(::GetSysColor(COLOR_3DLIGHT)); 
		dc.FillRect(&rect, &brush); 
		dc.Draw3dRect(&rect, ::GetSysColor(COLOR_3DDKSHADOW), ::GetSysColor(COLOR_3DHIGHLIGHT)); 
		rect.DeflateRect(1,1); 
		dc.Draw3dRect(&rect, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT)); 
		// make it look pressed 
		rect.top+= 1; 
		icontop += 1; 
	} 
 
	// dont even bother if no text 
	if (text.IsEmpty() == FALSE) 
	{ 
		// dont want text near the border 
		rect.DeflateRect(2,2); 
 
		// MS BUG: DT_VCENTER dont work! (or im doing something wrong) 
		// so must Vertical Center it ourself 
		CSize size; 
		GetTextExtentPoint32(dc.GetSafeHdc(), text, text.GetLength(), &size); 
 
		rect.top += (rect.Height() / 2) - (size.cy / 2) + 1; 
		rect.left += 20; 
 
		if (m_nState == SWITCHBUTTON_SELECTED) 
			dc.SelectObject(&m_fBold); 
		else 
			dc.SelectObject(&m_fNormal); 
 
		dc.DrawText(text, &rect, DT_END_ELLIPSIS|DT_VCENTER); 
	} 
 
	if (m_iIcon != NULL) 
		::DrawIconEx(dc.GetSafeHdc(), 4, icontop, m_iIcon, 16, 16, 0, (HBRUSH)brush, DI_NORMAL); 
 
	brush.DeleteObject(); 
} 
 
void CSwitcherButton::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	CWnd::OnLButtonDown(nFlags, point); 
 
	if (m_nState != SWITCHBUTTON_SELECTED) 
	{ 
		SetCapture(); 
		m_nState = SWITCHBUTTON_DOWN; 
		HasCapture = true; 
		Invalidate(); 
	} 
} 
 
void CSwitcherButton::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	CWnd::OnLButtonUp(nFlags, point); 
 
	bool change = true; 
 
	if (m_nState == SWITCHBUTTON_DOWN) 
	{ 
		m_nState = SWITCHBUTTON_SELECTED; 
		::SendMessage(m_wndParent->GetSafeHwnd(), SWM_SELCHANGE, (WPARAM)this, 0); 
	} 
	else 
	{ 
		if (m_nState == SWITCHBUTTON_UP) 
			change = false; 
 
		if (m_nState == SWITCHBUTTON_SELECTED) 
			::SendMessage(m_wndParent->GetSafeHwnd(), SWM_UNSELECT, (WPARAM)this, 0); 
 
		m_nState = SWITCHBUTTON_UP; 
	} 
 
	ReleaseCapture(); 
	HasCapture = false; 
 
	if (change) 
		Invalidate(); 
} 
 
void CSwitcherButton::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	CWnd::OnMouseMove(nFlags, point); 
 
	if (HasCapture) 
	{ 
		RECT rect; 
		GetClientRect(&rect); 
 
		if (point.x > rect.right || point.x < rect.left || point.y < rect.top || point.y > rect.bottom) 
		{ 
			if (m_nState != SWITCHBUTTON_UP) 
			{ 
				m_nState = SWITCHBUTTON_UP; 
				Invalidate(); 
			} 
		} 
		else 
		{ 
			if (m_nState != SWITCHBUTTON_DOWN) 
			{ 
				m_nState = SWITCHBUTTON_DOWN; 
				Invalidate(); 
			} 
		} 
	} 
 
} 
 
BOOL CSwitcherButton::DoCreate(CWnd *parent, int x, int y, int cx, int cy, CString text) 
{ 
	m_wndParent = parent; 
 
	WNDCLASS myclass; 
	myclass.style = CS_HREDRAW|CS_VREDRAW|CS_PARENTDC; 
	myclass.lpfnWndProc = AfxWndProc; 
	myclass.cbClsExtra = 0; 
	myclass.cbWndExtra = 0; 
	myclass.hInstance = AfxGetInstanceHandle(); 
	myclass.hIcon = NULL; 
	myclass.hCursor = LoadCursor(NULL, IDC_ARROW); 
	myclass.hbrBackground = NULL; 
	myclass.lpszMenuName = NULL; 
	myclass.lpszClassName = "SwitcherButtonClass"; 
	AfxRegisterClass(&myclass); 
 
	return Create("SwitcherButtonClass", text, WS_CHILD|WS_VISIBLE, CRect(x,y,cx+x,cy+y), parent, 0); 
} 
 
void CSwitcherButton::SetText(CString text) 
{ 
	SetWindowText(text); 
	Invalidate(); 
	return; 
} 
 
void CSwitcherButton::ReplaceIcon(HICON icon) 
{ 
	m_iIcon = icon; 
	Invalidate(); 
} 
 
void CSwitcherButton::Refresh() 
{ 
	Invalidate(); 
} 
 
void CSwitcherButton::Select() 
{ 
	if (HasCapture) 
	{ 
		ReleaseCapture(); 
		HasCapture = false; 
	} 
 
	m_nState = SWITCHBUTTON_SELECTED; 
	Invalidate(); 
} 
 
void CSwitcherButton::Unselect() 
{ 
	if (HasCapture) 
	{ 
		ReleaseCapture(); 
		HasCapture = false; 
	} 
 
	m_nState = SWITCHBUTTON_UP; 
	Invalidate(); 
}