贴图法美化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
}