Click here to Skip to main content
11,495,758 members (67,200 online)
Click here to Skip to main content
Add your own
alternative version

CButtonST v3.9 (MFC Flat buttons)

, 28 Mar 2003 1.8M 72.9K 584
A fully featured owner-draw button class - it's got the lot!
cbuttonst-beta.zip
cbuttonst26_demo.zip
CButtonST_demo.clw
CButtonST_demo.dsp
CButtonST_demo.dsw
FILE_ID.DIZ
res
32x32x16_About.ico
32x32x16_Cancel.ico
32x32x16_CancelBor.ico
32x32x16_Exit.ico
32x32x16_Explore.ico
32x32x16_Info.ico
32x32x16_Left.ico
32x32x16_Ok.ico
32x32x16_OkBor.ico
32x32x16_Question.ico
32x32x16_Right.ico
32x32x16_Screw.ico
32x32x16_Text.ico
32x32x16_View.ico
32x32x256_Baloon.ico
32x32x256_Cancel.ico
32x32x256_CDGold.ico
32x32x256_Hand.ico
32x32x256_Lamp.ico
32x32x256_Ok.ico
32x32x256_Zip.ico
32x32x256_ZipSmall.ico
32x32x2_CancelBor.ico
32x32x2_Lamp.ico
32x32x2_OkBor.ico
CButtonST_demo.ico
hand.cur
Release
TransparentCButtonST_demo.exe
CButtonST_demo.exe
cbuttonst26_src.zip
cbuttonst31_demo.zip
CButtonST_Demo.aps
CButtonST_Demo.clw
CButtonST_Demo.dsp
CButtonST_Demo.dsw
CButtonST_Demo.ncb
CButtonST_Demo.opt
CButtonST_Demo.exe
About.ico
Baloon.ico
BmpBack.bmp
Cancel1_32x32x16.ico
Cancel4_32x32x2.ico
Cannibal.bmp
CButtonST_Demo.ico
CDRom.ico
Eagle.bmp
EOapp.ico
Explorer.ico
Face.bmp
Halloween1.ico
Halloween2.ico
Hand.cur
Help.ico
JPEG Image.ico
Key manager.ico
Lamp1.ico
Lamp2.ico
LedOff.ico
LedOn.ico
Left2_32x32x16.ico
LogOff.ico
Ok1_32x32x16.ico
Ok4_32x32x2.ico
Open.ico
Palette.bmp
Right2_32x32x16.ico
Run.ico
Search1.ico
Search2.ico
Sky.bmp
Sound.ico
STLogo_Small.bmp
Tools4.ico
Web2.ico
Winzip1.ico
Winzip2.ico
Workgroup.ico
cbuttonst31_src.zip
CButtonST31_src
cbuttonst32_demo.zip
CButtonST_Demo.aps
CButtonST_Demo.clw
CButtonST_Demo.dsp
CButtonST_Demo.dsw
CButtonST_Demo.opt
CButtonST_Demo.exe
About.ico
Baloon.ico
BmpBack.bmp
Cancel1_32x32x16.ico
Cancel3_32x32x256.ico
Cancel4_32x32x2.ico
Cannibal.bmp
CButtonST_Demo.ico
CDRom.ico
Eagle.bmp
EOapp.ico
Explorer.ico
Face.bmp
Halloween1.ico
Halloween2.ico
Hand.cur
Help.ico
Help2_32x32x256.ico
IEDocument_48x48x256.ico
JPEG Image.ico
Key manager.ico
Lamp1.ico
Lamp2.ico
LedOff.ico
LedOn.ico
Left2_32x32x16.ico
LogOff.ico
Ok1_32x32x16.ico
Ok3_32x32x256.ico
Ok4_32x32x2.ico
Open.ico
Palette.bmp
Razor_32x32x256.ico
Right2_32x32x16.ico
Run.ico
Search1.ico
Search2.ico
Sky.bmp
Sound.ico
STLogo_Small.bmp
Tools4.ico
Web2.ico
Winzip1.ico
Winzip2.ico
Workgroup.ico
cbuttonst32_src.zip
cbuttonst_demo.zip
CButtonST_Demo.clw
CButtonST_Demo.dsp
CButtonST_Demo.dsw
CButtonST_Demo.opt
CButtonST_Demo.exe
About.ico
Baloon.ico
BmpBack.bmp
Butterfly.ico
Button.bmp
Cancel1_32x32x16.ico
Cancel3_32x32x256.ico
Cancel4_32x32x2.ico
Cannibal.bmp
CButtonST_Demo.ico
CDRom.ico
Classes1_32x32x16.ico
EOapp.ico
Explorer.ico
Face.bmp
Halloween1.ico
Halloween2.ico
Hand.cur
Help.ico
Help2_32x32x256.ico
Hover.wav
IEDocument_48x48x256.ico
JPEG Image.ico
Key manager.ico
Lamp1.ico
LedOff.ico
LedOn.ico
Left6_32x32x256.ico
LogOff.ico
No3_32x32x256.ico
Ok3_32x32x256.ico
Open.ico
Razor_32x32x256.ico
Right6_32x32x256.ico
Run.ico
Search1.ico
Sky.bmp
Sound.ico
Start.wav
STLogo_Small.bmp
toolbar.bmp
Tools4.ico
Web2.ico
Winzip1.ico
Workgroup.ico
cbuttonst_src.zip
#include "stdafx.h"
#include "BtnST.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CButtonST

CButtonSTCButtonST()
{
	m_bMouseOnButton = FALSE;

	FreeResources(FALSE);

	// Default type is "flat" button
	m_bIsFlat = TRUE; 
  
	// By default draw border in "flat" button 
	m_bDrawBorder = TRUE; 
  
	// By default icon is aligned horizontally
	m_nAlign = ST_ALIGN_HORIZ; 
  
	// By default show the text button
	m_bShowText = TRUE; 
  
	// By default, for "flat" button, don't draw the focus rect
	m_bDrawFlatFocus = FALSE;

	// By default the button is not the default button
	m_bIsDefault = FALSE;

	// By default the button is not a checkbox
	m_bIsCheckBox = FALSE;
	m_nCheck = 0;

	// Set default colors
	SetDefaultColors(FALSE);

	// No tooltip created
	m_ToolTip.m_hWnd = NULL;

	// Do not draw as a transparent button
	m_bDrawTransparent = FALSE;
	m_pbmpOldBk = NULL;

	// No URL defined
	ZeroMemory(&m_szURL, sizeof(m_szURL));
} // End of CButtonST


CButtonST~CButtonST()
{
	// Restore old bitmap (if any)
	if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
	{
		m_dcBk.SelectObject(m_pbmpOldBk);
	}

	FreeResources();

	// Destroy the cursor (if any)
	if (m_hCursor != NULL) DestroyCursor(m_hCursor);
} // End of ~CButtonST


BEGIN_MESSAGE_MAP(CButtonST, CButton)
    //{{AFX_MSG_MAP(CButtonST)
	ON_WM_CAPTURECHANGED()
	ON_WM_SETCURSOR()
	ON_WM_KILLFOCUS()
	ON_WM_MOUSEMOVE()
	ON_WM_SYSCOLORCHANGE()
	ON_WM_CTLCOLOR_REFLECT()
	ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


DWORD CButtonSTSetIcon(int nIconInId, int nIconOutId)
{
	HICON		hIconIn;
	HICON		hIconOut;
	HINSTANCE	hInstResource;

	// Find correct resource handle
	hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconInId), RT_GROUP_ICON);

	// Set icon when the mouse is IN the button
	hIconIn = (HICON)LoadImage(hInstResource, MAKEINTRESOURCE(nIconInId), IMAGE_ICON, 0, 0, 0);
  	// Set icon when the mouse is OUT the button
	hIconOut = (HICON)LoadImage(hInstResource, MAKEINTRESOURCE(nIconOutId), IMAGE_ICON, 0, 0, 0);

	return SetIcon(hIconIn, hIconOut);
} // End of SetIcon

DWORD CButtonSTSetIcon(HICON hIconIn, HICON hIconOut)
{
	BOOL		bRetValue;
	ICONINFO	ii;

	// Free any loaded resource
	FreeResources();

	if (hIconIn != NULL)
	{
		m_csIcons[0].hIcon = hIconIn;

		// Get icon dimension
		ZeroMemory(&ii, sizeof(ICONINFO));
		bRetValue = GetIconInfo(hIconIn, &ii);
		if (bRetValue == FALSE)
		{
			FreeResources();
			return BTNST_INVALIDRESOURCE;
		} // if

		m_csIcons[0].dwWidth	= (DWORD)(ii.xHotspot * 2);
		m_csIcons[0].dwHeight	= (DWORD)(ii.yHotspot * 2);
		DeleteObject(ii.hbmMask);
		DeleteObject(ii.hbmColor);

		if (hIconOut != NULL)
		{
			m_csIcons[1].hIcon = hIconOut;

			// Get icon dimension
			ZeroMemory(&ii, sizeof(ICONINFO));
			bRetValue = GetIconInfo(hIconOut, &ii);
			if (bRetValue == FALSE)
			{
				FreeResources();
				return BTNST_INVALIDRESOURCE;
			} // if

			m_csIcons[1].dwWidth	= (DWORD)(ii.xHotspot * 2);
			m_csIcons[1].dwHeight	= (DWORD)(ii.yHotspot * 2);
			DeleteObject(ii.hbmMask);
			DeleteObject(ii.hbmColor);
		} // if
	} // if

	RedrawWindow();

	return BTNST_OK;
} // End of SetIcon

BOOL CButtonSTSetBtnCursor(int nCursorId)
{
	HINSTANCE hInstResource;
	// Destroy any previous cursor
	if (m_hCursor != NULL) DestroyCursor(m_hCursor);
	m_hCursor = NULL;

	// If we want a cursor
	if (nCursorId != NULL)
	{
		hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId),
											RT_GROUP_CURSOR);
		// Load icon resource
		m_hCursor = (HCURSOR)LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0);
		// If something wrong then return FALSE
		if (m_hCursor == NULL) return FALSE;
	}

	return TRUE;
} // End of SetBtnCursor


void CButtonSTSetFlat(BOOL bState)
{
	m_bIsFlat = bState;
	Invalidate();
} // End of SetFlat


BOOL CButtonSTGetFlat()
{
	return m_bIsFlat;
} // End of GetFlat


void CButtonSTSetAlign(int nAlign)
{
	switch (nAlign)
	{    
		case ST_ALIGN_HORIZ
		case ST_ALIGN_HORIZ_RIGHT
		case ST_ALIGN_VERT
			m_nAlign = nAlign;
			break;
	}
	Invalidate();
} // End of SetAlign


int CButtonSTGetAlign()
{
	return m_nAlign;
} // End of GetAlign


void CButtonSTDrawBorder(BOOL bEnable)
{
	m_bDrawBorder = bEnable;
} // End of DrawBorder

void CButtonSTSetShowText(BOOL bShow)
{
	m_bShowText = bShow;
	Invalidate();
} // End of SetShowText


BOOL CButtonSTGetShowText()
{
	return m_bShowText;
} // End of GetShowText


void CButtonSTOnMouseMove(UINT nFlags, CPoint point)
{
	CWnd* pWnd;  // Finestra attiva
	CWnd* pParent; // Finestra che contiene il bottone

	CButtonOnMouseMove(nFlags, point);

	// If the mouse enter the button with the left button pressed
	// then do nothing
	if (nFlags & MK_LBUTTON && m_bMouseOnButton == FALSE) return;

	// If our button is not flat then do nothing
	if (m_bIsFlat == FALSE) return;

	pWnd = GetActiveWindow();
	pParent = GetOwner();

	if ((GetCapture() != this) && 
		(
#ifndef ST_LIKEIE
		pWnd != NULL && 
#endif
		pParent != NULL)) 
	{
		m_bMouseOnButton = TRUE;
		//SetFocus();	// Thanks Ralph!
		SetCapture();
		Invalidate();
	}
	else
	{
		/*
		CRect rc;
		GetClientRect(&rc);
		if (!rc.PtInRect(point))
		{
		*/

		POINT p2 = point;
		ClientToScreen(&p2);
		CWnd* wndUnderMouse = WindowFromPoint(p2);
//		if (wndUnderMouse != this)
		if (wndUnderMouse && wndUnderMouse->m_hWnd != this->m_hWnd)
		{
			// Redraw only if mouse goes out
			if (m_bMouseOnButton == TRUE)
			{
				m_bMouseOnButton = FALSE;
				Invalidate();
			}
			// If user is NOT pressing left button then release capture!
			if (!(nFlags & MK_LBUTTON)) ReleaseCapture();
		}
	}
} // End of OnMouseMove


void CButtonSTOnKillFocus(CWnd * pNewWnd)
{
	CButtonOnKillFocus(pNewWnd);

	// If our button is not flat then do nothing
	if (m_bIsFlat == FALSE) return;

	if (m_bMouseOnButton == TRUE)
	{
		m_bMouseOnButton = FALSE;
		Invalidate();
	}
} // End of OnKillFocus


void CButtonSTOnCaptureChanged(CWnd *pWnd) 
{
	if (m_bMouseOnButton == TRUE)
	{
		ReleaseCapture();
		Invalidate();
	}

	// Call base message handler
	CButtonOnCaptureChanged(pWnd);
} // End of OnCaptureChanged


void CButtonSTDrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	CDC* pDC = CDCFromHandle(lpDIS->hDC);

	CPen *pOldPen;
	BOOL	bIsPressed;

	// Checkbox or Radiobutton style ?
	if (m_bIsCheckBox == TRUE)
	{
		bIsPressed  =  (lpDIS->itemState & ODS_SELECTED)
					|| (m_nCheck != 0);
		//bIsPressed = TRUE;
	}
	// Normal button OR other button style ...
	else
	{
		bIsPressed = (lpDIS->itemState & ODS_SELECTED);
	}

//	BOOL bIsPressed  = (lpDIS->itemState & ODS_SELECTED);
	BOOL bIsFocused  = (lpDIS->itemState & ODS_FOCUS);
	BOOL bIsDisabled = (lpDIS->itemState & ODS_DISABLED);

	CRect itemRect = lpDIS->rcItem;

	pDC->SetBkMode(TRANSPARENT);

	if (m_bIsFlat == FALSE)
	{
		if (bIsFocused || (GetDefault() == TRUE))
		{
			CBrush br(RGB(0,0,0));  
			pDC->FrameRect(&itemRect, &br);
			itemRect.DeflateRect(1, 1);
		}
	}

	// Prepare draw... paint button's area with background color
	COLORREF bgColor;
	if ((m_bMouseOnButton == TRUE) || (bIsPressed))
		bgColor = m_crColors[BTNST_COLOR_BK_IN]; //GetActiveBgColor();
	else
		bgColor = m_crColors[BTNST_COLOR_BK_OUT]; //GetInactiveBgColor();

	CBrush br(bgColor);
	// Draw transparent?
	if (m_bDrawTransparent == TRUE)
	{
		PaintBk(pDC);
	}
	else
	{
		pDC->FillRect(&itemRect, &br);
	}

	// Disegno lo sfondo del bottone
	//CBrush br(GetSysColor(COLOR_BTNFACE));  
	//pDC->FillRect(&itemRect, &br);

	// Draw pressed button
	if (bIsPressed)
	{
		if (m_bIsFlat == TRUE)
		{
			if (m_bDrawBorder == TRUE)
			{
				pDC->Draw3dRect(itemRect, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHILIGHT));
			}
		}
		else    
		{
			CBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW));
			pDC->FrameRect(&itemRect, &brBtnShadow);
		}
	}
	else // ...else draw non pressed button
	{
		CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // White
		CPen pen3DLight(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));       // Light gray
		CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));   // Dark gray
		CPen pen3DDKShadow(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW)); // Black

		if (m_bIsFlat == TRUE)
		{
			if (m_bMouseOnButton == TRUE && m_bDrawBorder == TRUE)
			{
				pDC->Draw3dRect(itemRect, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_BTNSHADOW));
			}
		}
		else
		{
			// Disegno i bordi a sinistra e in alto
			// White line
			pOldPen = pDC->SelectObject(&penBtnHiLight);
			pDC->MoveTo(itemRect.left, itemRect.bottom-1);
			pDC->LineTo(itemRect.left, itemRect.top);
			pDC->LineTo(itemRect.right, itemRect.top);
			// Light gray line
			pDC->SelectObject(pen3DLight);
			pDC->MoveTo(itemRect.left+1, itemRect.bottom-1);
			pDC->LineTo(itemRect.left+1, itemRect.top+1);
			pDC->LineTo(itemRect.right, itemRect.top+1);
			// Disegno i bordi a destra e in basso
			// Black line
			pDC->SelectObject(pen3DDKShadow);
			pDC->MoveTo(itemRect.left, itemRect.bottom-1);
			pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
			pDC->LineTo(itemRect.right-1, itemRect.top-1);
			// Dark gray line
			pDC->SelectObject(penBtnShadow);
			pDC->MoveTo(itemRect.left+1, itemRect.bottom-2);
			pDC->LineTo(itemRect.right-2, itemRect.bottom-2);
			pDC->LineTo(itemRect.right-2, itemRect.top);
			//
			pDC->SelectObject(pOldPen);
		}
	}

	// Read the button's title
	CString sTitle;
	GetWindowText(sTitle);

	// If we don't want the title displayed
	if (m_bShowText == FALSE) sTitle.Empty();

	CRect captionRect = lpDIS->rcItem;

	// Draw the icon
	if (m_csIcons[0].hIcon != NULL)
	{
		DrawTheIcon(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, bIsPressed, bIsDisabled);
	}

	if (m_csBitmaps[0].hBitmap != NULL)
	{
		pDC->SetBkColor(RGB(255,255,255));
		DrawTheBitmap(pDC, !sTitle.IsEmpty(), &lpDIS->rcItem, &captionRect, bIsPressed, bIsDisabled);
	} // if

	// Write the button title (if any)
	if (sTitle.IsEmpty() == FALSE)
	{
		// Draw the button's title
		// If button is pressed then "press" title also
		if (bIsPressed && m_bIsCheckBox == FALSE)
			captionRect.OffsetRect(1, 1);
    
		// ONLY FOR DEBUG 
		// Evidenzia il rettangolo in cui verra' centrata la caption 
		//CBrush brBtnShadow(RGB(255, 0, 0));
		//pDC->FrameRect(&captionRect, &brBtnShadow);

		/*
		if ((m_bMouseOnButton == TRUE) || (bIsPressed)) 
		{
			pDC->SetTextColor(GetActiveFgColor());
			pDC->SetBkColor(GetActiveBgColor());
		} 
		else 
		{
			pDC->SetTextColor(GetInactiveFgColor());
			pDC->SetBkColor(GetInactiveBgColor());
		}
		*/
		// Center text
		CRect centerRect = captionRect;
		pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
		captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2);
		/* RFU
		captionRect.OffsetRect(0, (centerRect.Height() - captionRect.Height())/2);
		captionRect.OffsetRect((centerRect.Width() - captionRect.Width())-4, (centerRect.Height() - captionRect.Height())/2);
		*/

		pDC->SetBkMode(TRANSPARENT);
		/*
		pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED  DSS_NORMAL), 
						TRUE, 0, (CBrush*)NULL);
		*/
		if (bIsDisabled)
		{
			captionRect.OffsetRect(1, 1);
			pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
			pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
			captionRect.OffsetRect(-1, -1);
			pDC->SetTextColor(GetSysColor(COLOR_3DSHADOW));
			pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
		}
		else
		{
			if ((m_bMouseOnButton == TRUE) ||(bIsPressed)) 
			{
				pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_IN]);
				pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_IN]);
			} 
			else 
			{
				pDC->SetTextColor(m_crColors[BTNST_COLOR_FG_OUT]);
				pDC->SetBkColor(m_crColors[BTNST_COLOR_BK_OUT]);
			}
			pDC->DrawText(sTitle, -1, captionRect, DT_WORDBREAK | DT_CENTER);
		}
	}

	if (m_bIsFlat == FALSE || (m_bIsFlat == TRUE && m_bDrawFlatFocus == TRUE))
	{
		// Draw the focus rect
		if (bIsFocused)
		{
			CRect focusRect = itemRect;
			focusRect.DeflateRect(3, 3);
			pDC->DrawFocusRect(&focusRect);
		}
	}
} // End of DrawItem

void CButtonSTDrawTheIcon(CDC* pDC, BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, BOOL bIsDisabled)
{
	BYTE		byIndex		= 0;

	// Select the icon to use
	if (m_bIsCheckBox == TRUE)
	{
		if (bIsPressed == TRUE)
		{
			byIndex = 0;
		} // if
		else
		{
			if (m_csIcons[1].hIcon != NULL)
				byIndex = 1;
			else
				byIndex = 0;		// No icon Out available
		} // else
	} // if
	else
	{
		if (m_bMouseOnButton == TRUE || bIsPressed == TRUE)
		{
			byIndex = 0;
		} // if
		else
		{
			if (m_csIcons[1].hIcon != NULL)
				byIndex = 1;
			else
				byIndex = 0;		// No icon Out available
		} // else
	} // else

	CRect	rImage;
	PrepareImageRect(bHasTitle, rpItem, rpTitle, bIsPressed, m_csIcons[byIndex].dwWidth, m_csIcons[byIndex].dwHeight, &rImage);

	// Ole'!
	pDC->DrawState(	rImage.TopLeft(),
					rImage.Size(), 
					m_csIcons[byIndex].hIcon,
					(bIsDisabled ? DSS_DISABLED  DSS_NORMAL), 
					(CBrush*)NULL);
} // End of DrawTheIcon


void CButtonSTPreSubclassWindow() 
{
	UINT nBS;

	nBS = GetButtonStyle();

	// Check if this is the default button
	if (nBS & BS_DEFPUSHBUTTON) m_bIsDefault = TRUE;

	// Check if this is a checkbox
	if (nBS & BS_CHECKBOX) m_bIsCheckBox = TRUE;

	// Add BS_OWNERDRAW style
	SetButtonStyle(nBS | BS_OWNERDRAW);

	CButtonPreSubclassWindow();
} // End of PreSubclassWindow


BOOL CButtonSTPreTranslateMessage(MSG* pMsg) 
{
	InitToolTip();
	m_ToolTip.RelayEvent(pMsg);
	
	return CButtonPreTranslateMessage(pMsg);
} // End of PreTranslateMessage


LRESULT CButtonSTDefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	if (message == WM_LBUTTONDBLCLK)
	{
		message = WM_LBUTTONDOWN;
	}
	return CButtonDefWindowProc(message, wParam, lParam);
} // End of DefWindowProc

void CButtonSTSetFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint)
{
	m_bDrawFlatFocus = bDrawFlatFocus;
	
	// Repaint the button
	if (bRepaint == TRUE) Invalidate();
} // End of SetFlatFocus


BOOL CButtonSTGetFlatFocus()
{
	return m_bDrawFlatFocus;
} // End of GetFlatFocus


BOOL CButtonSTOnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// If a cursor was specified then use it!
	if (m_hCursor != NULL)
	{
		SetCursor(m_hCursor);
		return TRUE;
	}

	return CButtonOnSetCursor(pWnd, nHitTest, message);
} // End of OnSetCursor


void CButtonSTSetTooltipText(CString* spText, BOOL bActivate)
{
	// We cannot accept NULL pointer
	if (spText == NULL) return;

	// Initialize ToolTip
	InitToolTip();

	// If there is no tooltip defined then add it
	if (m_ToolTip.GetToolCount() == 0)
	{
		CRect rectBtn; 
		GetClientRect(rectBtn);
		m_ToolTip.AddTool(this, (LPCTSTR)*spText, rectBtn, 1);
	}

	// Set text for tooltip
	m_ToolTip.UpdateTipText((LPCTSTR)*spText, this, 1);
	m_ToolTip.Activate(bActivate);
} // End of SetTooltipText


void CButtonSTSetTooltipText(int nId, BOOL bActivate)
{
	CString sText;

	// load string resource
	sText.LoadString(nId);
	// If string resource is not empty
	if (sText.IsEmpty() == FALSE) SetTooltipText(&sText, bActivate);
} // End of SetTooltipText


void CButtonSTActivateTooltip(BOOL bActivate)
{
	// If there is no tooltip then do nothing
	if (m_ToolTip.GetToolCount() == 0) return;

	// Activate tooltip
	m_ToolTip.Activate(bActivate);
} // End of EnableTooltip


BOOL CButtonSTGetDefault()
{
	return m_bIsDefault;
} // End of GetDefault


void CButtonSTDrawTransparent(BOOL bRepaint)
{
	m_bDrawTransparent = TRUE;

	// Restore old bitmap (if any)
	if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
	{
		m_dcBk.SelectObject(m_pbmpOldBk);
	} // if

	m_bmpBk.DeleteObject();
	m_dcBk.DeleteDC();

	// Repaint the button
	if (bRepaint == TRUE) Invalidate();
} // End of DrawTransparent


void CButtonSTInitToolTip()
{
	if (m_ToolTip.m_hWnd == NULL)
	{
		// Create ToolTip control
		m_ToolTip.Create(this);
		// Create inactive
		m_ToolTip.Activate(FALSE);
	} // if
} // End of InitToolTip


void CButtonSTPaintBk(CDC* pDC)
{
	CClientDC clDC(GetParent());
	CRect rect;
	CRect rect1;

	GetClientRect(rect);

	GetWindowRect(rect1);
	GetParent()->ScreenToClient(rect1);

	if (m_dcBk.m_hDC == NULL)
	{
		m_dcBk.CreateCompatibleDC(&clDC);
		m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
		m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
		m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
	} // if

	pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
} // End of PaintBk


HBRUSH CButtonSTCtlColor(CDC* pDC, UINT nCtlColor) 
{
	return (HBRUSH)GetStockObject(NULL_BRUSH); 
} // End of CtlColor


void CButtonSTOnSysColorChange() 
{
	CButtonOnSysColorChange();

	m_dcBk.DeleteDC();
	m_bmpBk.DeleteObject();	
} // End of OnSysColorChange

BOOL CButtonSTOnClicked() 
{	
	if (m_bIsCheckBox == TRUE)
	{
		m_nCheck = !m_nCheck;
		Invalidate();
	} // if
	else
	{
		// Handle the URL (if any)
		if (lstrlen(m_szURL) > 0)
			ShellExecute(NULL, _T("open"), m_szURL, NULL,NULL, SW_SHOWMAXIMIZED);
	} // else

	return FALSE;
} // End of OnClicked

void CButtonSTSetCheck(int nCheck, BOOL bRepaint)
{
	if (m_bIsCheckBox == TRUE)
	{
		if (nCheck == 0) m_nCheck = 0;
		else m_nCheck = 1;

		if (bRepaint == TRUE) Invalidate();
	} // if
} // End of SetCheck

int CButtonSTGetCheck()
{
	return m_nCheck;
} // End of GetCheck

void CButtonSTFreeResources(BOOL bCheckForNULL)
{
	if (bCheckForNULL == TRUE)
	{
		// Destroy icons
		// Note the following two lines MUST be here! even if
		// BoundChecker says they are unnecessary!
		if (m_csIcons[0].hIcon != NULL)	DeleteObject(m_csIcons[0].hIcon);
		if (m_csIcons[1].hIcon != NULL)	DeleteObject(m_csIcons[1].hIcon);

		// Destroy bitmaps
		if (m_csBitmaps[0].hBitmap != NULL)	DeleteObject(m_csBitmaps[0].hBitmap);
		if (m_csBitmaps[1].hBitmap != NULL)	DeleteObject(m_csBitmaps[1].hBitmap);

		// Destroy mask bitmaps
		if (m_csBitmaps[0].hMask != NULL)	DeleteObject(m_csBitmaps[0].hMask);
		if (m_csBitmaps[1].hMask != NULL)	DeleteObject(m_csBitmaps[1].hMask);
	} // if

	ZeroMemory(&m_csIcons, sizeof(m_csIcons));
	ZeroMemory(&m_csBitmaps, sizeof(m_csBitmaps));
} // End of FreeResources

DWORD CButtonSTSetBitmaps(HBITMAP hBitmapIn, COLORREF crTransColorIn, HBITMAP hBitmapOut, COLORREF crTransColorOut)
{
	int		nRetValue;
	BITMAP	csBitmapSize;

	// Free any loaded resource
	FreeResources();

	if (hBitmapIn != NULL)
	{
		m_csBitmaps[0].hBitmap = hBitmapIn;
		m_csBitmaps[0].crTransparent = crTransColorIn;
		// Get bitmap size
		nRetValue = GetObject(hBitmapIn, sizeof(csBitmapSize), &csBitmapSize);
		if (nRetValue == 0)
		{
			FreeResources();
			return BTNST_INVALIDRESOURCE;
		} // if
		m_csBitmaps[0].dwWidth = (DWORD)csBitmapSize.bmWidth;
		m_csBitmaps[0].dwHeight = (DWORD)csBitmapSize.bmHeight;

		// Create mask for bitmap In
		m_csBitmaps[0].hMask = CreateBitmapMask(hBitmapIn, m_csBitmaps[0].dwWidth, m_csBitmaps[0].dwHeight, crTransColorIn);
		if (m_csBitmaps[0].hMask == NULL)
		{
			FreeResources();
			return BTNST_FAILEDMASK;
		} // if

		if (hBitmapOut != NULL)
		{
			m_csBitmaps[1].hBitmap = hBitmapOut;
			m_csBitmaps[1].crTransparent = crTransColorOut;
			// Get bitmap size
			nRetValue = GetObject(hBitmapOut, sizeof(csBitmapSize), &csBitmapSize);
			if (nRetValue == 0)
			{
				FreeResources();
				return BTNST_INVALIDRESOURCE;
			} // if
			m_csBitmaps[1].dwWidth = (DWORD)csBitmapSize.bmWidth;
			m_csBitmaps[1].dwHeight = (DWORD)csBitmapSize.bmHeight;

			// Create mask for bitmap Out
			m_csBitmaps[1].hMask = CreateBitmapMask(hBitmapOut, m_csBitmaps[1].dwWidth, m_csBitmaps[1].dwHeight, crTransColorOut);
			if (m_csBitmaps[1].hMask == NULL)
			{
				FreeResources();
				return BTNST_FAILEDMASK;
			} // if
		} // if
	} // if

	RedrawWindow();

	return BTNST_OK;
} // End of SetBitmaps

DWORD CButtonSTSetBitmaps(int nBitmapIn, COLORREF crTransColorIn, int nBitmapOut, COLORREF crTransColorOut)
{
	HBITMAP		hBitmapIn	= NULL;
	HBITMAP		hBitmapOut	= NULL;
	HINSTANCE hInstResource	= NULL;
	
	// Find correct resource handle
	hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmapIn), RT_BITMAP);

	// Load bitmap In
	hBitmapIn = (HBITMAP)LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapIn), IMAGE_BITMAP, 0, 0, 0);

	// Load bitmap Out
	hBitmapOut = (HBITMAP)LoadImage(hInstResource, MAKEINTRESOURCE(nBitmapOut), IMAGE_BITMAP, 0, 0, 0);

	return SetBitmaps(hBitmapIn, crTransColorIn, hBitmapOut, crTransColorOut);
} // End of SetBitmaps

void CButtonSTDrawTheBitmap(CDC* pDC, BOOL bHasTitle, RECT* rItem, CRect *rCaption, BOOL bIsPressed, BOOL bIsDisabled)
{
	HDC			hdcBmpMem	= NULL;
	HBITMAP		hbmOldBmp	= NULL;
	HDC			hdcMem		= NULL;
	HBITMAP		hbmT		= NULL;

	BYTE		byIndex		= 0;

	// Select the bitmap to use
	if (m_bIsCheckBox == TRUE)
	{
		if (bIsPressed == TRUE)
		{
			byIndex = 0;
		} // if
		else
		{
			if (m_csBitmaps[1].hBitmap != NULL)
				byIndex = 1;
			else
				byIndex = 0;		// No bitmap Out available
		} // else
	} // if
	else
	{
		if (m_bMouseOnButton == TRUE || bIsPressed == TRUE)
		{
			byIndex = 0;
		} // if
		else
		{
			if (m_csBitmaps[1].hBitmap != NULL)
				byIndex = 1;
			else
				byIndex = 0;		// No bitmap Out available
		} // else
	} // else

	CRect	rImage;
	PrepareImageRect(bHasTitle, rItem, rCaption, bIsPressed, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, &rImage);

	hdcBmpMem = CreateCompatibleDC(pDC->m_hDC);

	hbmOldBmp = (HBITMAP)SelectObject(hdcBmpMem, m_csBitmaps[byIndex].hBitmap);

	hdcMem = CreateCompatibleDC(NULL);

	hbmT = (HBITMAP)SelectObject(hdcMem, m_csBitmaps[byIndex].hMask);

	BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);

	BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);

	SelectObject(hdcMem, hbmT);
	DeleteDC(hdcMem);

	SelectObject(hdcBmpMem, hbmOldBmp);
	DeleteDC(hdcBmpMem);
} // End of DrawTheBitmap

HBITMAP CButtonSTCreateBitmapMask(HBITMAP hSourceBitmap, DWORD dwWidth, DWORD dwHeight, COLORREF crTransColor)
{
	HBITMAP		hMask		= NULL;
	HDC			hdcSrc		= NULL;
	HDC			hdcDest		= NULL;
	HBITMAP		hbmSrcT		= NULL;
	HBITMAP		hbmDestT	= NULL;
	COLORREF	crSaveBk;
	COLORREF	crSaveDestText;

	hMask = CreateBitmap(dwWidth, dwHeight, 1, 1, NULL);
	if (hMask == NULL)	return NULL;

	hdcSrc	= CreateCompatibleDC(NULL);
	hdcDest	= CreateCompatibleDC(NULL);

	hbmSrcT = (HBITMAP)SelectObject(hdcSrc, hSourceBitmap);
	hbmDestT = (HBITMAP)SelectObject(hdcDest, hMask);

	crSaveBk = SetBkColor(hdcSrc, crTransColor);

	BitBlt(hdcDest, 0, 0, dwWidth, dwHeight, hdcSrc, 0, 0, SRCCOPY);

	crSaveDestText = SetTextColor(hdcSrc, RGB(255, 255, 255));
	SetBkColor(hdcSrc,RGB(0, 0, 0));

	BitBlt(hdcSrc, 0, 0, dwWidth, dwHeight, hdcDest, 0, 0, SRCAND);

	SetTextColor(hdcDest, crSaveDestText);

	SetBkColor(hdcSrc, crSaveBk);
	SelectObject(hdcSrc, hbmSrcT);
	SelectObject(hdcDest, hbmDestT);

	DeleteDC(hdcSrc);
	DeleteDC(hdcDest);

	return hMask;
} // End of CreateBitmapMask

//
// Parameters
//		[IN]	bHasTitle
//				TRUE if the button has a text
//		[IN]	rpItem
//				A pointer to a RECT structure indicating the allowed paint area
//		[IN/OUT]rpTitle
//				A pointer to a CRect object indicating the paint area reserved for the
//				text. This structure will be modified if necessary.
//		[IN]	bIsPressed
//				TRUE if the button is currently pressed
//		[IN]	dwWidth
//				Width of the image (icon or bitmap)
//		[IN]	dwHeight
//				Height of the image (icon or bitmap)
//		[OUT]	rpImage
//				A pointer to a CRect object that will receive the area available to the image
//
void CButtonSTPrepareImageRect(BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, CRect* rpImage)
{
	CRect rBtn;

	rpImage->CopyRect(rpItem);

	switch (m_nAlign)
	{
		case ST_ALIGN_HORIZ
			if (bHasTitle == FALSE /*spTitle->IsEmpty()*/)
			{
				// Center image horizontally
				rpImage->left += ((rpImage->Width() - dwWidth)/2);
			}
			else
			{
				// Image must be placed just inside the focus rect
				rpImage->left += 3;  
				rpTitle->left += dwWidth + 3;
			}
			// Center image vertically
			rpImage->top += ((rpImage->Height() - dwHeight)/2);
			break;

		case ST_ALIGN_HORIZ_RIGHT
			GetClientRect(&rBtn);
			if (bHasTitle == FALSE /*spTitle->IsEmpty()*/)
			{
				// Center image horizontally
				rpImage->left += ((rpImage->Width() - dwWidth)/2);
			}
			else
			{
				// Image must be placed just inside the focus rect
				rpTitle->right = rpTitle->Width() - dwWidth - 3;
				rpTitle->left = 3;
				rpImage->left = rBtn.right - dwWidth - 3;
				// Center image vertically
				rpImage->top += ((rpImage->Height() - dwHeight)/2);
			}
			break;
		
		case ST_ALIGN_VERT
			// Center image horizontally
			rpImage->left += ((rpImage->Width() - dwWidth)/2);
			if (bHasTitle == FALSE /*spTitle->IsEmpty()*/)
			{
				// Center image vertically
				rpImage->top += ((rpImage->Height() - dwHeight)/2);           
			}
			else
			{
				rpTitle->top += dwHeight;
			}
			break;
	}
    
	// If button is pressed then press image also
	if (bIsPressed == TRUE && m_bIsCheckBox == FALSE)
		rpImage->OffsetRect(1, 1);
} // End of PrepareImageRect

//
// Parameters
//		[IN]	bRepaint
//				If TRUE the control will be repainted.
// Return value
//		BTNST_OK
//			Function executed successfully.
//
DWORD CButtonSTSetDefaultColors(BOOL bRepaint)
{
	m_crColors[BTNST_COLOR_BK_IN]	= GetSysColor(COLOR_BTNFACE);
	m_crColors[BTNST_COLOR_FG_IN]	= GetSysColor(COLOR_BTNTEXT);
	m_crColors[BTNST_COLOR_BK_OUT]	= GetSysColor(COLOR_BTNFACE);
	m_crColors[BTNST_COLOR_FG_OUT]	= GetSysColor(COLOR_BTNTEXT);

	if (bRepaint == TRUE)	Invalidate();

	return BTNST_OK;
} // End of SetDefaultColors

//
// Parameters
//		[IN]	byColorIndex
//				Index of the color to set. This index is zero-based.
//		[IN]	crColor
//				New color.
//		[IN]	bRepaint
//				If TRUE the control will be repainted.
//
// Return value
//		BTNST_OK
//			Function executed successfully.
//		BTNST_INVALIDINDEX
//			Invalid color index.
//
DWORD CButtonSTSetColor(BYTE byColorIndex, COLORREF crColor, BOOL bRepaint)
{
	if (byColorIndex >= BTNST_MAX_COLORS)	return BTNST_INVALIDINDEX;

	// Set new color
	m_crColors[byColorIndex] = crColor;

	if (bRepaint == TRUE)	Invalidate();

	return BTNST_OK;
} // End of SetColor

//
// Parameters
//		[IN]	byColorIndex
//				Index of the color to get. This index is zero-based.
//		[OUT]	crpColor
//				A pointer to a COLORREF that will receive the color.
//
// Return value
//		BTNST_OK
//			Function executed successfully.
//		BTNST_INVALIDINDEX
//			Invalid color index.
//
DWORD CButtonSTGetColor(BYTE byColorIndex, COLORREF* crpColor)
{
	if (byColorIndex >= BTNST_MAX_COLORS)	return BTNST_INVALIDINDEX;

	// Get color
	*crpColor = m_crColors[byColorIndex];

	return BTNST_OK;
} // End of GetColor

//
// Parameters
//		[IN]	lpszURL
//				Pointer to a null-terminated string that contains the URL.
//
// Return value
//		BTNST_OK
//			Function executed successfully.
//
DWORD CButtonSTSetURL(LPCTSTR lpszURL)
{
	if (lpszURL != NULL)
	{
		// Store the URL
		lstrcpyn(m_szURL, lpszURL, _MAX_PATH);
	} // if
	else
	{
		// Remove any existing URL
		ZeroMemory(&m_szURL, sizeof(m_szURL));
	} // else

	return BTNST_OK;
} // End of SetURL

#undef ST_LIKEIE

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Davide Calabro
Web Developer
Italy Italy
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150520.1 | Last Updated 29 Mar 2003
Article Copyright 1999 by Davide Calabro
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid