【C\C++】利用Windows API实现简单控制台动态进度条(动画)

C\C++简单控制台进度条动画

导语

这个想法是在初学C语言时出现的,当时想要实现动态的过程,用来优化程序的运行界面,奈何不了解Windows句柄,一直无法实现,直到学习了一些相关知识,成功把它实现出来了。不过发现实际意义并不大,仅仅是设计过程的有趣,因此将这个小功能模块分享出来,同时也作为自己学习过程的记录。

效果图

加载中
加载完成
动态过程

所需头文件

C++:

#include <iostream>
#include <Windows.h>
#include <time.h>

C语言请把iostream改成stdio.h,并更改函数中的输出部分

源代码

获取光标位置:

COORD getXY()							//通过WindowsAPI函数获取光标的位置
{
	CONSOLE_SCREEN_BUFFER_INFO pBuffer;

	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
	//利用标准输出句柄获得光标坐标信息

	return COORD{ pBuffer.dwCursorPosition.X, pBuffer.dwCursorPosition.Y };	
	//封装为表示坐标的COORD结构
}

获取缓冲区大小:

COORD getScrnInfo()										//获取控制台窗口缓冲区大小
{
	HANDLE hStd = GetStdHandle(STD_OUTPUT_HANDLE);		//获得标准输出设备句柄
	CONSOLE_SCREEN_BUFFER_INFO scBufInf;				//定义一个窗口缓冲区信息结构体

	GetConsoleScreenBufferInfo(hStd, &scBufInf);		//获取窗口缓冲区信息

	return scBufInf.dwSize;								//返回窗口缓冲区大小
}

移动光标位置:

void moveXY(COORD pstn)
{
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pstn);
	//通过标准输出句柄控制光标的位置
}

清除部分屏幕内容:(C语言请自行改动输出部分)即:更改std::cout部分

void clearDisplay(COORD firstPst, COORD lastPst)		//清除部分屏幕内容,从firstPst坐标到lastPst坐标之间的内容
{
	int yDValue(lastPst.Y - firstPst.Y);					//记录首末位置纵坐标差值,控制迭代次数

	COORD size(getScrnInfo());								//记录目前控制台缓冲区大小

	moveXY(firstPst);							//移动光标到首位置
	for (int y(0); y <= yDValue; y++)			//一层循环控制清除行数
	{
		for (int x(firstPst.X); x <= size.X; x++)			//二层循环避免重复清除
		{
			std::cout << ' ';						//输出一个空格来覆盖原内容,达到清除效果
			int px;									//记录光标当前位置的横坐标
			if (x != size.X)
				px = x + 1;
			else
				px = 0;
			if (y == yDValue&&px == lastPst.X)		//与光标末位置作对比,达到末位置即退出循环
				break;
		}
	}
	moveXY(firstPst);
}

进度条图像显示:(C语言请自行改动输出部分

void loading()									//等待界面,模拟动态进度条过程
{
	COORD headPst(getXY());						//记录最初位置,便于结束后清除进度条内容
	HANDLE hStd(GetStdHandle(STD_OUTPUT_HANDLE));
	CONSOLE_CURSOR_INFO  cInfo;
	GetConsoleCursorInfo(hStd, &cInfo);			//获取光标信息的句柄
	cInfo.bVisible = false;						//修改光标可见性
	SetConsoleCursorInfo(hStd, &cInfo);			//设置光标不可见

	std::cout << "请等待";
	COORD firstPst;								//存储光标坐标,为清除做铺垫
	COORD lastPst;

	int n(0);									//模拟进度条数字
	int m(0);									//记录进度条方块总数
	srand((unsigned)time(NULL));				//取时间作为随机数种子,避免伪随机数
	while (n < 100)								//达到较好的动态效果
	{
		m = n / 5;
		n += rand() % 14 + 1;
		if (n < 100)
		{
			for (int i(n / 5 - m); i>0; i--)
				std::cout << "█";
			firstPst = getXY();						//获取输出前坐标
			std::cout << n << "%";					//输出百分比进度条
			lastPst = getXY();						//获取输出之后的光标位置
		}
		else
		{
			n = 100;								//最大值为100,达到则退出操作
			std::cout << "█";
			std::cout << n << "%";
			lastPst = getXY();
			break;
		}

		Sleep(80);
		clearDisplay(firstPst, lastPst);		//清除现有图形,重新绘制
	}

	clearDisplay(headPst, lastPst);				//清除进度条图形
	cInfo.bVisible = true;						//光标可见性改为可见
	SetConsoleCursorInfo(hStd, &cInfo);
}

总结

此小部件是本人学习过程中的一点小玩意,希望能对其他初学者有一点启发。
代码中所出现的Windows API函数或结构,请自行搜索,此处不做过多赘述。

学海无涯,力争上游
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值