自绘按钮

普通按钮:

#pragma once
#include"stdafx.h"

class MyButton : public CButton
{
private:
	bool is_pressed;  //鼠标是否按下
	int type;//按钮形状
	COLORREF m_bkColor;//背景色
	COLORREF m_roundColor;//边框色
	COLORREF m_textColor; //文字色
public:
	virtual void PreSubclassWindow();  //修改自绘属性
	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);  //绘制 圆形按钮
	void SetAttribute(int,COLORREF, COLORREF, COLORREF);
public:
	DECLARE_MESSAGE_MAP()
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  //鼠标按下
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);  //鼠标松开
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);  //不擦除背景
};

//实现文件
// MyButton
void MyButton::SetAttribute(int t=0,COLORREF bk=RGB(255,128,0),COLORREF rd=RGB(0,255,0),COLORREF txt=RGB(255,255,255))
{
	type = t;
	m_bkColor = bk;
	m_roundColor= rd;
	m_textColor=txt;

}
void MyButton::PreSubclassWindow()
{

	ModifyStyle(0, BS_OWNERDRAW);
	is_pressed = false;
	CButton::PreSubclassWindow();
}

void MyButton::DrawItem(LPDRAWITEMSTRUCT lp)
{
	CRect rc = lp->rcItem;
	CDC dc;
	dc.Attach(lp->hDC);
	dc.SetBkMode(TRANSPARENT);
	CBrush br;
	if (is_pressed)
	{
		//按下去的颜色设为一样,都是灰色
		CPen pen(PS_SOLID, 2, RGB(200, 200, 255));//边框颜色
		br.CreateSolidBrush(RGB(180, 180,180)); //按钮背景色
		dc.SelectObject(&br);
		dc.SelectObject(&pen);
		switch (type)
		{
		case 0:
			dc.Rectangle(0, 0, rc.Width(), rc.Height());
			dc.Rectangle(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
			break;
		case 1:
			dc.Ellipse(0, 0, rc.Width(), rc.Height());
			dc.Ellipse(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
			break;
		case 2:
			dc.RoundRect(0, 0, rc.Width(), rc.Height(), 20, 20);
			dc.RoundRect(1, 1, rc.Width() - 1, rc.Height() - 1, 20, 20);//画边框
			break;
		default:
			break;
		}
		
	}
	else
	{
		CPen pen(PS_SOLID,2, m_roundColor);
		dc.SelectObject(&pen);
		br.CreateSolidBrush(m_bkColor); //按钮背景色
		dc.SelectObject(&br);
		switch (type)
		{
		case 0:
			dc.Rectangle(0, 0, rc.Width(), rc.Height());
			dc.Rectangle(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
			break;
		case 1:
			dc.Ellipse(0, 0, rc.Width(), rc.Height());
			dc.Ellipse(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
			break;
		case 2:
			dc.RoundRect(0, 0, rc.Width(), rc.Height(), 30,30);
			dc.RoundRect(1, 1, rc.Width() - 1, rc.Height() - 1, 30, 30);//画边框
			break;
		default:
			break;
		}
	}
	CString str;
	GetWindowText(str);
	dc.SetTextColor(m_textColor);
	dc.DrawText(str, CRect(0, 0, rc.right, rc.bottom), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	dc.DeleteDC();
}

BEGIN_MESSAGE_MAP(MyButton, CButton)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()


void MyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
	is_pressed = true;
	CButton::OnLButtonDown(nFlags, point);
}

void MyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
	is_pressed = false;
	CButton::OnLButtonUp(nFlags, point);
}

BOOL MyButton::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;  //不擦除背景
}

开关按钮:

#pragma once
#include"stdafx.h"

class MyButton : public CButton
{
private:
	int is_open; // 是否打开
	int type;//按钮形状
	COLORREF m_bkColor;//背景色
	COLORREF m_roundColor;//边框色
	COLORREF m_textColor; //文字色
public:
	virtual void PreSubclassWindow();  //修改自绘属性
	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);  //绘制 圆形按钮
	void SetAttribute(int,COLORREF, COLORREF, COLORREF);
public:
	DECLARE_MESSAGE_MAP()
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  //鼠标按下
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);  //不擦除背景
};

//实现文件
// MyButton
void MyButton::SetAttribute(int t=0,COLORREF bk=RGB(255,128,0),COLORREF rd=RGB(0,255,0),COLORREF txt=RGB(255,255,255))
{
	type = t;
	m_bkColor = bk;
	m_roundColor= rd;
	m_textColor=txt;

}
void MyButton::PreSubclassWindow()
{

	ModifyStyle(0, BS_OWNERDRAW);
	is_open = -1;
	CButton::PreSubclassWindow();
}

void MyButton::DrawItem(LPDRAWITEMSTRUCT lp)
{
	CRect rc = lp->rcItem;
	CDC dc;
	dc.Attach(lp->hDC);
	dc.SetBkMode(TRANSPARENT);
	dc.SelectObject(GetStockObject(NULL_PEN));

	CBrush close, open,round; //分别代表关闭 打开 还有圆的颜色
	close.CreateSolidBrush(RGB(192, 192, 192));
	open.CreateSolidBrush(RGB(0, 220, 0));
	round.CreateSolidBrush(RGB(120, 120, 120));
	POINT pt = { 15,15};
	if (is_open == -1)
	{
		dc.SelectObject(close);
		dc.RoundRect(rc,pt);
		dc.SelectObject(round);
		dc.Ellipse(rc.left+2, rc.top+2, rc.bottom - rc.top-2, rc.bottom-2);
	}
	else
	{
		dc.SelectObject(open);
		dc.RoundRect(rc, pt);
		dc.SelectObject(GetStockObject(WHITE_BRUSH));
		dc.Ellipse(rc.right-(rc.bottom - rc.top)+2, rc.top+2, rc.right-2, rc.bottom-2);
	}

	dc.DeleteDC();
}

BEGIN_MESSAGE_MAP(MyButton, CButton)
	ON_WM_LBUTTONDOWN()
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()


void MyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
	is_open = -is_open;
	CButton::OnLButtonDown(nFlags, point);
}
BOOL MyButton::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;  //不擦除背景
}

最小化以及关闭按钮:


#pragma once
#include"stdafx.h"

class MyButton : public CButton
{
public:
	MyButton(int t) :type(t) {}
	virtual void PreSubclassWindow();  //修改自绘属性
	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);  //绘制 圆形按钮
public:
	DECLARE_MESSAGE_MAP()
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);  //不擦除背景
	afx_msg void OnTimer(UINT_PTR nIDEvent);
	void DrawAlphaRect(CRect);
private:
	BOOL bInBtn;//鼠标是否在按钮的区域内
	int type; //按钮的类型 0为最小化,1为关闭
};

//实现文件

void MyButton::PreSubclassWindow()
{

	ModifyStyle(0, BS_OWNERDRAW);
	SetTimer(1, 200, NULL);
	bInBtn = FALSE;
	CButton::PreSubclassWindow();
}

void MyButton::DrawItem(LPDRAWITEMSTRUCT lp)
{
	CRect rc = lp->rcItem;
	CDC dc;
	dc.Attach(lp->hDC);
	dc.SetBkMode(TRANSPARENT);
	dc.SelectObject(GetStockObject(NULL_PEN));
	CPen pen;
	pen.CreatePen(PS_SOLID, 2, RGB(160,160,160));
	dc.SelectObject(pen);
	if (type == 0)
	{
		dc.MoveTo(rc.left + 6, (rc.bottom - rc.top) / 3 * 2);
		dc.LineTo(rc.right - 6, (rc.bottom - rc.top) / 3 * 2);
	}
	else if (type == 1)
	{
		dc.MoveTo(rc.left + 6, rc.top + 6);
		dc.LineTo(rc.right - 6, rc.bottom - 6);
		dc.MoveTo(rc.left + 6, rc.bottom - 6);
		dc.LineTo(rc.right - 6, rc.top + 6);
	}
	
	pen.DeleteObject();
	dc.DeleteDC();
}

BEGIN_MESSAGE_MAP(MyButton, CButton)
	ON_WM_ERASEBKGND()
	ON_WM_TIMER()
END_MESSAGE_MAP()

BOOL MyButton::OnEraseBkgnd(CDC* pDC)
{
	return FALSE;  //不擦除背景
}
void MyButton::DrawAlphaRect(CRect rect)
{
	CDC *dc = GetDC();
	CDC cdc;
	cdc.CreateCompatibleDC(dc);
	CBitmap bitmap, *pOldBitmap;
	bitmap.CreateCompatibleBitmap(dc, rect.right, rect.bottom);
	CRect src(rect);
	src.OffsetRect(CSize(-rect.left, -rect.top));
	pOldBitmap = cdc.SelectObject(&bitmap);
	cdc.FillSolidRect(src, RGB(0, 85, 255)); //透明色  
	if (::AlphaBlend == 0)
	{
		dc->BitBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, &cdc, src.left, src.top, SRCINVERT);
	}	else {
		BLENDFUNCTION bf;
		memset(&bf, 0, sizeof(bf));
		bf.SourceConstantAlpha = 0x3f; //透明程度//值越大越不透明  
		bf.BlendOp = AC_SRC_OVER;
		::AlphaBlend(dc->GetSafeHdc(), rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
			cdc.GetSafeHdc(), src.left, src.top, src.right - src.left, src.bottom - src.top, bf);
	}
	cdc.SelectObject(pOldBitmap);
}
void MyButton::OnTimer(UINT_PTR nIDEvent)
{
	CRect rc;
	GetClientRect(&rc);
	CPoint pt;
	GetCursorPos(&pt);
	ScreenToClient(&pt);
	CDC *dc = GetDC();
	dc->SelectObject(GetStockObject(NULL_PEN));
	if (rc.PtInRect(pt)) //如果鼠标悬浮在按钮上,则画出一个矩形
	{	
		if (bInBtn)
		{
			CRect r = { rc.left + 1,rc.top + 1,rc.right - 1,rc.bottom - 1 };//由于画透明矩形时有1像素的边框,所以画的区域为按钮的区域-1
			DrawAlphaRect(r);
			bInBtn = FALSE;
		}
	}
	else
	{
		bInBtn = TRUE;
		CBrush brush;
		brush.CreateSolidBrush(RGB(240, 240, 240));//屏幕默认RGB
		dc->SelectObject(brush);
		dc->Rectangle(rc);
		CPen pen;
		pen.CreatePen(PS_SOLID, 2, RGB(160, 160, 160));
		dc->SelectObject(pen);
		if (type == 0)
		{
			dc->MoveTo(rc.left+6, (rc.bottom - rc.top) / 3*2);
			dc->LineTo(rc.right-6, (rc.bottom - rc.top) /3*2);
		}
		else if (type == 1)
		{
			dc->MoveTo(rc.left + 6, rc.top + 6);
			dc->LineTo(rc.right - 6, rc.bottom - 6);
			dc->MoveTo(rc.left + 6, rc.bottom - 6);
			dc->LineTo(rc.right - 6, rc.top + 6);
		}
		pen.DeleteObject();
		
	}
	ReleaseDC(dc);
	
	CButton::OnTimer(nIDEvent);
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值