贴图法美化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
}
相关推荐
鲤籽鲲13 分钟前
C# MethodTimer.Fody 使用详解
开发语言·c#·mfc
心怀梦想的咸鱼37 分钟前
UE5 第一人称射击项目学习(四)
学习·ue5
AI完全体40 分钟前
【AI日记】24.11.22 学习谷歌数据分析初级课程-第2/3课
学习·数据分析
rellvera1 小时前
【强化学习的数学原理】第02课-贝尔曼公式-笔记
笔记·机器学习
Mephisto.java1 小时前
【大数据学习 | Spark-Core】Spark提交及运行流程
大数据·学习·spark
PandaCave2 小时前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
yuwinter2 小时前
鸿蒙HarmonyOS学习笔记(2)
笔记·学习·harmonyos
red_redemption2 小时前
自由学习记录(23)
学习·unity·lua·ab包
幽兰的天空3 小时前
默语博主的推荐:探索技术世界的旅程
学习·程序人生·生活·美食·交友·美女·帅哥
游走于计算机中摆烂的3 小时前
启动前后端分离项目笔记
java·vue.js·笔记