MFC实战-自定义按钮控件

MFC实战-自定义按钮控件
.h头文件设计

#include"stdafx.h"
class CMybutton:public CButton
{
public:
 CMybutton();
 virtual ~CMybutton();
 BOOL Create(LPCTSTR lpszCaption,DWORD dwStyle,const CPoint point,const HRGN hRgn,CWnd* pParentWnd,UINT nID);
 BOOL Create(LPCTSTR lpszCaption,DWORD dwStyle,const CPoint point,const HRGN hRgn,CWnd* pParentWnd,UINT nID,COLORREF color);
 BOOL Create(LPCTSTR lpszCaption,DWORD dwStyle,const CPoint point,const HRGN hRgn,CWnd* pParentWnd,UINT nID,UINT nBorder,COLORREF nColor,COLORREF sColor,COLORREF hColor,COLORREF dColor);
private:
 UINT m_nBorder;
 LONG m_lfEscapement;
 COLORREF m_nColor;
 COLORREF m_sColor;
 COLORREF m_hColor;
 COLORREF m_dColor;
 CBitmap *m_pNormal;
 CBitmap *m_pSelected;
 CBitmap *m_pHover;
 CBitmap *m_pDisabled;
 CPoint m_CenterPoint;
 BOOL m_bMouseDown;
 BOOL m_bHover;
 BOOL m_bCapture;
 HRGN m_hRgn;
 BOOL m_bNeedBitmaps;
 void DrawButton(CDC*pDC,CRect *pRect,UINT state);
 void PrepareStateBitmaps(CDC *pDC,CRect *pRect);
 BOOL HitTest(CPoint point);
 //void FrameRgn3D(HDC hDC,const HRGN hRgn,BOOL bSunken);
 void CheckHover(CPoint point);
protected:
 void PrepareNormalState(CDC *pDC,CDC *pMemDC,CRect *pRect);
 void PrepareSelectedState(CDC *pDC,CDC *pMemDC,CRect *pRect); 
 void PrepareHoverState(CDC *pDC,CDC *pMemDC,CRect *pRect); 
 void PrepareDisabledState(CDC *pDC,CDC *pMemDC,CRect *pRect); 
 void DrawButtonCaption(HDC hDC,CRect *pRect,BOOL bEnabled,BOOL bSunken);
 void PaintRgn(CDC *pDC,CDC *pMemDC,CBitmap *pBitmap,COLORREF color,CRect *pRect,BOOL bEnabled,BOOL bSunken);
public:
 //ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CMybutton)
 public:
  virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
 protected:
  virtual void PreSubclassWindow();
 //}}AFX_VIRTUAL
protected:
 //{{AFX_VIRTUAL(CMybutton)
 afx_msg BOOL OnEraseBkgnd(CDC *pDC);
 afx_msg void OnMouseMove(UINT nFlags,CPoint point);
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
 afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
 //}}AFX_VIRTUAL
 DECLARE_MESSAGE_MAP()
};

.cpp文件代码设计

#include"stdafx.h"
#include"Mybutton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CMybutton::CMybutton()
{
 m_nColor=GetSysColor(COLOR_BTNFACE);
 m_sColor=m_nColor;
 m_hColor=m_nColor;
 m_dColor=m_nColor;
 m_nBorder=1;
 m_pNormal=NULL;
 m_pSelected=NULL;
 m_pHover=NULL;
 m_pDisabled=NULL;
 m_hRgn=0;
 m_bHover=false;
 m_bCapture=false;
 m_bMouseDown=false;
 m_bNeedBitmaps=true;
}
CMybutton::~CMybutton()
{
 delete m_pNormal;
 delete m_pSelected;
 delete m_pHover;
 delete m_pDisabled;
 DeleteObject(m_hRgn);
}
BEGIN_MESSAGE_MAP(CMybutton, CButton)
	//{{AFX_MSG_MAP(CMybutton)

	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CMybutton::Create(LPCTSTR lpszCaption,DWORD dwStyle,const CPoint point,const HRGN hRgn,CWnd * pParentWnd,UINT nID)
{
 DeleteObject(m_hRgn);
 m_hRgn=CreateRectRgn(0,0,31,31);
 CRect box(0,0,0,0);
 if(m_hRgn!=0)
  CombineRgn(m_hRgn,hRgn,0,RGN_COPY);
 GetRgnBox(m_hRgn,&box);
 OffsetRgn(m_hRgn,-box.left,-box.top);
 GetRgnBox(m_hRgn,&box);
 m_CenterPoint=CPoint(box.left+box.Width()/2,box.top+box.Height()/2);
 box.OffsetRect(point);
 return CButton::Create(lpszCaption,dwStyle,box,pParentWnd,nID);
}
BOOL CMybutton::Create(LPCTSTR lpszCaption,DWORD dwStyle,const CPoint point,
        const HRGN hRgn,CWnd *pParentWnd,UINT nID,
        COLORREF color)
{
 m_sColor=color;
 m_hColor=color;
 return Create(lpszCaption,dwStyle,point,hRgn,pParentWnd,nID);
}
BOOL CMybutton::Create(LPCTSTR lpszCaption,DWORD dwStyle,const CPoint point,const HRGN hRgn,CWnd* pParentWnd,UINT nID,UINT nBorder,COLORREF nColor,COLORREF sColor,COLORREF hColor,COLORREF dColor)
{
 m_nBorder=nBorder;
 m_nColor=nColor;
 m_sColor=sColor;
 m_hColor=hColor;
 m_dColor=hColor;
 return Create(lpszCaption,dwStyle,point,hRgn,pParentWnd,nID);
}
void CMybutton::PreSubclassWindow()
{
 ModifyStyle(0,BS_OWNERDRAW|BS_PUSHBUTTON);
 CButton::PreSubclassWindow();
}
void CMybutton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
 CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
 CRect rect;
 GetClientRect(rect);
 if(m_bNeedBitmaps)
	PrepareStateBitmaps(pDC,&rect);
 DrawButton(pDC,&rect,lpDrawItemStruct->itemState);
}
void CMybutton::PrepareStateBitmaps(CDC *pDC,CRect *pRect)
{
 CDC *pMemDC;
 pMemDC=new CDC;
 pMemDC->CreateCompatibleDC(pDC);
 PrepareNormalState(pDC,pMemDC,pRect);
 PrepareSelectedState(pDC,pMemDC,pRect);
 PrepareHoverState(pDC,pMemDC,pRect);
 PrepareDisabledState(pDC,pMemDC,pRect);
 delete pMemDC;
 m_bNeedBitmaps=false;
}
void CMybutton::PrepareNormalState(CDC *pDC,CDC *pMemDC,CRect *pRect)
{
 delete m_pNormal;
 m_pNormal=new CBitmap;
 PaintRgn(pDC,pMemDC,m_pNormal,m_nColor,pRect,true,false);
}
void CMybutton::PrepareSelectedState(CDC *pDC,CDC *pMemDC,CRect *pRect)
{
 delete m_pSelected;
 m_pSelected=new CBitmap;
 PaintRgn(pDC,pMemDC,m_pSelected,m_sColor,pRect,true,true);
}
void CMybutton::PrepareHoverState(CDC *pDC,CDC *pMemDC,CRect *pRect)
{
 delete m_pHover;
 m_pHover=new CBitmap;
 PaintRgn(pDC,pMemDC,m_pHover,m_hColor,pRect,true,false);
}
void CMybutton::PrepareDisabledState(CDC *pDC,CDC *pMemDC,CRect *pRect)
{
 delete m_pDisabled;
 m_pDisabled=new CBitmap;
 PaintRgn(pDC,pMemDC,m_pDisabled,m_dColor,pRect,false,false);
}
//...
void CMybutton::PaintRgn(CDC *pDC,CDC *pMemDC,CBitmap *pBitmap,COLORREF color,
						 CRect *pRect,BOOL bEnabled,BOOL bSunken)
{
	pBitmap->CreateCompatibleBitmap(pDC,pRect->Width(),pRect->Height());
	CBitmap *pOldBitmap=pMemDC->SelectObject(pBitmap);
	HRGN hRgn=CreateRectRgn(0,0,0,0);
	GetWindowRgn(hRgn);
	HBRUSH hBrush=CreateSolidBrush(color);
	pMemDC->FillSolidRect(pRect,RGB(0,0,0));
	FillRgn(pMemDC->GetSafeHdc(),hRgn,hBrush);
	DeleteObject(hBrush);
	DrawButtonCaption(pMemDC->GetSafeHdc(),pRect,bEnabled,bSunken);
	FrameRgn3D(pMemDC->GetSafeHdc(),hRgn,bSunken);
	DeleteObject(hRgn);
	pMemDC->SelectObject(pOldBitmap);
}
void CMybutton::DrawButtonCaption(HDC hDC,CRect *pRect,BOOL bEnabled,BOOL bSunken)
{
	int nOldMode=SetBkMode(hDC,TRANSPARENT);
	CString text;
	GetWindowText(text);
	LOGFONT lf;
	GetParent()->GetFont()->GetLogFont(&lf);
	HFONT hFont=CreateFontIndirect(&lf);
	HFONT hOldFont=(HFONT)SelectObject(hDC,hFont);
	TEXTMETRIC tm;
	GetTextMetrics(hDC,&tm);
	CPoint p=CPoint(m_CenterPoint.x,m_CenterPoint.y+tm.tmHeight/2);
	if(bSunken)
		p.Offset(m_nBorder,m_nBorder);
	if(bEnabled)
	{
		if(m_bHover||m_bCapture)
		{
			SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT));
			SetTextAlign(hDC,TA_CENTER|TA_BOTTOM);
			TextOut(hDC,p.x,p.y,text,text.GetLength());
		}
		else
		{
			SetTextColor(hDC,GetSysColor(COLOR_3DHILIGHT));
			SetTextAlign(hDC,TA_CENTER|TA_BOTTOM);
			TextOut(hDC,p.x,p.y,text,text.GetLength());
		}
	}
	else
	{
		SetTextColor(hDC,GetSysColor(COLOR_3DHILIGHT));
		TextOut(hDC,p.x+1,p.y+1,text,text.GetLength());
		SetTextColor(hDC,GetSysColor(COLOR_3DSHADOW));
		TextOut(hDC,p.x,p.y,text,text.GetLength());
	}
	SelectObject(hDC,hOldFont);
	DeleteObject(hFont);
	SetBkMode(hDC,nOldMode);
}
void CMybutton::FrameRgn3D(HDC hDC,const HRGN hRgn,BOOL bSunken)
{
	HBRUSH hBrush;
	HRGN hBaseRgn=CreateRectRgn(0,0,0,0);
	COLORREF ltOuter;
	COLORREF ltInner;
	COLORREF rbOuter;
	COLORREF rbInner;
	if(!bSunken)
	{
		ltOuter=GetSysColor(COLOR_3DLIGHT);
		ltInner=GetSysColor(COLOR_3DHILIGHT);
		rbOuter=GetSysColor(COLOR_3DDKSHADOW);
		rbInner=GetSysColor(COLOR_3DSHADOW);
	}
	else
	{
		ltOuter=GetSysColor(COLOR_3DSHADOW);
		ltInner=GetSysColor(COLOR_3DDKSHADOW);
		rbOuter=GetSysColor(COLOR_3DHILIGHT);
		rbInner=GetSysColor(COLOR_3DLIGHT);
	}
switch(m_nBorder)
{
case 2:
	CombineRgn(hBaseRgn,hRgn,0,RGN_COPY);
	OffsetRgn(hBaseRgn,2,2);
	CombineRgn(hBaseRgn,hRgn,hBaseRgn,RGN_DIFF);
	hBrush=CreateSolidBrush(ltInner);
	FillRgn(hDC,hBaseRgn,hBrush);
	DeleteObject(hBrush);
	//
	CombineRgn(hBaseRgn,hRgn,0,RGN_COPY);
	OffsetRgn(hBaseRgn,-2,-2);
	CombineRgn(hBaseRgn,hRgn,hBaseRgn,RGN_DIFF);
	hBrush=CreateSolidBrush(rbInner);
	FillRgn(hDC,hBaseRgn,hBrush);
	DeleteObject(hBrush);
	//
	CombineRgn(hBaseRgn,hRgn,0,RGN_COPY);
	OffsetRgn(hBaseRgn,1,1);
	CombineRgn(hBaseRgn,hRgn,hBaseRgn,RGN_DIFF);
	hBrush=CreateSolidBrush(ltOuter);
	FillRgn(hDC,hBaseRgn,hBrush);
	DeleteObject(hBrush);
	//
	CombineRgn(hBaseRgn,hRgn,0,RGN_COPY);
	OffsetRgn(hBaseRgn,-1,-1);
	CombineRgn(hBaseRgn,hRgn,hBaseRgn,RGN_DIFF);
	hBrush=CreateSolidBrush(rbOuter);
	FillRgn(hDC,hBaseRgn,hBrush);
	DeleteObject(hBrush);
	break;
default:
	CombineRgn(hBaseRgn,hRgn,0,RGN_COPY);
	OffsetRgn(hBaseRgn,1,1);
	CombineRgn(hBaseRgn,hRgn,hBaseRgn,RGN_DIFF);
	hBrush=CreateSolidBrush(ltInner);
	FillRgn(hDC,hBaseRgn,hBrush);
	DeleteObject(hBrush);
	//
	CombineRgn(hBaseRgn,hRgn,0,RGN_COPY);
	OffsetRgn(hBaseRgn,-1,-1);
	CombineRgn(hBaseRgn,hRgn,hBaseRgn,RGN_DIFF);
	hBrush=CreateSolidBrush(rbOuter);
	FillRgn(hDC,hBaseRgn,hBrush);
	DeleteObject(hBrush);
	break;
}
DeleteObject(hBaseRgn);	
}
void CMybutton::DrawButton(CDC *pDC,CRect *pRect,UINT state)
{
 CDC *pMemDC=new CDC;
 pMemDC->CreateCompatibleDC(pDC);
 CBitmap *pOldBitmap;
 HRGN hRgn=CreateRectRgn(0,0,0,0);
 GetWindowRgn(hRgn);
 if(state&ODS_DISABLED)
  pOldBitmap=pMemDC->SelectObject(m_pDisabled);
 else
 {
  if(state&ODS_SELECTED)
   pOldBitmap=pMemDC->SelectObject(m_pSelected);
  else
  {
   if(m_bHover)
    pOldBitmap=pMemDC->SelectObject(m_pHover);
   else
    pOldBitmap=pMemDC->SelectObject(m_pNormal);
  }
 }
 ::SelectClipRgn(pDC->GetSafeHdc(),hRgn);
 pDC->BitBlt(0,0,pRect->Width(),pRect->Height(),pMemDC,0,0,SRCCOPY);
 ::SelectClipRgn(pDC->GetSafeHdc(),NULL);
 DeleteObject(hRgn);
 pMemDC->SelectObject(pOldBitmap);
 delete pMemDC;
}
void CMybutton::OnLButtonDown(UINT nFlags,CPoint point)
{
 m_bMouseDown=true;
 if(!m_bCapture)
 {
  SetCapture();
  m_bCapture=true;
 }
 CButton::OnLButtonDown(nFlags,point);
}
void CMybutton::OnLButtonUp(UINT nFlags,CPoint point)
{
 CButton::OnLButtonUp(nFlags,point);
 m_bMouseDown=false;
 if(m_bCapture)
 {
  ReleaseCapture();
  m_bCapture=false;
 }
 CheckHover(point);
}
void CMybutton::OnMouseMove(UINT nFlags,CPoint point)
{
 if(!m_bMouseDown)
  CheckHover(point);
 CButton::OnMouseMove(nFlags,point);
}
void CMybutton::CheckHover(CPoint point)
{
 if(HitTest(point))
 {
  if(!m_bCapture)
  {
   SetCapture();
   m_bCapture=true;
  }
  if(!m_bHover)
  {
   m_bHover=true;
   RedrawWindow();
  }
 }
 else
 {
  if(m_bCapture)
  {
   ReleaseCapture();
   m_bCapture=false;
  }
  m_bHover=false;
  RedrawWindow();
 }
}
BOOL CMybutton::HitTest(CPoint point)
{
 BOOL result=false;
 HRGN hRgn=CreateRectRgn(0,0,0,0);
 GetWindowRgn(hRgn);
 CRect rgnRect;
 GetRgnBox(hRgn,&rgnRect);
 result=PtInRect(&rgnRect,point)&&PtInRegion(hRgn,point.x,point.y);
 DeleteObject(hRgn);
 return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肤白貌美

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值