[原创]ConsoleApplication ProgressBar

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

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值