尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
MFC 自定义纯色居中文字进度条控件
一、前言在 MFC 原生开发中系统自带的CProgressCtrl进度条样式固定、自定义空间极小很难实现自定义边框、纯色填充、进度文字居中显示这类定制 UI 需求。 本文通过继承CStatic静态文本控件从零封装一个高复用自定义进度条实现效果黑色实线外边框空白区域白色底色进度区域纯绿色填充支持 0~100 区间动态切换百分比文字自动水平 垂直精准居中适配 0%/70%/100% 不同长度文本对外提供极简SetProgress接口一行代码切换进度值兼容对话框工程仅需绑定 Static 控件即可使用最终界面效果底部按钮点击切换进度进度条实时重绘更新文字与填充区域。二、整体设计思路基类选择继承CStatic对话框资源直接拖入 Static 文本控件无需自定义资源 ID 模板上手简单绘图逻辑重写WM_PAINT消息OnPaint函数分层绘制外框底色→进度填充→居中文字进度约束接口内部自动截断数值到0~100避免越界绘制文字居中核心使用GetTextExtent获取文字真实宽高通过矩形中心坐标减去文字半宽 / 半高实现完全居中摒弃固定像素偏移写法刷新机制修改进度值后调用Invalidate()触发重绘界面实时更新。三、完整控件源码3.1 头文件 ProgressStatic.h#pragma once #include afxwin.h // 自定义进度条控件继承CStatic class CProgressStatic : public CStatic { // MFC动态创建宏支持DDX_Control绑定对话框控件 DECLARE_DYNCREATE(CProgressStatic) public: CProgressStatic(); virtual ~CProgressStatic(); // 对外接口设置进度值范围0~100 void SetProgress(int nPercent); protected: int m_nPercent; // 存储当前进度数值 0~100 // 消息映射声明 DECLARE_MESSAGE_MAP() // 重绘消息响应函数 afx_msg void OnPaint(); };3.2 实现文件 ProgressStatic.cpp#include StdAfx.h #include ProgressStatic.h IMPLEMENT_DYNCREATE(CProgressStatic, CStatic) CProgressStatic::CProgressStatic() { m_nPercent 0; } CProgressStatic::~CProgressStatic() { } BEGIN_MESSAGE_MAP(CProgressStatic, CStatic) ON_WM_PAINT() END_MESSAGE_MAP() void CProgressStatic::SetProgress(int nPercent) { // 限制区间 0~100 m_nPercent max(0, min(100, nPercent)); Invalidate(); // 重绘控件 } void CProgressStatic::OnPaint() { CPaintDC dc(this); CRect rect; GetClientRect(rect); // 1. 绘制完整外黑框白底 dc.SelectStockObject(PS_SOLID); dc.SelectStockObject(WHITE_BRUSH); dc.Rectangle(rect); // 关键填充区域向内收缩1像素避免覆盖边框 CRect fillRect rect; fillRect.left 1; fillRect.top 1; fillRect.right - 1; fillRect.bottom - 1; // 根据百分比计算右侧宽度 fillRect.right fillRect.left (fillRect.Width() * m_nPercent) / 100; // 2. 只填充绿色不绘制边线 CBrush greenBrush(RGB(0, 255, 0)); dc.SelectObject(greenBrush); dc.SelectStockObject(NULL_PEN); dc.FillRect(fillRect, greenBrush); // 3. 居中文字逻辑不变 CString strText; strText.Format(_T(%d%%), m_nPercent); dc.SetTextColor(RGB(128, 0, 128)); dc.SetBkMode(TRANSPARENT); CSize textSize dc.GetTextExtent(strText); int nCenterX rect.left rect.Width() / 2; int nCenterY rect.top rect.Height() / 2; int textX nCenterX - textSize.cx / 2; int textY nCenterY - textSize.cy / 2; dc.TextOut(textX, textY, strText); }四、对话框中使用教程4.1 对话框资源布局打开对话框资源编辑器拖拽一个Static Text静态控件到界面修改 ID 为IDC_PROGRESS_BAR拉大控件矩形作为进度条容器在控件下方添加 4 个按钮ID 与文本对应IDC_BTN_100显示文字100%IDC_BTN_70显示文字70%IDC_BTN_10显示文字10%IDC_BTN_0显示文字0%4.2 对话框头文件引入控件并声明成员#include ProgressStatic.h class CMainDlg : public CDialogEx { // ... 系统自动生成代码省略 ... private: // 自定义进度条控件对象 CProgressStatic m_progressBar; protected: // 控件绑定交换函数 virtual void DoDataExchange(CDataExchange* pDX); // 按钮点击消息响应函数声明 afx_msg void OnBnClickedBtn100(); afx_msg void OnBnClickedBtn70(); afx_msg void OnBnClickedBtn10(); afx_msg void OnBnClickedBtn0(); DECLARE_MESSAGE_MAP() };4.3 对话框实现文件绑定控件 按钮事件// 控件绑定将资源Static控件关联到自定义CProgressStatic对象 void CMainDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_PROGRESS_BAR, m_progressBar); } BEGIN_MESSAGE_MAP(CMainDlg, CDialogEx) // 绑定四个按钮点击事件 ON_BN_CLICKED(IDC_BTN_100, CMainDlg::OnBnClickedBtn100) ON_BN_CLICKED(IDC_BTN_70, CMainDlg::OnBnClickedBtn70) ON_BN_CLICKED(IDC_BTN_10, CMainDlg::OnBnClickedBtn10) ON_BN_CLICKED(IDC_BTN_0, CMainDlg::OnBnClickedBtn0) END_MESSAGE_MAP() // 切换至100%进度 void CMainDlg::OnBnClickedBtn100() { m_progressBar.SetProgress(100); } // 切换至70%进度默认示例效果 void CMainDlg::OnBnClickedBtn70() { m_progressBar.SetProgress(70); } // 切换至10%进度 void CMainDlg::OnBnClickedBtn10() { m_progressBar.SetProgress(10); } // 切换至0%进度 void CMainDlg::OnBnClickedBtn0() { m_progressBar.SetProgress(0); }五、关键技术点解析5.1 为什么不用原生 CProgressCtrlMFC 自带CProgressCtrl仅支持水平 / 垂直简单进度无法自定义边框、填充色且原生控件不支持直接在进度条上绘制居中文字想要实现文字叠加需要额外绘图逻辑封装成本高于继承CStatic自定义绘制。5.2 文字精准居中实现原理很多新手会直接写固定像素偏移TextOut(centerX - 20, centerY - 12, str)存在严重缺陷文本长度变化时0% / 100% 宽度不同文字会左右偏移控件高度修改、字体大小调整后垂直方向不再居中。本文解决方案dc.GetTextExtent(strText)获取当前 DC 下文字真实宽高用矩形中心点减去文字一半尺寸无论文本、字体、控件尺寸如何变化文字永远水平 垂直居中。5.3 数值越界防护SetProgress中使用max(0, min(100, nPercent))强制约束进度范围传入负数自动修正为 0传入大于 100 的数值自动修正为 100 避免填充区域计算时出现负宽度、超出控件范围等绘图异常。5.4 重绘刷新机制调用Invalidate()会向控件发送WM_PAINT消息触发OnPaint重新执行全套绘图逻辑修改进度后画面实时同步更新无卡顿。六、扩展优化方向可自行拓展圆角进度条将Rectangle替换为RoundRect(rect, 8, 8)设置圆角半径实现圆角边框与填充渐变填充使用 Windows APIGradientFill实现绿色渐变进度自定义颜色接口新增SetFillColor、SetTextColor函数外部自由修改填充、文字颜色自适应字体在OnPaint中创建指定大小字体适配高分辨率界面平滑动画添加定时器分段递增进度值实现进度平滑滚动动画垂直进度条增加标志位切换水平 / 垂直填充计算逻辑。七、踩坑记录常见错误解决方案报错CRect 不存在 CenterX 成员错误写法rect.CenterX()该 API 为 Qt 接口MFC 原生 CRect 无此函数必须手动计算rect.left rect.Width() / 2文字背景白色遮挡绿色填充忘记调用dc.SetBkMode(TRANSPARENT)文字背景不透明会覆盖底层绿色区域必须设置透明背景模式修改进度后界面无变化SetProgress函数遗漏Invalidate()没有触发重绘画面不会刷新DDX_Control 绑定失败头文件未添加#include ProgressStatic.h或资源控件 ID 与DoDataExchange中 ID 不匹配。八、总结本文基于 MFCCStatic封装的自定义进度条控件代码简洁、无第三方依赖、复用性极强完美解决原生进度条自定义样式不足的痛点。核心绘图逻辑分层清晰居中文字算法通用性强可直接移植到任意 MFC 对话框工程中使用同时预留了充足扩展空间可根据项目 UI 需求自由修改颜色、圆角、动画等效果。
RELATED

相关推荐

腾讯智影数字人播报功能解析:3步定制AI主播与多场景应用

腾讯智影数字人播报功能解析:3步定制AI主播与多场景应用

腾讯智影数字人播报功能深度解析:从定制到多场景实战去年在一次线上教育课程制作中,我第一次接触到数字人播报技术。当时为了赶制一批教学视频,团队尝试了各种传统录制方式,要么讲师时间难以协调,要么后期剪辑耗时费力…

📅 2026/9/6 11:09:16
小波注意力网络MLWAN:图像超分辨率重建新突破

小波注意力网络MLWAN:图像超分辨率重建新突破

1. 项目背景与核心价值在图像超分辨率重建领域,小波变换与注意力机制的融合正掀起一场技术革命。我们团队最新研发的"小波注意力多尺度学习网络"(MLWAN)在Set5测试集上实现了98.7%的峰值信噪比(PSNR)&#x…

📅 2026/8/21 3:50:16
Java InvalidKeySpecException 异常深度解析与实战排查指南

Java InvalidKeySpecException 异常深度解析与实战排查指南

1. 项目概述:一个看似简单的异常,背后是密码学的“暗礁”在Java开发里,尤其是涉及到加密、签名、证书处理或者与外部系统进行安全通信时,java.security.spec.InvalidKeySpecException这个异常就像一块隐藏在水下的暗礁。表面上看&…

📅 2026/8/21 3:50:18
MORE NEWS

更多资讯

📰

基于MATLAB的MIMO-OFDM仿真程序解析:从发射链路到误码率曲线

简介:这套基于MATLAB实现的MIMO-OFDM仿真程序,面向通信工程与信号处理方向的初学者和研究人员,是理解多天线正交频分复用系统原理及仿真的实用资料。压缩包共31个文件,含15个m函数文件(完成信道建模、调制解调、OFDM收…

📰

Midscene Chrome扩展安装教程:自然语言控制浏览器,4步跑通第一个AI自动化任务

Midscene Chrome扩展安装教程:自然语言控制浏览器,4步跑通第一个AI自动化任务 【免费下载链接】midscene GUI Agent for E2E Testing 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene Midscene Chrome扩展是一款面向新手的AI浏览器自…

📰

如何用 Docker 运行 Android 模拟器:3 分钟跑通 Docker-Android

如何用 Docker 运行 Android 模拟器:3 分钟跑通 Docker-Android 【免费下载链接】docker-android Android in docker solution with noVNC supported, video recording and mcp server 项目地址: https://gitcode.com/GitHub_Trending/do/docker-android CI …

📰

DevDocs 如何为 R 语言文档编译并获取本地 HTML 源文件?

DevDocs 如何为 R 语言文档编译并获取本地 HTML 源文件? 【免费下载链接】devdocs API Documentation Browser 项目地址: https://gitcode.com/GitHub_Trending/de/devdocs DevDocs 里的 R 文档和大多数文档不一样:它的 scraper Docs::R 继承自 F…

📰

PCIe链路信任机制深度解析:从物理层到事务层的性能真相

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

洁净车间环境监控系统设计与实践

1. 洁净车间环境监控的行业痛点在制药、电子制造、食品加工等行业,洁净车间的温湿度控制直接关系到产品质量和生产安全。传统的人工巡检方式存在三大致命缺陷:数据滞后性:每小时记录一次的手工台账无法捕捉突发性环境波动,等发现问…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬