贴图法美化Button按钮

贴图法美化Button按钮

项目是在下面这篇文章里的基础上进行美化的:MFC实现INI配置文件的读取

1. 初始效果

2.最终效果

3. 增加 CImgButton 类

1.1 ImgButton.h 头文件

CPP 复制代码
#pragma once
// CImgButton

class CImgButton : public CBitmapButton
{
	DECLARE_DYNAMIC(CImgButton)
public:
	CImgButton();
	virtual ~CImgButton();

protected:
	DECLARE_MESSAGE_MAP()
public:
	COLORREF TextColor; 
	void SetTextColor(COLORREF crColor); 
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};

1.2 ImgButton.cpp 文件

CPP 复制代码
// ImgButton.cpp : 实现文件
#include "stdafx.h"
#include "READINI.h"
#include "ImgButton.h"
// CImgButton
IMPLEMENT_DYNAMIC(CImgButton, CBitmapButton)
CImgButton::CImgButton()
{
}

CImgButton::~CImgButton()
{
}

BEGIN_MESSAGE_MAP(CImgButton, CBitmapButton)
END_MESSAGE_MAP()

// CImgButton 消息处理程序
void CImgButton::SetTextColor(COLORREF crColor) 
{ 
	TextColor = crColor; 
} 
void CImgButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    // 获取按钮的矩形区域
    CRect rect = lpDrawItemStruct->rcItem;
    
    // 从 lpDrawItemStruct 中获取设备上下文指针
    CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    
    // 保存当前设备上下文状态
    int nSaveDC = pDC->SaveDC();
    
    // 获取按钮的状态
    UINT state = lpDrawItemStruct->itemState;
    
    // 定义一个字符数组来存储按钮文本
    TCHAR strText[MAX_PATH + 1];
    
    // 获取按钮的文本内容
    ::GetWindowText(m_hWnd, strText, MAX_PATH);

    // 设置按钮背景颜色
    pDC->FillSolidRect(&rect, ::GetSysColor(COLOR_3DFACE));

    // 获取按钮位图
    BITMAP bmp;
    m_bitmap.GetBitmap(&bmp);

    // 创建内存DC,并选择位图
    CDC memDC;
    memDC.CreateCompatibleDC(pDC);
    CBitmap* pOldBitmap = memDC.SelectObject(&m_bitmap);

    // 调整位图大小以适应按钮大小
    pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

    // 恢复原位图
    memDC.SelectObject(pOldBitmap);

    // 设置文本颜色
    pDC->SetTextColor(TextColor);

    // 如果按钮有文本
    if (strText != NULL)
    {
        // 获取按钮字体
        CFont *hFont = GetFont();
        
        // 选择按钮字体,并保存旧字体
        CFont *hOldFont = pDC->SelectObject(hFont);
        
        // 计算文本的宽度和高度
        CSize szExtent = pDC->GetTextExtent(strText, lstrlen(strText));
        
        // 计算文本绘制位置,使其居中
        CPoint pt(rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);
        
        // 如果按钮被按下,偏移绘制位置
        if (state & ODS_SELECTED)
        {
            pt.Offset(1, 1);
        }
        
        // 设置背景模式为透明
        int nMode = pDC->SetBkMode(TRANSPARENT);
        
        // 如果按钮被禁用,绘制禁用状态的文本
        if (state & ODS_DISABLED)
        {
            pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
        }
        else // 否则,绘制正常状态的文本
        {
            pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
        }
        
        // 恢复旧字体
        pDC->SelectObject(hOldFont);
        // 恢复背景模式
        pDC->SetBkMode(nMode);
    }

    // 恢复设备上下文状态
    pDC->RestoreDC(nSaveDC);
}

4. 修改按钮的 Owner Draw 属性

5. 在资源视图中增加位图

在项目文件中新建一个文件存放位图资源,名字随意。笔者这里是 Extern

导入刚刚存放位图资源的文件夹,因为这里图片资源少,所以位图名字改不改都行

6. 在 READINIDlg.h 增加声明

CPP 复制代码
// READINIDlg.h : 头文件
。。。。。。
public:
	CImgButton m_BitmapButton;
	CImgButton m_SelectButton, m_FreshButton, m_ShowButton, m_GetButton, m_WriteButton;

7. 修改READINIDlg.cpp文件

每一个 Button 控件对应一个上面声明的成员函数

CPP 复制代码
void CREADINIDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	。。。。。。
	DDX_Control(pDX, IDC_SELECT_FILE_BUTTON, m_SelectButton);
	DDX_Control(pDX, IDC_FLUSH_BUTTON, m_FreshButton);
	DDX_Control(pDX, IDC_SHOW_INI_BUTTON, m_ShowButton);
	DDX_Control(pDX, IDC_GET_BUTTON, m_GetButton);
	DDX_Control(pDX, IDC_WRITE_BUTTON, m_WriteButton);
	。。。。。。
}
CPP 复制代码
BOOL CREADINIDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	。。。。。。
	// TODO: 在此添加额外的初始化代码
	m_SelectButton.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);
	m_SelectButton.SetTextColor(RGB(0,0,0));

	m_FreshButton.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);
	m_FreshButton.SetTextColor(RGB(0,0,0));

	m_ShowButton.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);
	m_ShowButton.SetTextColor(RGB(0,0,0));

	m_GetButton.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);
	m_GetButton.SetTextColor(RGB(0,0,0));

	m_WriteButton.LoadBitmaps(IDB_BITMAP1, IDB_BITMAP2);
	m_WriteButton.SetTextColor(RGB(0,0,0));

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
相关推荐
平安的平安7 分钟前
面向大模型算子开发的高效编程范式PyPTO深度解析
c++·mfc
JustDI-CM9 分钟前
AI学习笔记-提示词工程
人工智能·笔记·学习
悟纤10 分钟前
学习与专注音乐流派 (Study & Focus Music):AI 音乐创作终极指南 | Suno高级篇 | 第33篇
大数据·人工智能·深度学习·学习·suno·suno api
爱写bug的野原新之助10 分钟前
加密摘要算法MD5、SHA、HMAC:学习笔记
笔记·学习
ZH154558913138 分钟前
Flutter for OpenHarmony Python学习助手实战:Web开发框架应用的实现
python·学习·flutter
百锦再1 小时前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
CappuccinoRose1 小时前
JavaScript 学习文档(二)
前端·javascript·学习·数据类型·运算符·箭头函数·变量声明
A9better1 小时前
C++——不一样的I/O工具与名称空间
开发语言·c++·学习
小乔的编程内容分享站1 小时前
C语言笔记之函数
c语言·笔记
AI职业加油站1 小时前
职业提升之路:我的大数据分析师学习与备考分享
大数据·人工智能·经验分享·学习·职场和发展·数据分析