赞
踩
这个想法是在初学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函数或结构,请自行搜索,此处不做过多赘述。
学海无涯,力争上游 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。