SegeX Progress:MFC通用进度条

news2025/1/18 17:03:54

----哆啦刘小洋 原创,转载需说明出处

MFC高级通用进度条-目录

    • 1 简介
    • 2 进度条实现基本原理
    • 3 使用方法
      • 3 .1 简单情况
      • 3.2 两个前后独立的进度条
      • 3.3 实际应用的一般情况
      • 3.4 带子进度条
    • 4 其他
      • 4.1 使用限制
      • 4.2 其他全局宏(函数)
      • 4.3 当前进度条设置

1 简介

SegeX组件之一:SegeX EvProgress。应用级源代码,首次公开。EvProgress是基于MFC的通用进度条,功能强大又简单易用。几行代码就可以让你的计算具有进度显示的功能,并且具有多种高级功能:1. 支持任意多个进度条同时存在;2.支持在子函数中继续主函数中的进度;3.支持两级子进度条;4.加入进度条后可避免长时间计算的”应用程序没有响应”;5.支持调节大小、背景颜色、背景图片;6.全自动管理。
源代码下载附后。

2 进度条实现基本原理

“工程地球物理系统(SegeX)“公开的原创组件之一。
本篇文章并不打算深入到实现原理的末端细节,感兴趣的读者可以阅读源代码,这里仅从宏观介绍一下实现原理。
1)全局模式。组件利用专门的处理类CEvProgressManager,管理任意多个进度条窗口CEvProgressWin。用户接口使用全局宏EV_START_NEW_PROGRESS_AUTO()来声明一个新的进度条。
2)栈管理。当声明一个新的进度条后,先前的进度条被压栈,因此这之后所有的进度操作都是针对当前的进度条。
3)自动释放。EV_START_NEW_PROGRESS_AUTO声明时,后台组件辅助类CEvProgressAutoDestroy会记录当前进度条,当EV_START_NEW_PROGRESS_AUTO所在的作用域结束时,CEvProgressAutoDestroy自动释放本次声明的进度条。
4)子函数中仍然可以继续主函数的进度,且子函数与主函数完全脱耦,无参数传递,不用关心也不需要知道是谁调用,也不用关心进度占主进度多少(按100%处理即可)。
5)全局设置。组件利用全局函数设置进度条的尺寸、背景颜色、背景图片等全局参数。
6)局部设置。组件在新开进度条之后,也可以对该进度条进行专门的背景图片设置等。

3 使用方法

首先,该组件是针对MFC Windows桌面应用程序,不支持控制台程序。因此假定你的工程是MFC Windows桌面应用程序,例如对话框程序。
1)将ev_progress.h 、ev_progress.cpp复制到工程指定目录。
2)在要使用的文件中增加头文件:#include “ev_progress.h”
3)ev_progress.cpp会用到预编译头文件,如果这里出错,请改为你的工程预编译头文件。(vc6一般是stdafx.h,而VC2022是pch.h)
4)然后可以开始使用了。详见后续多种使用场景。

3 .1 简单情况

最简单也是最常用的使用场景是在一个函数中,需要长时间计算,这时给一个进度条可提升交互体验,并可避免长时间纯计算引起的计算机假死(应用程序没有响应)现象。
举例说明:

void test_Progress_Simple()
{
	int i;

	//开始一个进度条
	EV_START_NEW_PROGRESS_AUTO(_T("Title"), _T("Prompt..."), NULL, 0, 1, 0);
	for (i = 0; i < 10000; ++i)
	{
		//设置进度条进度
		EV_DO_PROGRESS_CHECK_ABORT(i * 1.0 / 10000, NULL, NULL)
			return; //如果点击了“取消”按钮
		EV_END_DO_PROGRESS_CHECK_ABORT()
	}	
}

在这里插入图片描述

代码中主要有三行控制进度条的代码:

1)EV_START_NEW_PROGRESS_AUTO(lpstrTitle, lpstrMainPrompt, lpstrSubPrompt, dStart, dEnd, nShowSub):申明一个新的进度条。
lpstrTitle:进度条窗口的标题
lpstrMainPrompt:主进度条提示
lpstrSubPrompt:子进度条提示
dStart:主进度起始值。组件的进度基于0~1。
dEnd:主进度结束值。
nShowSub:是否显示子进度。0:不显示,1:显示。

2)EV_DO_PROGRESS_CHECK_ABORT(dValue, lpstrMainPrompt, lpstrSubPrompt):设置进度条进度的语句。
dValue:进度值。进度基于0~1。
lpstrMainPrompt:主进度条提示。这里可以改变它,不需要改变,设为NULL。
lpstrSubPrompt:子进度条提示。这里可以改变它,不需要改变,设为NULL。

3)EV_END_DO_PROGRESS_CHECK_ABORT():结束进度条进度的设置
组件支持取消操作,因此在这两句中间的代码,就是点击了“取消”之后,你需要执行的代码。如果不允许取消,两句中间可以空着。
组件在执行EV_DO_PROGRESS_CHECK_ABORT时,会处理Windows消息队列,防止消息堵塞,因此可以防止计算机没有响应的现象。

3.2 两个前后独立的进度条

组件支持顺序任意多个进度条,操作总是针对最后一个进度条操作。
举例说明:

//两个前后独立的进度条
void test_Progress_2()
{
	int i, j;

	//用应用程序的主图标作为进度条窗口图标
	EV_SET_PROGRESS_WINDOW_ICON(128);//IDR_MAINFRAME

	//开始一个进度条
	EV_START_NEW_PROGRESS_AUTO(_T("Title"), _T("Prompt..."), NULL, 0, 1, 0);
	for (i = 0; i < 10000; ++i)
	{
		//插入一个新的进度条
		if (i == 0)
		{
			EV_START_NEW_PROGRESS_AUTO(_T("Title2"), _T("Prompt2..."), NULL, 0, 1, 0);
			for (j = 0; j < 10000; ++j)
			{
				EV_DO_PROGRESS_CHECK_ABORT(j * 1.0 / 10000, NULL, NULL)
					; //如果点击了“取消”按钮,什么也不做(也即是不能取消)
				EV_END_DO_PROGRESS_CHECK_ABORT()
			}
		}
		
		//继续第一个进度条
		EV_DO_PROGRESS_CHECK_ABORT(i * 1.0 / 10000, NULL, NULL)
			return; //如果点击了“取消”按钮,终止函数运行
		EV_END_DO_PROGRESS_CHECK_ABORT()
	}
}

代码在新建一个进度条之后,马上建立了第二个进度条并操作,第二个进度条结束后,继续第一个进度条的操作。
同时该段代码用EV_SET_PROGRESS_WINDOW_ICON()函数设置了一下窗口的图标。你需要根据你的工程设置图标资源号。

3.3 实际应用的一般情况

实际应用中一般经常遇到进程分几段,每段会占用总进度一定占比,而每段又是调用的子函数,比如下面的示意性代码:

void xxx()
{
	//第1段 占总进度的 %0 ~ %30 
	Sub_Function1();

	//第2段 占总进度的 %30~100%
	Sub_Function2();
}

想实现上述功能,使用EvProgress将变得十分简单,实例如下:

//一般情况
bool Sub_Function1(int n)
{
	int j;
	for (j = 0; j < n * 1000; j++)
	{
		//只需关心本过程的进度值
		EV_DO_PROGRESS_CHECK_ABORT(j * 1.0 / (n * 1000), NULL, NULL);//按占比100%进度处理
			return false;
		EV_END_DO_PROGRESS_CHECK_ABORT();
	}
	return true;
}
void test_Progress_Normal()
{
	//开始一个进度条
	EV_START_NEW_PROGRESS_AUTO(_T("Title"), _T("Prompt..."), NULL, 0, 1, 0);

	//第1段 %0~%30 
	EV_SET_PROGRESS_RANGE(0, 0.3); //设置后续进度在总进度的占比范围
	Sub_Function1(30);

	//第2段 %30~100%
	EV_SET_PROGRESS_RANGE(0.3, 1); //设置后续进度在总进度的占比范围
	Sub_Function1(70);
}

如代码所示,在第一段,只需要用EV_SET_PROGRESS_RANGE设置该段在总进度的占比范围,然后调用子函数即可。而在子函数呢,只需按照100%的进度去赋进度值即可。第二段和第一段一样,只需要先设置该段在总进度的占比范围(0.3, 1)即可。

3.4 带子进度条

有时计算时间很长,主函数调用子函数,或主循环中带大计算量的子循环,为了防止看上去一动不动,组件支持一级子进度。
举例说明:

//带子进度条
bool Sub_Function();
void test_Progress_Sub()
{
	int i;

	EV_START_NEW_PROGRESS_AUTO(_T("waiting..."), _T("Main:"), _T("Sub"), 0.0, 1.0, 1/*子进度条数为1(1个子进度*/);
	for(i =0 ; i< 50; i++)
	{
        //因为外层循环是50次,所以每次子循环占据主进度1/50。模式为按比例。
		EV_START_SUB_PROGRESS(1.0/50/*本次子进度占主进度设置范围的1/50*/, 
                              EV_PROGRESS_MODE_SCALE_ABSOLUTE/*子进度按主进度占比通知主进度*/);
		
		if(!Sub_Function())
			return;

		EV_END_SUB_PROGRESS();
	}
}
bool Sub_Function()
{
	int j;
	for(j =0; j< 1000; j++)
	{
		//只需关心本过程的进度值
		EV_DO_PROGRESS_CHECK_ABORT((j*1.0 / 999), NULL, NULL);
			return false;
		EV_END_DO_PROGRESS_CHECK_ABORT();
	}
	return true;
}

在这里插入图片描述

EV_START_SUB_PROGRESS(dRange, nMode):开始一个子进度。
dRange:子进度占总进度值(0~1)。
nMode:
EV_PROGRESS_MODE_SCALE_ABSOLUTE:占主进度总范围比例(取值:0~1)
EV_PROGRESS_MODE_RANGE_ABSOLUTE:占主进度初始范围值(取值:0~1)

注意EV_DO_PROGRESS_CHECK_ABORT()总是针对当前计算过程中赋值。因此组件使用非常灵活实用。比如一个子过程可能被2个主函数调用(上面代码中Sub_Function作为一个子函数),并且占2个主函数的计算量不一样,但通过上述代码,只需主函数指定子函数的进度比,子函数就可以在2个不同地方良好工作。
甚至还有第三个主函数调用了子函数,但主函数并没有申请进度条,子函数中的EV_DO_PROGRESS_CHECK_ABORT()也会正常工作,只是什么都不做而已,但不会引起程序崩溃。

4 其他

4.1 使用限制

在一个作用域(就是一对{})里,只能声明一次EV_START_NEW_PROGRESS_AUTO()。例如下代码会产生编译错误:

void test_error()
{
	EV_START_NEW_PROGRESS_AUTO(_T("waiting1..."), _T("Main1:"), _T("Sub1"), 0.0, 1.0, 1);
    
    //...
    
    EV_START_NEW_PROGRESS_AUTO(_T("waiting2..."), _T("Main2:"), _T("Sub2"), 0.0, 1.0, 1);   
}

增加一个作用域,可以解决,代码如下:

void test_error()
{
   EV_START_NEW_PROGRESS_AUTO(_T("waiting1..."), _T("Main1:"), _T("Sub1"), 0.0, 1.0, 1);
   
   //...
   {
   	EV_START_NEW_PROGRESS_AUTO(_T("waiting2..."), _T("Main2:"), _T("Sub2"), 0.0, 1.0, 1);   
   }
}

4.2 其他全局宏(函数)

必须放在EV_START_NEW_PROGRESS_AUTO之前, 之后对所有进度条有效:

//	1)EV_SET_PROGRESS_WINDOW_ICON(UINT idIcon);//指定进度条对话框图标
//	2)EV_SET_PROGRESS_CONFIRM_CANCEL(BOOL bConfirm); //指定取消是否需要确认
//	3)EV_SET_PROGRESS_COLOR(DWORD forecolor, DWORD backcolor); //指定进度条前景色和背景色
//	4)EV_SET_PROGRESS_CTRL_SIZE(int width, int height); //指定进度条的宽度和高度
//	5)EV_SET_PROGRESS_BITMAP(UINT idFore, UINT idBack); //指定全局进度条的位图

4.3 当前进度条设置

必须放在EV_START_NEW_PROGRESS_AUTO之后,对当前进度条有效:

//	1)EV_SET_PROGRESS_STRINGS(LPCTSTR lpstrTitle, LPCTSTR lpstrMainPrompt, LPCTSTR lpstrSubPrompt);//指定显示的文本
//	2)EV_SET_SHOW_SUBPROGRESS(int nSubMark = 0, BOOL bUpdateWin = TRUE);
//	3)EV_GET_PROGRESS_RANGE(double& dStart, double& dEnd);//获取进度限定范围
//	4)EV_SET_PROGRESS_BITMAP_CURRENT(IDB_BITMAP_MAIN[, IDB_BITMAP_SUB]);//指定当前进度条的位图(优先于全局)

下载完整的代码资源。代码资源附带完整的VC实例工程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116863.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

技术开发107

技术开发107 业务内容&#xff1a; 汽车音响等汽车电子部件试制、电子设备部件试制、精密钣金试制精密钣金试制 公司简介&#xff1a; 代表&#xff1a;中山尚美 成立时间&#xff1a;1950年6月 资本金&#xff1a;1000万日元 员工数&#xff1a;15名 资格认证&#xff…

数智为线,经纬中国:新华三勾勒出的山河锦绣

刺绣&#xff0c;是中华民族源远流长的技艺美术。早在《尚书》中&#xff0c;就记载了章服制度“衣画而裳绣”。而刺绣之美之所以能够传承千年&#xff0c;形成中国审美的一张名片&#xff0c;就是因为传统的染色技艺不够精细&#xff0c;颜色常常浮在布匹表面&#xff0c;但刺…

【卫朋】营销技能:营销4P之外,还有这些经典理论

一提到市场营销&#xff0c;很多人都可能会联想到经典的营销4P理论&#xff0c;但你可能不知道的是&#xff0c;4P理论只是“4字营销理论家族”中的一员。 市场营销“4字家族”中的4P、4R、4C理论构成了市场营销的基础部分。 它们诞生于特殊的环境和年代&#xff0c;为当时的企…

Redis原理篇—内存回收

Redis原理篇—内存回收 笔记整理自 b站_黑马程序员Redis入门到实战教程 内存过期策略-过期key处理 Redis 之所以性能强&#xff0c;最主要的原因就是基于内存存储。然而单节点的 Redis 其内存大小不宜过大&#xff0c;会影响持久化或主从同步性能。 我们可以通过修改配置文件…

再学C语言16:表达式和语句

语句组成了C的基本程序的步骤&#xff0c;大多数语句由表达式构造而成 一、表达式 表达式&#xff08;expression&#xff09;由运算符和操作数组合构成 操作数是运算符操作的对象&#xff0c;可以是常量、变量或二者的组合 C的一个重要属性&#xff1a;每一个C表达式都有一…

Python 基础教程(1)——翻转字符串、集合运算、字符串、列表、元组、字典、数据类型转换、Python推导式、Python运算符、Python 数字类型转换、字符串

1.翻转字符串 def reverseWords(input):# 通过空格将字符串分隔符&#xff0c;把各个单词分隔为列表inputWords input.split(" ")# 翻转字符串# 假设列表 list [1,2,3,4], # list[0]1, list[1]2 &#xff0c;而 -1 表示最后一个元素 list[-1]4 ( 与 list[3]4 一样…

【C++进阶】特殊类设计

&#x1f387;C学习历程&#xff1a;入门 博客主页&#xff1a;一起去看日落吗持续分享博主的C学习历程博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 也许你现在做的事情&#xff0c;暂时看不到成果&#xff0c;但不要忘记&…

vue书写一个uni-app小程序

在本次文章中我来大致向大家介绍一下如何使用Hbuilder X来编写一个uni-app的小程序的项目&#xff0c;在此我只说编写的方法与方向&#xff0c;具体的操作留给大家去亲自实操哦。 1.起步&#xff08;创建一个uni-app框架&#xff09;&#xff1a; 首先&#xff0c;我们需要把…

低代码破解了软件开发“不可能三角”?我做了个测评...

老读者知道&#xff0c;K哥写了10几年代码&#xff0c;后来转做技术管理&#xff0c;现在是上市公司的技术高管。在我们软件行业有一条铁律&#xff1a;长周期、大规模的软件研发过程当中&#xff0c;想要维持良好的运作&#xff0c;需要解决&#xff1a;成本、效能、质量。而且…

Doris-查询(三)

目录1、查询设置1.1、增大内存1.2、修改超时时间1.3、查询重试和高可用1.3.1 代码方式1.3.2 JDBC Connector1.3.3 ProxySQL 方式2、简单查询3、Join查询3.1 Broadcast Join3.2 Shuffle Join&#xff08;Partitioned Join&#xff09;3.3 Colocation Join3.3.1 原理3.3.2 使用3.…

数字孪生电力3D可视化管控平台

当前&#xff0c;新一轮科技革命和产业变革加速演进&#xff0c;物联网、大数据、云计算、人工智能、5G等新一代信息技术快速发展。在众多技术手段中&#xff0c;数字孪生技术以虚实结合为主&#xff0c;架起虚拟世界与现实世界之间沟通的桥梁&#xff0c;为人们提供了更加便捷…

分享5款可以录屏的软件,录屏幕视频软件,亲测好用

很多小伙伴都会使用电脑来作为自己办公、娱乐、学习生活的工具。在电脑上安装录屏软件&#xff0c;可以轻松的协助我们进行网课录制、会议录制、影剧片段录制等。网络上的录屏软件有很多&#xff0c;今天小编分享5款亲测好用的录屏软件&#xff0c;一起来看看吧。 可以录屏的软…

数据结构进阶 二叉搜索树

作者&#xff1a;小萌新 专栏&#xff1a;数据结构进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍二叉搜索树并且模拟实现之 二叉搜索树二叉搜索树的概念节点类二叉搜索树类私有成员构造函数拷贝构造函数赋值运算符重载函数…

若想学 HTML,应从何入手?

前言 个人信息&#xff1a; 大三 工商管理 逻辑算清晰 无编程基础 想学网页设计&#xff0c;打算从HTML开始 。 下面是问题&#xff1a; 需要先学一些更基础的语言&#xff08;如C之类的&#xff09;吗&#xff1f;有何建议&#xff1a; &#xff08;1&#xff09;看哪些书、泡…

无忧·企业邮筒功能介绍

应用介绍 企业邮筒&#xff0c;基于B/S模式的邮件客户端&#xff0c;采用JVS的统一用户体系&#xff0c;作为JVS的协同办公的应用之一。 产品特点 私有化部署、支持多邮件账户、将多个邮件客户端统一为web操作、 软件架构 软件架构说明&#xff0c;JVS-mailbox是作为JVS基…

服装实体店运营需要的所有软件,合集在此!(建议收藏)实体店运营 实体店运营干货 实体店运营全流程所需系统推荐

随着信息化普及程度越来越高&#xff0c;各行各业的运转速度都在加快&#xff0c;做生意的老板们也开始发现&#xff0c;单靠以前的人工管理已经完全不够用了。 尤其是服装实体店&#xff0c;款式分类多&#xff0c;库存又容易挤压&#xff0c;更加需要有科学的手段去管控日常的…

MyBatis学习 | 缓存机制

文章目录一、一级缓存1.1 简介1.2 一级缓存的失效情况二、二级缓存2.1 简介2.2 二级缓存的使用学习地址&#x1f517; https://www.bilibili.com/video/BV1mW411M737https://www.bilibili.com/video/BV1NE411Q7Nx官网文档 一、一级缓存 1.1 简介 &#x1f4ac;概述&#xff1…

Spring与SpringBoot

目录 前言 1、Spring能做什么 1.1、Spring的能力 1.2、Spring的生态 1.3、Spring5重大升级 1.3.1、响应式编程 1.3.2、内部源码设计 2、为什么用SpringBoot 2.1、SpringBoot优点 2.2、SpringBoot缺点 3、时代背景 3.1、微服务 3.2、分布式 分布式的困难 分布式的…

迪文DGUS智能屏如何轻松实现3D动画

三维立体的视觉效果已经被广泛应用于人机交互中&#xff0c;三维图形逼真的显示效果往往可以更加直接的传递出视觉信息&#xff0c;减少用户的信息解读门槛。 传统的三维立体静态、动态画面的显示往往对于 GPU 的图像处理性能、显示带宽有较高要求&#xff0c;GPU 需要完成图形…

使用gs_probackup进行数据库物理备份与恢复

概述 物理备份与恢复适用于数据量大的场景&#xff0c;主要用于全量数据备份恢复&#xff0c;也可对整个数据库中的WAL归档日志和运行日志进行备份。openGauss提供了三种物理备份与恢复相关的工具&#xff1a;gs_backup、gs_basebackup和gs_probackup。三个工具的对比见下图。…