贴图法美化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
}
相关推荐
阿絮~2 分钟前
Apache RocketMQ进阶之路阅读笔记和疑问
笔记·apache·rocketmq
天水幼麟5 小时前
动手学深度学习-学习笔记(总)
笔记·深度学习·学习
天水幼麟7 小时前
动手学深度学习-学习笔记【二】(基础知识)
笔记·深度学习·学习
绿皮的猪猪侠8 小时前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
沧海一笑-dj8 小时前
【51单片机】51单片机学习笔记-课程简介
笔记·学习·51单片机·江科大·江科大学习笔记·江科大单片机·江科大51单片机
老虎06278 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
大苏打seven9 小时前
Docker学习笔记:Docker网络
笔记·学习·docker
Green1Leaves11 小时前
pytorch学习-9.多分类问题
人工智能·pytorch·学习
慕y27411 小时前
Java学习第十五部分——MyBatis
java·学习·mybatis
碣石潇湘无限路12 小时前
【AI篇】当Transformer模型开始学习《孙子兵法》
人工智能·学习