MFC重绘按钮控件

最近工作在学MFC,就写点博客记录一下
算是新手上路,勿喷
用的是VS2010

做的是一个圆形按钮 按下和弹起会不同颜色

.h文件

#pragma once
#include "afxwin.h"
class CCustomDrawBtn :
	public CButton
{
	CDC* pDC;
	CPen* pOldPen;
	CFont* pOldFont;
	DECLARE_DYNAMIC(CCustomDrawBtn)
public:
	CCustomDrawBtn();
	virtual ~CCustomDrawBtn();
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	virtual void PreSubclassWindow();
	void SetColorStyle(COLORREF bkColor, COLORREF hoverColor, COLORREF textColor, COLORREF borderColor, int fontSize, int radis);
	void SetFontSize(int fontsize);
	void SetTextColor(COLORREF color);
//	afx_msg void OnTimer(UINT nIDEvent);

protected:
	DECLARE_MESSAGE_MAP()
	void Draw(LPDRAWITEMSTRUCT lpDrSt, CDC* pDC, CRect rect, int roundRadis, COLORREF bkColor, CString strText);
	void Redraw(LPDRAWITEMSTRUCT lpDrSt);



public:
	//绘制区域
	CRect    m_rcDrawClient;
	//默认背景颜色
	COLORREF m_bkColor;
	//鼠标移动上去的颜色
	COLORREF m_hoverColor;
	//文字颜色
	COLORREF m_textColor;
	//边框颜色
	COLORREF m_borderColor;
	//背景颜色
	COLORREF m_drawBkColor;
	//字体大小
	int      m_fontSize;
	//圆角幅度>0,=0 无圆角
	int      m_radis;
	//累计
	int count;
	//是否已经画了高亮色
	BOOL     m_bPaintedHighLight;
	//文本
	CString  m_btnText;
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	int m_flag;
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};

.cpp文件

#include "StdAfx.h"
#include "CustomDrawBtn.h"
#include "SKinColors.h"
#include "resource.h"

IMPLEMENT_DYNAMIC(CCustomDrawBtn, CButton)

CCustomDrawBtn::CCustomDrawBtn()
	: m_flag(0)
{
	m_bkColor = RGB(51, 126, 251);//默认是蓝色风格背景
	m_hoverColor = RGB(17, 94, 188);//默认高亮色
	m_textColor = RGB(255, 255, 255);//默认文字颜色
	m_radis = 100;//圆角幅度
	m_fontSize = 14;//字体
	m_bPaintedHighLight = FALSE;
	m_btnText = "";
	m_drawBkColor = m_bkColor;
	m_borderColor = m_bkColor;
	m_flag = FALSE;
	count = 1;
}

CCustomDrawBtn::~CCustomDrawBtn(){}

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

//设置颜色
void CCustomDrawBtn::SetColorStyle(COLORREF bkColor, COLORREF hoverColor, 
					COLORREF textColor, COLORREF borderColor, int fontSize, int radis){
	m_bkColor = bkColor;
	m_hoverColor = hoverColor;
	m_radis = radis;
	m_textColor = textColor;
	m_fontSize = fontSize;
	m_drawBkColor = m_bkColor;
	m_borderColor = borderColor;
	Invalidate();
}

//设置文字大小
void CCustomDrawBtn::SetFontSize(int fontsize){
	m_fontSize = fontsize;
}

//设置文字颜色
void CCustomDrawBtn::SetTextColor(COLORREF color){
	m_textColor = color;
}

//画 调用↓
void CCustomDrawBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	Redraw(lpDrawItemStruct);
}

//画 调用↓
void CCustomDrawBtn::Redraw(LPDRAWITEMSTRUCT lpDrSt){
	//获取窗口客户区
	GetClientRect(&m_rcDrawClient);
	//获取句柄
	pDC = GetDC();
	if (pDC){
		//获取窗口的标题条文本
		GetWindowText(m_btnText);
		//调用自己封装的重写方法
		Draw(lpDrSt, pDC, m_rcDrawClient, m_radis, m_drawBkColor, m_btnText);
		//释放
		ReleaseDC(pDC);
	}
}

//画
void CCustomDrawBtn::Draw(LPDRAWITEMSTRUCT lpDrSt, CDC* pDC, CRect rect, int roundRadis, 
								  COLORREF bkColor, CString strText){
	if (pDC){
		CRect rect, rectFocus;
		GetClientRect(&rect);
		rectFocus.CopyRect(&rect);
		//朝它的中心移动边以缩小
		rectFocus.DeflateRect(4, 4, 4, 4);
		//获取文字颜色
		COLORREF textColor = m_textColor;
		//获取边框颜色
		COLORREF borderColor = m_borderColor;
		//BOOL bRet = pDC->Rectangle(&rectFocus);
		CBrush framebrush = borderColor;
		if (lpDrSt->itemState & ODS_DISABLED){
			bkColor = SKinColors::lightgray;
			textColor = SKinColors::dark_gray;
			borderColor = SKinColors::dark_gray;
		}
		CPen pen(PS_SOLID, 1, borderColor);
		pOldPen = pDC->SelectObject(&pen);
		CFont font;
		font.CreateFont(m_fontSize, 0, 0, 0, 700, FALSE, FALSE, FALSE, DEFAULT_CHARSET, 
						OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("宋体"));
		pOldFont = pDC->SelectObject(&font);
 		CBrush brushtemp;
 		brushtemp.CreateSolidBrush(RGB(192,124,104));
 		pDC->SelectObject(&brushtemp);
 		pDC->RoundRect(0, 0, rect.right , rect.bottom , roundRadis + 10, roundRadis + 10);
 		pDC->SelectObject(pOldPen);
		CBrush brush;
		brush.CreateSolidBrush(bkColor);
		pDC->SelectObject(&brush);
		pDC->RoundRect(10, 10, rect.right-10, rect.bottom-10, roundRadis, roundRadis);
		pDC->SelectObject(pOldPen);

		//绘制按钮文本 定义一个CRect用于绘制文本 
		CRect textRect;
		//拷贝矩形区域 
		textRect.CopyRect(&m_rcDrawClient);
		//获得字符串尺寸
		CString btnCaption = m_btnText;
		CSize sz = pDC->GetTextExtent(btnCaption);
		//调整文本位置 居中 
		textRect.top += (textRect.Height() - sz.cy) / 2;
		//设置文本背景透明 
		pDC->SetBkMode(TRANSPARENT);
		//设置文本颜色
		pDC->SetTextColor(textColor);
		//绘制文本内容
		pDC->DrawText(btnCaption, &textRect, DT_RIGHT | DT_CENTER | DT_BOTTOM);
		//焦点下的外观绘制
		if (lpDrSt->itemState & ODS_FOCUS){
			int iPrevBkMode = pDC->GetBkMode();
			pDC->SetBkMode(TRANSPARENT);
			CPen pen(PS_DOT, 0, m_hoverColor);
			CPen *pPrevPen = pDC->SelectObject(&pen);
			CGdiObject *pPrevBrush = pDC->SelectStockObject(NULL_BRUSH);
			pDC->SetBkMode(iPrevBkMode);
			pDC->SelectObject(pPrevPen);
			pDC->SelectObject(pPrevBrush);
		}
		pDC->SelectObject(pOldFont);
		font.DeleteObject();
		pen.DeleteObject();
	}
}
//改为所有者绘制
void CCustomDrawBtn::PreSubclassWindow(){

	ModifyStyle(0, BS_OWNERDRAW); // make the button owner drawn
	CButton::PreSubclassWindow();
}

//背景擦除
BOOL CCustomDrawBtn::OnEraseBkgnd(CDC* pDC){
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	return TRUE;
	//return CButton::OnEraseBkgnd(pDC);
}

//按键按下
void CCustomDrawBtn::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CRect rcWindow;
	GetWindowRect(&rcWindow);
	CPoint ptCursor;//鼠标光标位置
	GetCursorPos(&ptCursor);
	if (!m_bPaintedHighLight) {
		count = count % 10 + 1;
		m_drawBkColor = m_hoverColor;//变换背景色
		InvalidateRect(NULL);
		//m_bPaintedHighLight = true;
	}
	Invalidate(FALSE);
	CButton::OnLButtonDown(nFlags, point);
}


void CCustomDrawBtn::OnLButtonUp(UINT nFlags, CPoint point){
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CRect rcWindow;
	GetWindowRect(&rcWindow);
	CPoint ptCursor;//鼠标光标位置
	GetCursorPos(&ptCursor);
	if (m_bPaintedHighLight) {
		m_drawBkColor = m_bkColor;
		InvalidateRect(NULL);
		//m_bPaintedHighLight = false;
	}
	Invalidate(FALSE);
	CButton::OnLButtonUp(nFlags, point);
}

调用 在Dlg.h文件中申明一个重绘按钮变量CCustomDrawBtn CCustomDrawBtnTest;
再在Dlg.cpp文件中创建

//按钮重绘
CCustomDrawBtnTest.Create(_T("测试"), WS_VISIBLE | WS_EX_COMPOSITED, CRect(900, 600, 1000, 700), this, IDC_MYBUTTON);

函数细节可以在微软的网站上找api MFC类 | Microsoft learn

想增加其他效果也可以通过类向导里增加映射来实现

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

楠风丶北枝

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

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

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

打赏作者

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

抵扣说明:

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

余额充值