如何使用Delphi在控制台应用程序中显示进度条?

如何使用Delphi在控制台应用程序中显示进度条?,delphi,console,Delphi,Console,我想在一个漫长的过程中在我的控制台应用程序中显示某种动画,但不知道如何做到这一点 我已经做了一项研究,但我发现的解决方案没有引起我的兴趣,或者我不愿意理解它们 我的应用程序加载一个文本文件,并通过搜索要替换的单词逐个遍历所有行 它可以是进度条或任何循环动画。很久很久以前;一个用来和主机交流的人,用一根管子显示这种类型的绿色字母。从那时起,除了使用命令行界面的程序实际上仍然与(虚拟)VT100的后端通信外,情况发生了很大变化。在很大程度上基于代码,这32个最低值对于控制屏幕上显示的位置非常重要。这

我想在一个漫长的过程中在我的控制台应用程序中显示某种动画,但不知道如何做到这一点

我已经做了一项研究,但我发现的解决方案没有引起我的兴趣,或者我不愿意理解它们

我的应用程序加载一个文本文件,并通过搜索要替换的单词逐个遍历所有行


它可以是进度条或任何循环动画。

很久很久以前;一个用来和主机交流的人,用一根管子显示这种类型的绿色字母。从那时起,除了使用命令行界面的程序实际上仍然与(虚拟)VT100的后端通信外,情况发生了很大变化。在很大程度上基于代码,这32个最低值对于控制屏幕上显示的位置非常重要。这就是为什么在某些环境中,新行仍然被编码为
#13
,在电传打字机上执行“回车”操作,而
#10
在链式进纸机上执行单行进纸操作。VT100通过修改位置以显示下一个接收到的字符来模拟相同的情况

因此,要覆盖控制台窗口中的屏幕内容,只需发送
#13
和新数据。例如:

procedure ShowProgress(Position,Max:integer);
var
  i,j:integer;
const
  BarWidth=28; //must be less than 79
begin
  Write(#13'[');
  j:=Position*BarWidth div Max;
  for i:=1 to BarWidth do
    if i<=j then Write('#') else Write('-');
  Write(']');
end;
过程显示进度(位置,最大值:整数);
变量
i、 j:整数;
常数
条宽=28//必须小于79
开始
写(#13'[');
j:=位置*最大杆宽div;
对于i:=1的宽度

如果我这里有一个示例,它将在一个循环中产生消息处理X of Y(Z%)…延迟,表示在循环中做某事所花费的时间。显然,这是一个人为的示例,但它显示了一种可能性。(同样很明显,您将用有意义的值替换消息中循环上限和Y的值,例如
TStringList.Count

进度指标快照


尝试此控制台应用程序:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Windows;


procedure ClearScreen;
var
  stdout: THandle;
  csbi: TConsoleScreenBufferInfo;
  ConsoleSize: DWORD;
  NumWritten: DWORD;
  Origin: TCoord;
begin
  stdout := GetStdHandle(STD_OUTPUT_HANDLE);
  Win32Check(stdout<>INVALID_HANDLE_VALUE);
  Win32Check(GetConsoleScreenBufferInfo(stdout, csbi));
  ConsoleSize := csbi.dwSize.X * csbi.dwSize.Y;
  Origin.X := 0;
  Origin.Y := 0;
  Win32Check(FillConsoleOutputCharacter(stdout, ' ', ConsoleSize, Origin,
    NumWritten));
  Win32Check(FillConsoleOutputAttribute(stdout, csbi.wAttributes, ConsoleSize, Origin,
    NumWritten));
  Win32Check(SetConsoleCursorPosition(stdout, Origin));
end;

var
  iFileLineCount : Integer;
  iCounter1,iCounter2 : Integer;
  iPercent : Integer;
begin


  try
    iFileLineCount := 12000;
    for iCounter1 := 1 to iFileLineCount do
      begin

        //do your application thing like reading file
        ClearScreen;
        iPercent :=  iCounter1 * 100 div iFileLineCount;
        for iCounter2 := 1 to iPercent do
          write('|');
        write(IntToStr(iPercent) + '%');
      end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;



end.
程序项目1;
{$APPTYPE控制台}
{$R*.res}
使用
System.SysUtils,Windows;
程序清除屏幕;
变量
stdout:THandle;
csbi:TConsoleScreenBufferInfo;
安慰:德沃德;
numwrited:DWORD;
来源:TCORD;
开始
stdout:=GetStdHandle(标准输出句柄);
Win32Check(stdoutINVALID\u HANDLE\u值);
Win32Check(GetConsoleScreenBufferInfo(stdout,csbi));
ConsoleSize:=csbi.dwSize.X*csbi.dwSize.Y;
原点X:=0;
原点Y=0;
Win32Check(FillConsoleOutputCharacter(标准输出)、控制台大小、原点、,
numwrited);
Win32Check(填写控制台输出属性(stdout、csbi.wAttributes、ConsoleSize、Origin、,
numwrited);
Win32Check(SetConsoleCursorPosition(stdout,Origin));
结束;
变量
iFileLineCount:整数;
i计数器1,i计数器2:整数;
i参数:整数;
开始
尝试
iFileLineCount:=12000;
对于iCounter1:=1到iFileLineCount do
开始
//你的应用程序像读取文件一样工作吗
透明屏幕;
iPercent:=iCounter1*100 div iFileLineCount;
对于iCounter2:=1到iPercent do
写(“|”);
写入(IntToStr(iPercent)+'%');
结束;
除了
关于E:Exception-do
Writeln(E.ClassName,“:”,E.Message);
结束;
结束。
对于像dos这样的操作系统,这是在控制台应用程序中显示进度条的老方法,当然有很多更好的方法,但它只是工作而已。
德里不支持CRT工具,因此我添加了一个用于清除屏幕的
过程。

如果进度指示器只是一个递增的整数,请使用
write
将其写入控制台(而不是
writeln
)然后是回车符。这样,它将覆盖上一个值。@Jerry Dodge应用程序有点复杂,只是解释了您要更改的部分。我更喜欢字符序列
-\\\\;/
,在屏幕上相同的位置重复,直到过程完成。嗯,这个q真的保证3 answe吗rs?@MartynA:为什么不呢?我想很多人对此都有现成的答案,现在他们想展示一下他们是如何做到的。
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Windows;


procedure ClearScreen;
var
  stdout: THandle;
  csbi: TConsoleScreenBufferInfo;
  ConsoleSize: DWORD;
  NumWritten: DWORD;
  Origin: TCoord;
begin
  stdout := GetStdHandle(STD_OUTPUT_HANDLE);
  Win32Check(stdout<>INVALID_HANDLE_VALUE);
  Win32Check(GetConsoleScreenBufferInfo(stdout, csbi));
  ConsoleSize := csbi.dwSize.X * csbi.dwSize.Y;
  Origin.X := 0;
  Origin.Y := 0;
  Win32Check(FillConsoleOutputCharacter(stdout, ' ', ConsoleSize, Origin,
    NumWritten));
  Win32Check(FillConsoleOutputAttribute(stdout, csbi.wAttributes, ConsoleSize, Origin,
    NumWritten));
  Win32Check(SetConsoleCursorPosition(stdout, Origin));
end;

var
  iFileLineCount : Integer;
  iCounter1,iCounter2 : Integer;
  iPercent : Integer;
begin


  try
    iFileLineCount := 12000;
    for iCounter1 := 1 to iFileLineCount do
      begin

        //do your application thing like reading file
        ClearScreen;
        iPercent :=  iCounter1 * 100 div iFileLineCount;
        for iCounter2 := 1 to iPercent do
          write('|');
        write(IntToStr(iPercent) + '%');
      end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;



end.