Flat owner drawn buttons

I have some code for Owner Drawn Button, Which makes the button look flat. and when the mouse cursor, goes over it, the text will become bold and the button with the focus will have underline on the text..And when you click on it, then also it becomes bold. I have upgraded this to accept bitmaps. Use SetBitmap (UINT ID) function to have the bitmap on the button. The bitmap is drawn in monochrome when it does not have focus and will change to its original colors when a mouse comes over it or when you click on it. It represents having the focus by being in color.
********************************************************************************

// BtnMenu.cpp : implementation file
//

#include "stdafx.h"
#include "BtnMenu.h"

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

/////////////////////////////////////////////////////////////////////////////
// CBtnMenu

CBtnMenu::CBtnMenu()
{
	m_clrText =  GetSysColor (COLOR_BTNTEXT);
	m_clrBack = GetSysColor (COLOR_BTNFACE);
	m_brBackground.CreateSolidBrush (m_clrBack);
	m_crText = m_clrText;
	m_bLBtnDown = FALSE;
	m_idCursor = 0;
	m_idBitmap = 0;
}

CBtnMenu::~CBtnMenu()
{
	if ((HBRUSH) m_brBackground != NULL)
		m_brBackground.DeleteObject ();
}


BEGIN_MESSAGE_MAP(CBtnMenu, CButton)
//{{AFX_MSG_MAP(CBtnMenu)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBtnMenu message handlers

HBRUSH CBtnMenu::CtlColor(CDC* pDC, UINT nCtlColor) 
{
	// TODO: Change any attributes of the DC here
	// TODO: Return a non-NULL brush if the parent's handler should not be called
	return NULL;
}

void CBtnMenu::OnMouseMove(UINT nFlags, CPoint point)
{
	//Here I will set a timer and see if the current cursor is within our boundaries if
	// not kill the timer and remove the current highlighting
	SetTimer (1,55,NULL);
	CButton::OnMouseMove(nFlags, point);
}


void CBtnMenu::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bLBtnDown= TRUE;
	CButton::OnLButtonDown(nFlags, point);
}

void CBtnMenu::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bLBtnDown= FALSE;
	//Take out the cursor 
	CButton::OnLButtonUp(nFlags, point);
}

void CBtnMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS) 
{
	ASSERT(lpDIS != NULL);
	
	CDC* pDC = CDC::FromHandle(lpDIS->hDC);
	CRect rect;
	HBITMAP hBitmap =NULL;
	
    // draw the colored rectangle portion
	rect.CopyRect(&lpDIS->rcItem);
	
    // draw the up/down/focused/disabled state
	
	UINT state = lpDIS->itemState;
    if ( (state & ODS_SELECTED) )
    {
        // draw the down edges
		
		CBrush *pOldBrush = pDC->SelectObject(&m_brBackground);
		pDC->RoundRect(rect.left, rect.top, rect.Width(), rect.Height(), 2, 2);
		pDC->SelectObject(pOldBrush);

		if (m_idBitmap)
			hBitmap = (HBITMAP) LoadImage (AfxGetInstanceHandle (),MAKEINTRESOURCE (m_idBitmap),
			IMAGE_BITMAP,0,0,LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS|LR_LOADTRANSPARENT); 
 
		
		pDC->Draw3dRect (rect,GetSysColor (COLOR_3DDKSHADOW),GetSysColor (COLOR_3DHILIGHT));
    }
    else
    {
		
		CBrush *pOldBrush = pDC->SelectObject(&m_brBackground);
		pDC->RoundRect(rect.left, rect.top, rect.Width(), rect.Height(), 2, 2);
		pDC->SelectObject(pOldBrush);
		if (m_idBitmap)
			hBitmap = 	(HBITMAP) LoadImage (AfxGetInstanceHandle (),MAKEINTRESOURCE (m_idBitmap),
					IMAGE_BITMAP,0,0,LR_MONOCHROME|LR_LOADMAP3DCOLORS); 
		
        // draw the up edges
		pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
    }
	
    // draw the text if there is any
	//We have to paint the text only if the image is nonexistant
	CString strText;
	GetWindowText(strText);
	if ( !strText.IsEmpty())
	{
		LOGFONT lf;
		ZeroMemory ((PVOID) &lf,sizeof (LOGFONT));
		CFont * pFont = GetFont();
		
		CFont dispFont;
		
		pFont->GetLogFont (&lf);
		
		if ((state & ODS_SELECTED))
		{
			lf.lfWeight = FW_EXTRABOLD;
			dispFont.CreateFontIndirect (&lf);
			pFont = pDC->SelectObject (&dispFont);
			
			//While selected move the text a bit
			rect.top +=2;
			rect.left +=2;
			rect.right -=2;
			rect.bottom -=2;
			
		}
		
		int         iOldMode = pDC->GetBkMode();
		COLORREF    crOldText = pDC->GetTextColor();
		
		pDC->SetBkMode( TRANSPARENT );
		pDC->SetTextColor( m_crText );
		
		if (state & ODS_FOCUS )
		{
			if (!(state & ODS_SELECTED))
			{
				lf.lfUnderline = TRUE;
				lf.lfWeight = FW_LIGHT;
				dispFont.CreateFontIndirect (&lf);
				pFont = pDC->SelectObject (&dispFont);
				if (m_idBitmap)
					hBitmap =(HBITMAP) LoadImage (AfxGetInstanceHandle (),MAKEINTRESOURCE (m_idBitmap),
					IMAGE_BITMAP,0,0,LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS|LR_LOADTRANSPARENT); 
			}
		}

		if (state & ODS_DISABLED)
		{
			CBrush grayBrush;
			grayBrush.CreateSolidBrush (GetSysColor (COLOR_GRAYTEXT));
			pDC->GrayString (&grayBrush,NULL,(LPARAM)((LPCSTR)strText),-1,rect.left, rect.top,rect.Width(),rect.Height());
		}
		else
		{
			if (!hBitmap)
				pDC->DrawText(strText, rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
			else
			{
				CDC memdc;
				CBitmap bmp;
				CBitmap *poldbmp;
				bmp.Attach (hBitmap);
				BITMAP bitmap;
				bmp.GetBitmap (&bitmap);

				memdc.CreateCompatibleDC( pDC );
				// Select the bitmap into the DC
				poldbmp = memdc.SelectObject( &bmp);
				// Copy (BitBlt) bitmap from memory DC to screen DC
				pDC -> StretchBlt( rect.left,rect.top,
					rect.right-rect.left, rect.bottom -rect.top, &memdc, 0,0, bitmap.bmWidth,bitmap.bmHeight,SRCCOPY );
				memdc.SelectObject( poldbmp );
				bmp.Detach ();
			}
			
		}
		
		pDC->SetBkMode( iOldMode );
		pDC->SetTextColor( crOldText );
		
		pDC->SelectObject (pFont); //set it to the old font
		dispFont.DeleteObject ();
	}
	
	
	if ( (state & ODS_DISABLED) )
    {
        //AST - how should we indicate this???
    }
}


void CBtnMenu::OnTimer(UINT nIDEvent) 
{
	POINT pt;
	static BOOL pPainted = FALSE;

	GetCursorPos(&pt);
	CRect rect;
	GetWindowRect (rect);

	if (m_bLBtnDown)
	{
		KillTimer (1);
		//Take the cursor out if the man has pressed de button
		if (m_idCursor)
		{
			::SetCursor (AfxGetApp () -> LoadStandardCursor (IDC_ARROW));
		}

		if (pPainted)
			InvalidateRect (NULL);

		pPainted = FALSE;
		return;
	}

	if (!rect.PtInRect (pt))
	{
		KillTimer (1);
		//Take out the cursor if the thing is out
		if (m_idCursor)
		{
			::SetCursor (AfxGetApp () -> LoadStandardCursor (IDC_ARROW));
		}

		if (pPainted)
			InvalidateRect (NULL);
		pPainted = FALSE;
		return;
	}
	else
	{

		if (pPainted)
			return;
		else
			pPainted = TRUE;

		//Here we need to put the cursor in for the settings
		if (m_idCursor)
		{
			HCURSOR hCursor = AfxGetApp () -> LoadCursor (m_idCursor);
			::SetCursor (hCursor);
		}


		CDC *pDC = GetDC ();

		if (!m_idBitmap)
		{
			LOGFONT lf;
			ZeroMemory ((PVOID) &lf,sizeof (LOGFONT));
			CFont * pFont = GetFont();
			
			CFont dispFont;
			pFont->GetLogFont (&lf);
			lf.lfUnderline = TRUE;
			lf.lfWeight = FW_BOLD;
			
			int         iOldMode = pDC->GetBkMode();
			COLORREF    crOldText = pDC->GetTextColor();
			
			dispFont.CreateFontIndirect (&lf);
			
			pDC->SetBkMode( TRANSPARENT );
			pDC->SetTextColor( m_crText);
			
			pDC -> SelectObject (dispFont);
			
			CString strText;
			GetWindowText (strText);
			
			CRect rect;
			GetClientRect (rect);
			pDC->FillSolidRect (rect,m_clrBack);
			
			pDC->DrawText(strText, rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
			
			pDC->SetBkMode( iOldMode );
			pDC->SetTextColor( crOldText );
			
			pDC->SelectObject (pFont); //set it to the old font
			dispFont.DeleteObject ();
		}
		else
		{
			HBITMAP hBitmap =(HBITMAP) LoadImage (AfxGetInstanceHandle (),MAKEINTRESOURCE (m_idBitmap),
				IMAGE_BITMAP,0,0,LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS|LR_LOADTRANSPARENT); 
			
			GetClientRect (rect);
			CDC memdc;
			CBitmap bmp;
			CBitmap *poldbmp;
			bmp.Attach (hBitmap);
			BITMAP bitmap;
			bmp.GetBitmap (&bitmap);
			memdc.CreateCompatibleDC( pDC );
			// Select the bitmap into the DC
			poldbmp = (CBitmap *) memdc.SelectObject( &bmp );
			// Copy (BitBlt) bitmap from memory DC to screen DC
			pDC -> StretchBlt( rect.left,rect.top,
				rect.right-rect.left, rect.bottom -rect.top, &memdc, 0,0,bitmap.bmWidth,bitmap.bmHeight, SRCCOPY );
			memdc.SelectObject( poldbmp );

		}
		ReleaseDC (pDC);
	}
	
	CButton::OnTimer(nIDEvent);
}

void CBtnMenu::SetBkgndColor (COLORREF rgb)
{
	m_clrBack = rgb;
	if ((HBRUSH)m_brBackground != NULL)
		m_brBackground.DeleteObject();
	m_brBackground.CreateSolidBrush (m_clrBack);
}

void CBtnMenu::SetTextColor (COLORREF rgb)
{
	m_clrText = rgb;
	m_crText = m_clrText;
}


void CBtnMenu::SetCursor(UINT idCursor)
{
	m_idCursor = idCursor;
}

void CBtnMenu::SetBitmap (UINT idBmp)
{
	m_idBitmap = idBmp;
}

****************************************************************************************

// BtnMenu.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CBtnMenu window
#ifndef _BTNMENU_H
#define _BTNMENU_H

class CBtnMenu : public CButton
{
	
// Construction

	public:
	BOOL m_bLBtnDown;
	CBrush m_brBackground;
	COLORREF m_crText;
	CBtnMenu();
	void SetBkgndColor (COLORREF rgb);
	void SetTextColor (COLORREF rgb);
	void SetBitmap (UINT);
	
	// Attributes

	public:
	
	// Operations

	public:
	
	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CBtnMenu)
	public:
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	//}}AFX_VIRTUAL
	
	// Implementation

	protected:

		COLORREF m_clrBack;
		COLORREF m_clrText;
		UINT m_idBitmap;


	public:
		UINT m_idCursor;
		void SetCursor (UINT idCursor);
	virtual ~CBtnMenu();
	
	// Generated message map functions

	protected:
	//{{AFX_MSG(CBtnMenu)
	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnTimer(UINT nIDEvent);
	//}}AFX_MSG
	
	DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
#endif //_BTNMENU_H





Comments

  • terrell suggs jersey

    Posted by Jimmyby2fb on 11/02/2012 11:23pm

    seywg champ bailey jersey gajdu peyton manning jersey rwesc larry fitzgerald jersey rjcnf legarrette blount jersey htlgu aldon smith jersey

    Reply
  • where the fucking code idiot

    Posted by Legacy on 03/26/2003 12:00am

    Originally posted by: sss

    where the fucking code idiot

    Reply
  • Plz Help me

    Posted by Legacy on 07/28/2002 12:00am

    Originally posted by: Anjum Ali

    Dear Friend,

    I have add ur code (c++ and header files)
    in my project but i am unable to display a flate
    button plz tell me the simplest way that i can display
    this flate button.

    I want to use this button in Dialog, but i didnt see
    it in the control box.
    Plz write a little routine so that i can implement is
    .

    Thanks in advance

    Anjum Ali

    Reply
  • abc

    Posted by Legacy on 11/04/2001 12:00am

    Originally posted by: thanh phuc

    I want to get the demo project using it
    Thanks

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • When it comes to desktops – physical or virtual – it's all about the applications. Cloud-hosted virtual desktops are growing fast because you get local data center-class security and 24x7 access with the complete personalization and flexibility of your own desktop. Organizations make five common mistakes when it comes to planning and implementing their application management strategy. This eBook tells you what they are and how to avoid them, and offers real-life case studies on customers who didn't …

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds