博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[原创]ConsoleApplication ProgressBar
阅读量:4951 次
发布时间:2019-06-11

本文共 4651 字,大约阅读时间需要 15 分钟。

很抱歉各位看官,不太会排版丑陋了点,但是重点很清晰。

 

因本人的工作原因,大部分时间都在和控制台打交道,话说无论写什么控制台处理程序都有进度显示,方便直观。假设如果仅使用文件方式记录进度的话相当的麻烦,当然这个用作记录日志的话另当别论了。本文为了方便查看处理进度而特意在ConsoleApplication ProgressBar花了1个小时而开发的一个进度条控件类。

 

首先例举两个个常用的记录进度方式:

1、Console.Write

如图:

这种是最常见的,没什么好不好之说,但是不好的地方显而易见:屏幕一刷而过,当有其他的信息需要打印的时候还得翻滚动条。如果进度太长就无奈了。

2、Console.Title

如图:

 

这个用的相对比较少,如果开的比较多控制台的话,Title上原本的信息就没有了。

3、ConsoleApplication ProgressBar

如图:

 

 

综合前面两种方式,后者是最为方便的。好处我想不用我多说了。

 

下面奉上源码

 

调用示例:

class Program
    {
        
static 
void Main(
string[] args)
        {
            Random r = 
new Random();
            
while (
true)
            {
                ConsoleProgressBar bar = 
new ConsoleProgressBar(
"
测试ConsoleApplication ProgressBar
");
                
int c = r.Next(
534);
                
for (
int i = 
1; i <= c; i++)
                {
                    bar.Update(i, c, 
string.Format(
"
完成进度:{0}/{1}
", i, c));
                    System.Threading.Thread.Sleep(
10);
                }
                
//
 等待退出 
                Console.ReadKey(
true);
            }    
        }
    }

 

源码:

 
public 
class ConsoleProgressBar
    {
        
int left = 
0;
        
int backgroundLength = 
50;
        
#region [ window api ]
        ConsoleColor colorBack = Console.BackgroundColor;
        ConsoleColor colorFore = Console.ForegroundColor;
        
private 
const 
int STD_OUTPUT_HANDLE = -
11;
        
private 
int mHConsoleHandle;
        COORD barCoord;
        [StructLayout(LayoutKind.Sequential)]
        
public 
struct COORD
        {
            
public 
short X;
            
public 
short Y;
            
public COORD(
short x, 
short y)
            {
                X = x;
                Y = y;
            }
        }
        [StructLayout(LayoutKind.Sequential)]
        
struct SMALL_RECT
        {
            
public 
short Left;
            
public 
short Top;
            
public 
short Right;
            
public 
short Bottom;
        }
        [StructLayout(LayoutKind.Sequential)]
        
struct CONSOLE_SCREEN_BUFFER_INFO
        {
            
public COORD dwSize;
            
public COORD dwCursorPosition;
            
public 
int wAttributes;
            
public SMALL_RECT srWindow;
            
public COORD dwMaximumWindowSize;
        }
        [DllImport(
"
kernel32.dll
", EntryPoint = 
"
GetStdHandle
", SetLastError = 
true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        
private 
static 
extern 
int GetStdHandle(
int nStdHandle);
        [DllImport(
"
kernel32.dll
", EntryPoint = 
"
GetConsoleScreenBufferInfo
", SetLastError = 
true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        
private 
static 
extern 
int GetConsoleScreenBufferInfo(
int hConsoleOutput, 
out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
        [DllImport(
"
kernel32.dll
", EntryPoint = 
"
SetConsoleCursorPosition
", SetLastError = 
true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        
private 
static 
extern 
int SetConsoleCursorPosition(
int hConsoleOutput, COORD dwCursorPosition);
        
public 
void SetCursorPos(
short x, 
short y)
        {
            SetConsoleCursorPosition(mHConsoleHandle, 
new COORD(x, y));
        }
        
public COORD GetCursorPos()
        {
            CONSOLE_SCREEN_BUFFER_INFO res;
            GetConsoleScreenBufferInfo(mHConsoleHandle, 
out res);
            
return res.dwCursorPosition;
        }
        
#endregion
        
public ConsoleProgressBar(
string title, 
int left = 
10)
        {
            Console.WriteLine();
            
//
获取当前窗体句柄
            mHConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
            
//
获取当前窗体偏移量
            barCoord = 
this.GetCursorPos();
            
this.left = left;
            
//
获取字符长度
            
int len = GetStringLength(title);
            
//
设置标题的相对居中位置
            Console.SetCursorPosition(left + (backgroundLength / 
2 - len), barCoord.Y);
            Console.Write(title);
            
//
写入进度条背景
            Console.BackgroundColor = ConsoleColor.DarkCyan;
            Console.SetCursorPosition(left, barCoord.Y + 
1);
            
for (
int i = 
0; ++i <= backgroundLength; )
                Console.Write(
"
 
");
            Console.WriteLine();
            Console.BackgroundColor = colorBack;
        }
        
///
 
<summary>
        
///
 更新进度条
        
///
 
</summary>
        
///
 
<param name="current">
当前进度
</param>
        
///
 
<param name="total">
总进度
</param>
        
///
 
<param name="message">
说明文字
</param>
        
public 
void Update(
int current, 
int total, 
string message)
        {
            
//
计算百分比
            
int i = (
int)Math.Ceiling(current / (
double)total * 
100);
            Console.BackgroundColor = ConsoleColor.Yellow;
            Console.SetCursorPosition(left, barCoord.Y + 
1);
            
//
写入进度条
            StringBuilder bar = 
new StringBuilder();
            
//
当前百分比*进度条总长度=要输出的进度最小单位数量
            
int count = (
int)Math.Ceiling((
double)i / 
100 * backgroundLength);
            
for (
int n = 
0; n < count; n++) bar.Append(
"
 
");
            Console.Write(bar);
            
//
设置和写入百分比
            Console.BackgroundColor = colorBack;
            Console.ForegroundColor = ConsoleColor.Green;
            Console.SetCursorPosition(left + backgroundLength, barCoord.Y + 
1);
            Console.Write(
"
 {0}% 
", i);
            Console.ForegroundColor = colorFore;
            
//
获取字符长度
            
int len = GetStringLength(message);
            
//
获取相对居中的message偏移量
            Console.SetCursorPosition(left + (backgroundLength / 
2 - len), barCoord.Y + 
2);
            Console.Write(message);
            
//
进度完成另起新行作为输出
            
if (i >= 
100) Console.WriteLine();
        }
        
///
 
<summary>
        
///
 获取字符长度
        
///
 
</summary>
        
///
 
<remarks>
中文和全角占长度1,英文和半角字符2个字母占长度1
</remarks>
        
///
 
<param name="message"></param>
        
///
 
<returns></returns>
        
private 
int GetStringLength(
string message)
        {
            
int len = Encoding.ASCII.GetBytes(message).Count(b => b == 
63);
            
return (message.Length - len) / 
2 + len;
        }
    }

 

转载于:https://www.cnblogs.com/xuyi/archive/2012/10/25/2738911.html

你可能感兴趣的文章
几种图表库
查看>>
揭秘:黑客必备的Kali Linux是什么,有哪些弊端?
查看>>
linux系统的远程控制方法——学神IT教育
查看>>
springboot+mybatis报错Invalid bound statement (not found)
查看>>
Linux环境下SolrCloud集群环境搭建关键步骤
查看>>
P3565 [POI2014]HOT-Hotels
查看>>
UVa11078:Open Credit System
查看>>
MongoDB的简单使用
查看>>
git clone 遇到的问题
查看>>
hdfs 命令使用
查看>>
hdu 1709 The Balance
查看>>
prometheus配置
查看>>
定宽320 缩放适配手机屏幕
查看>>
BZOJ 2120 数颜色 【带修改莫队】
查看>>
【noip2004】虫食算——剪枝DFS
查看>>
Codeforces 40 E. Number Table
查看>>
CLR via C#(第3 版)
查看>>
java语法之final
查看>>
关于响应式布局
查看>>
详解ASP.Net 4中的aspnet_regsql.exe
查看>>