贴图法美化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
}
相关推荐
yuhouxiyang4 小时前
学习海康VisionMaster之路径提取
学习·计算机视觉
PLUS_WAVE5 小时前
CogCoM: A Visual Language Model with Chain-of-Manipulations Reasoning 学习笔记
学习·语言模型·大模型·cot·vlm·推理模型·reasoning
绵绵细雨中的乡音5 小时前
Linux进程学习【环境变量】&&进程优先级
linux·运维·学习
贺函不是涵5 小时前
【沉浸式求职学习day27】
学习
努力奋斗的小杨5 小时前
学习MySQL的第十二天
数据库·笔记·学习·mysql·navicat
枫叶20006 小时前
OceanBase数据库-学习笔记1-概论
数据库·笔记·学习·oceanbase
一点.点6 小时前
李沐动手深度学习(pycharm中运行笔记)——04.数据预处理
pytorch·笔记·python·深度学习·pycharm·动手深度学习
一点.点6 小时前
李沐动手深度学习(pycharm中运行笔记)——07.自动求导
pytorch·笔记·python·深度学习·pycharm·动手深度学习
你可以叫我仔哥呀6 小时前
k8s学习记录(五):Pod亲和性详解
学习·容器·kubernetes
tcoding6 小时前
《MySQL 技术内幕-innoDB 存储引擎》笔记
数据库·笔记·mysql