CButton 按钮类的重写

<p>//头文件 
//CGWBButton.h</p><pre name="code" class="cpp">
 
#if !defined(AFX_WBBUTTON_H__518122CF_358F_11D4_8F4F_00402656D980__INCLUDED_)
#define AFX_WBBUTTON_H__518122CF_358F_11D4_8F4F_00402656D980__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CAutoFont;
#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }

class CGWBButton : public CButton
{
	typedef enum mode
	{
		NORMAL ,
		HOVER ,
		DOWN ,
		DISABLE 
	}stateBtn;

	enum state
	{
		notInited    = 0,
		FileLoaded   = 1,
		BitmapInited = 2
	};

public:
	CGWBButton();
	/*
	功能:为按钮加载背景图片,支持透明,各个状态的图标在一张图上
	参数:strPath本地图片路径,
		count图片中包含的图标的个数,
		nWidth每个图标的宽度,
		nHeight每个图标的高度,
		bSizeChange是否改变图标大小适应控件
	*/
	bool LoadImg( CString strPath,int count,int nWidth,int nHeight,int nInterval,BOOL bMouseMove = FALSE,bool bSizeChange = true);
	/*
	功能:为按钮加载背景图片,支持透明,各个状态的图标不在一张图上
	参数:strPath本地图片Normal状态路径,
		strPath本地图片Normal状态路径,
		strPath本地图片Normal状态路径,
		strPath本地图片Normal状态路径,
		bSizeChange是否改变图标大小适应控件
	*/
	bool LoadImg(CString strNormal,CString strHover,CString strDown,CString strDisable,BOOL bMouseMove = FALSE,bool bSizeChange = true);
	void SetButtonDef( int TopHeight, int BottomHeight, int LeftWidth, int RightWidth );
	void SetBackColor( COLORREF color ) { m_BkColor = color; }
	COLORREF GetBackColor() { return m_BkColor; }
	void SetTextFont( CFont & fnt );
	void SetTextFont( CAutoFont & fnt );
	CFont * GetTextFont() { return (CFont *)m_pFnt; }
	CAutoFont * GetTextAutoFont() { return m_pFnt; }
	void SetFontColor( COLORREF color );
	void SetBackImage(CString strPath);//设置背景图片

	virtual ~CGWBButton();
protected:
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	DECLARE_MESSAGE_MAP()
private:
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
private: 
	int m_State;
	stateBtn m_state;
	void DrawBitmap( CDC * pDC, int mode );

	UINT m_RcId;       // Resource ID
	int  m_NumofPics;  

	Bitmap*		m_pNormalBitmap;
	Bitmap*		m_pHoverBitmap;
	Bitmap*		m_pDownBitmap;
	Bitmap*		m_pDisableBitmap;
	Bitmap*		m_pBackImage;
	bool		m_bBackImage;

	int m_TopHeight; //= 8;
	int m_BottomHeight; //= 8;
	int m_LeftWidth; //= 8;
	int m_RightWidth;// = 17;
	bool m_bMouseOver;
	bool m_bEnabled;

	int m_dwWidth;
	int m_dwHeight;
	BOOL		m_bDCStored;
	CDC			m_memDC;
	bool		m_bSizeChange;
	COLORREF	m_BkColor;
	CAutoFont * m_pFnt;
	BOOL	m_bTracking ;//是否追踪鼠标状态
	BOOL	m_bMouseMove;
public:
	afx_msg void OnMouseLeave();
};

#ifndef _MEMDC_H_
#define _MEMDC_H_

//
// CMemDCWB - memory DC
//
// Author: Keith Rule
// Email:  keithr@europa.com
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// This class implements a memory Device Context

class CMemDCWB : public CDC {
private:
	CBitmap*	m_bitmap;
	CBitmap*	m_oldBitmap;
	CDC*		m_pDC;
	CRect		m_rcBounds;
public:
	CMemDCWB(CDC* pDC, const CRect& rcBounds) : CDC()
	{
		CreateCompatibleDC(pDC);
		m_bitmap = new CBitmap;
		m_bitmap->CreateCompatibleBitmap(pDC, rcBounds.Width(), rcBounds.Height());
		m_oldBitmap = SelectObject(m_bitmap);
		m_pDC = pDC;
		m_rcBounds = rcBounds;
		//For some reason the background color is not correct,
		//so we use the button face color.
		DWORD	color = ::GetSysColor( COLOR_BTNFACE );
		CBrush bkg(color);
		FillRect(rcBounds, &bkg);

	}
	~CMemDCWB() 
	{
		m_pDC->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(), 
			this, m_rcBounds.left, m_rcBounds.top, SRCCOPY);
		SelectObject(m_oldBitmap);
		if (m_bitmap != NULL) delete m_bitmap;
	}
	CMemDCWB* operator->() {
		return this;
	}
};

#endif

/

#endif // !defined(AFX_WBBUTTON_H__518122CF_358F_11D4_8F4F_00402656D980__INCLUDED_)

 

//源文件CGWButton.cpp

 

#include "stdafx.h"
#include "GWBButton.h"
#include "AutoFont.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CGWBButton::CGWBButton()
{
	m_TopHeight = 8;
	m_BottomHeight = 8;
	m_LeftWidth = 8;
	m_RightWidth = 17;
	m_State = notInited;
	m_pFnt = new CAutoFont(_T("MS Sans Serif"));
	m_BkColor = RGB(255,0,255);

	m_RcId       = 0;       // Resource ID
	m_NumofPics  = 0;  
	m_bDCStored = FALSE;

	m_pNormalBitmap = NULL;
	m_pHoverBitmap = NULL;
	m_pDownBitmap = NULL;
	m_pDisableBitmap = NULL;
	m_bMouseOver = false;
	m_bEnabled = true;
	m_bTracking = FALSE;

	m_pBackImage = NULL;
	m_bBackImage = FALSE;
	m_bMouseMove = TRUE;
}

CGWBButton::~CGWBButton()
{
	
	SAFE_DELETE(m_pNormalBitmap) ;
	SAFE_DELETE(m_pHoverBitmap);
	SAFE_DELETE(m_pDownBitmap) ;
	SAFE_DELETE(m_pDisableBitmap);
	SAFE_DELETE(m_pBackImage);
	SAFE_DELETE(m_pFnt);
}


BEGIN_MESSAGE_MAP(CGWBButton, CButton)
	//{{AFX_MSG_MAP(CGWBButton)
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
	ON_WM_MOUSEMOVE()
	ON_WM_MOUSELEAVE()
END_MESSAGE_MAP()


void CGWBButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	UINT state = lpDrawItemStruct->itemState; 
	//CRect rect;
	//rect.CopyRect(&lpDIS->rcItem); 

	m_state = NORMAL;

	if (state & ODS_FOCUS)
	{
		if (state & ODS_SELECTED)
		{ 
			m_state = DOWN;
		}
		else
		{
			if(m_bMouseOver)
				m_state = HOVER;
		}
	}
	else
	{
		m_state = NORMAL;
	}
	if (state & ODS_DISABLED)
	{
		m_state = DISABLE;
		m_bEnabled = false;
	}
	CDC xdc;
	xdc.Attach( lpDrawItemStruct->hDC );
	CRect rc;
	GetClientRect(rc);
	CMemDCWB dc(&xdc,rc);


	DrawBitmap( &dc, m_state );


	int imode = dc.SetBkMode(TRANSPARENT);
	CFont *pOldFnt = dc.SelectObject(m_pFnt);
	COLORREF oldColor;
	oldColor = dc.SetTextColor( m_pFnt->GetFontColor() );
	CString txt;
	GetWindowText(txt);
	dc.DrawText(txt,rc,DT_CENTER | DT_VCENTER | DT_SINGLELINE);

	dc.SetTextColor( oldColor );
	dc.SelectObject(pOldFnt);
	dc.SetBkMode(imode );

}

bool CGWBButton::LoadImg(CString strPath,int count,int nWidth,int nHeight,int nInterval,BOOL bMouseMove,bool bSizeChange)
{
	OutputDebugString(_T(" CGWBButton::LoadImg")+ strPath);
	m_NumofPics  = count; 
	Bitmap *pSrc = new Gdiplus::Bitmap(strPath);
	m_pNormalBitmap = pSrc->Clone(0,0,nWidth,nHeight,PixelFormat32bppARGB);
	int nWidthtest = m_pNormalBitmap->GetWidth();
	CString strOut;
	strOut.Format(_T("Normal nWidthtest:%d,nWidth:%d,nHeight:%d"),nWidthtest,nWidth,nHeight);
	OutputDebugString(strOut);
	m_pHoverBitmap = pSrc->Clone(nWidth+nInterval,0,nWidth,nHeight,PixelFormat32bppARGB);
	nWidthtest = m_pHoverBitmap->GetWidth();
	strOut.Format(_T("Hover nWidthtest:%d"),nWidthtest);
	OutputDebugString(strOut);
	m_pDownBitmap = pSrc->Clone((nWidth+nInterval)*2,0,nWidth,nHeight,PixelFormat32bppARGB);
	m_pDisableBitmap = pSrc->Clone(0,0,nWidth,nHeight,PixelFormat32bppARGB);
	
	delete pSrc;
	m_State = FileLoaded;
	m_bSizeChange = bSizeChange;
	m_bMouseMove = bMouseMove;
	return true;
}


bool CGWBButton::LoadImg(CString strNormal,CString strHover,CString strDown,CString strDisable,BOOL bMouseMove,bool bSizeChange )
{
	SAFE_DELETE(m_pNormalBitmap) ;
	SAFE_DELETE(m_pHoverBitmap);
	SAFE_DELETE(m_pDownBitmap) ;
	SAFE_DELETE(m_pDisableBitmap);
	m_pNormalBitmap = Bitmap::FromFile(strNormal);
	if (strHover.IsEmpty())
	{
		m_pHoverBitmap = Bitmap::FromFile(strNormal);
	}
	else
	{
		m_pHoverBitmap = Bitmap::FromFile(strHover);
	}
	
	if (strDown.IsEmpty())
	{
		m_pDownBitmap = Bitmap::FromFile(strNormal);
	}
	else
	{
		m_pDownBitmap = Bitmap::FromFile(strDown);
	}
	if (strDisable.IsEmpty())
	{
		m_pDisableBitmap = Bitmap::FromFile(strNormal);
	}
	else
	{
		m_pDisableBitmap = Bitmap::FromFile(strDisable);
	}
	m_State = FileLoaded;
	m_bSizeChange = bSizeChange;
	m_bMouseMove = bMouseMove;
	return true;
}

//设置背景图片
void CGWBButton::SetBackImage(CString strPath)
{
	if (strPath.IsEmpty())
	{
		SAFE_DELETE(m_pBackImage);
		m_bBackImage = false;
	}
	else
	{
		m_pBackImage = Bitmap::FromFile(strPath);
		m_bBackImage = true;
	}
}
void CGWBButton::DrawBitmap( CDC * pDC, int mode )
{
	//if( m_State < FileLoaded ) return;

	CRect rc;
	GetClientRect(rc);

	COLORREF crOldText = pDC->SetTextColor(RGB(0,0,0));
	CDC memDC;
	CBitmap bmp;
	memDC.CreateCompatibleDC(pDC);
	bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
	memDC.SelectObject(&bmp);
	Bitmap* pOldBitmap;
	switch(mode)
	{
	case NORMAL:
		pOldBitmap  = m_pNormalBitmap;
		break;
	case HOVER:
		pOldBitmap  = m_pHoverBitmap;
		break;
	case DOWN:
		pOldBitmap  = m_pDownBitmap;
		break;
	case DISABLE:
		pOldBitmap  = m_pDisableBitmap;
		break;
	default:
		return;
	}

	if (!pOldBitmap)
		return;
	int nWidth = rc.Width();
	int nHeight = rc.Height();
	memDC.BitBlt(0, 0, nWidth, nHeight, &m_memDC, 0, 0, SRCCOPY);
	Graphics graphic(memDC.GetSafeHdc());
	Rect rect(0,0,rc.Width(),rc.Height());
	if (m_bBackImage)
	{
		graphic.DrawImage(m_pBackImage,rect,0,0,pOldBitmap->GetWidth(),pOldBitmap->GetHeight(),UnitPixel);

	}
	if (m_bSizeChange)
	{
		graphic.DrawImage(pOldBitmap,rect,0,0,pOldBitmap->GetWidth(),pOldBitmap->GetHeight(),UnitPixel);
	}
	else
	{
		graphic.DrawImage(pOldBitmap,0,0,0,0,pOldBitmap->GetWidth(),pOldBitmap->GetHeight(),UnitPixel);
	}

	
	pDC->StretchBlt(0,0,nWidth,nHeight,&memDC,0,0,nWidth
		,nHeight,SRCCOPY);
	memDC.DeleteDC();


 	CFont* pOldFont;
 	pOldFont = pDC->SelectObject(GetFont());
 	CString txt;
 	GetWindowText(txt);

 	if (!txt.IsEmpty())
 	{
 		pDC->SetBkMode(TRANSPARENT);//graphic.DrawString(txt,pOldFont,)//
 		pDC->DrawText(txt,rc,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 	}
 	pDC->SelectObject(pOldFont);
	
}



BOOL CGWBButton::OnEraseBkgnd(CDC* pDC) 
{
	if(!m_bDCStored)
	{

		CRect  rect;
		GetClientRect(&rect);
		if(m_memDC.m_hDC!=NULL)
		{
			m_memDC.DeleteDC();
		}

		m_memDC.CreateCompatibleDC (pDC);


		CBitmap	btScreen;

		btScreen.CreateCompatibleBitmap (pDC,rect.Width(),rect.Height());
		m_memDC.SelectObject (&btScreen);

		CClientDC paintDC(GetParent());
		CRect rt;
		GetWindowRect(rt);
		ScreenToClient(rt);
		m_memDC.BitBlt (0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY);
		m_bDCStored=true;
		btScreen.DeleteObject();
	}
	return TRUE;
}

void CGWBButton::SetButtonDef( int TopHeight, int BottomHeight, int LeftWidth, int RightWidth )
{ 
	m_TopHeight = TopHeight;
	m_BottomHeight = BottomHeight;
	m_LeftWidth = LeftWidth;
	m_RightWidth = RightWidth;
}

void CGWBButton::SetTextFont( CFont & fnt )
{ 

	LOGFONT lf;
	fnt.GetLogFont(&lf);
	SAFE_DELETE(m_pFnt);
	m_pFnt = new CAutoFont(lf);
}

void CGWBButton::SetFontColor( COLORREF color )
{
	m_pFnt->SetFontColor(color);
	UpdateWindow();
}



void CGWBButton::OnMouseMove(UINT nFlags, CPoint point)
{
	m_bEnabled = IsWindowEnabled();

	if(!m_bMouseOver&&m_bEnabled)
	{
		m_bMouseOver=true;
		m_state = HOVER;

		if (!m_bTracking)
		{
			TRACKMOUSEEVENT tme;
			tme.cbSize = sizeof(TRACKMOUSEEVENT);
			tme.dwFlags = TME_LEAVE | TME_HOVER;//要触发的消息
			tme.hwndTrack = this->m_hWnd;
			tme.dwHoverTime = 10;// 若不设此参数,则无法触发mouseHover

			if (::_TrackMouseEvent(&tme)) //MOUSELEAVE|MOUSEHOVER消息由此函数触发
			{
				m_bTracking = true;   
			}
		}

		if(m_bMouseMove)
		{

		}
		else
		{
			CString txt;
			GetWindowText(txt);
			if (!txt.IsEmpty())
			{
				SetWindowText(txt);
			}
			CClientDC  dc(this);
			DrawBitmap(&dc,HOVER);


		}
		
	}

	CButton::OnMouseMove(nFlags, point);
}

void CGWBButton::OnMouseLeave()
{

	m_bTracking = false;
	CPoint	point;
	CRect	rect;
	GetWindowRect(&rect);	
	GetCursorPos(&point);
	if (!rect.PtInRect(point) && m_bMouseOver&&m_bEnabled)
	{
		if(m_bMouseMove)
		{
			((CDlgQQTalkMFC*)GetParent())->MouseMove(FALSE);
		}
		else
		{
			CString txt;
			GetWindowText(txt);
			CClientDC  dc(this);
			DrawBitmap(&dc,NORMAL);
		}
		
	}
	m_bMouseOver=false;
	CButton::OnMouseLeave();
}


 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值