贴图法美化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
}
相关推荐
Pluchon17 小时前
硅基计划6.0 伍 JavaEE 网络原理
网络·网络协议·学习·tcp/ip·udp·java-ee·信息与通信
时光不去20 小时前
java接口自动化之allure本地生成报告
运维·笔记·自动化
杨浦老苏21 小时前
简单直观的笔记管理器Poznote
笔记·docker·群晖
椰壳也可1 天前
06_作业基于CubeMx实现按键控制LED灯(裸机)(立芯嵌入式笔记)
笔记·stm32·学习
im_AMBER1 天前
Leetcode 52
笔记·学习·算法·leetcode
菜鸟‍1 天前
【前端学习】阿里前端面试题
前端·javascript·学习
wdfk_prog1 天前
[Linux]学习笔记系列 -- [kernel]kallsyms
linux·笔记·学习
!chen1 天前
CPP 学习笔记 语法总结
c++·笔记·学习
现在,此刻1 天前
李沐深度学习笔记D3-线性回归
笔记·深度学习·线性回归
d111111111d1 天前
STM32外设学习--DMA直接存储器读取(AD扫描程序,DMA搬运)--学习笔记。
笔记·stm32·单片机·嵌入式硬件·学习