2017-11-10 5 views
2

私は長いプロセスの間、私のコンソールアプリケーションに何らかのアニメーションを表示したいと思います。Delphiを使用してコンソールアプリケーションにプログレスバーを表示する方法は?

私は既に研究を行っていますが、私が見つけた解決策は興味を起こさなかったし、私はそれらを理解することができなかった。

私のアプリケーションは、テキストファイルを読み込み、置換する単語を検索することによって、すべての行を1つずつトラバースします。

これはプログレスバーまたはループアニメーションです。

+2

進捗インジケータが単なる増加した整数の場合は、 'write'(' writeln'ではなく)とそれに続くキャリッジリターンを使用してコンソールに書き込みます。これにより、以前の値が上書きされます。 – MartynA

+0

@ジェリードッジあなたが変更したい部分を説明したところで、アプリケーションは少し複雑です。 – Anderson

+0

私は ' - \ |/'、プロセスが終了するまで画面上の同じ場所で繰り返します。 –

答えて

9

メッセージを生成するサンプルは次のとおりです。Y(Z%)...のXをループ内で処理し、ループ内で何かを実行するのにかかる時間を表す遅延があります。明らかに、それは人為的な例ですが、1つの可能性を示しています。 (また明らかに、このようなTStringList.Countなどの意味のある値を持つメッセージループとYの上限値を置き換えることになる。)

program Project1; 

{$APPTYPE CONSOLE} 

uses 
    System.SysUtils; 

var 
    i: Integer; 
    StopValue, Pct: Integer; 

(* 
    #13 is a carriage return, which moves the cursor back to the 
    left side of the console without adding a line feed (#10). It 
    allows writing on the same line over the same content without 
    moving to the next line. See the demo output. 
*) 
const 
    StatusMsg = #13'Processing %d of %d (%d%%) ...'; 

begin 
    StopValue := 150;  // Replace with your upper limit, e.g. StringList.Count 
    for i := 1 to StopValue do 
    begin 
    Pct := Trunc((i * 1.0/StopValue) * 100); 
    Write(Format(StatusMsg, [i, StopValue, Pct])); 
    (**************************************************************** 
     Note: The call to Sleep here is only to introduce an artificial 
     delay in the loop in order to allow the progress to be seen. 
     Otherwise, the empty loop runs so fast that it's not clear when 
     the progress increments are shown. 

     Clearly, you would replace the call to Sleep with your code to 
     actually do some work, such as processing each line of the text 
     file. 

     Explained in detail for clarity, as some commenters have indicated 
     they're not capable of understanding why a call to Sleep is used 
     here, so adding this unnecessarily large comment is needed for them. 
    ****************************************************************) 
    Sleep(250); 
    end; 
    Write(#13'Processing complete. Press Enter to quit.'); 
    ReadLn; 
end. 

進捗インジケータ

enter image description here

のスナップショット
3

長い、長い時間前。 1つは、VT100の緑色の文字を表示するチューブでメインフレームと通信するために使用されました。それ以来、コマンドラインインターフェイスを使用しているプログラムは、実際には(バーチャル)VT100のバックエンドと通信しています。コードASCIIに大きく基づいているため、画面上のどこに表示されたかを制御するには、これらの最低値が重要です。そのため、新しいタイプのラインは、テレタイプのライターで「キャリッジリターン」を行う#13と、チェーンフィード用紙に1本のラインを送る#10の2種類があります。 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; 

WriteLn;(実際Write(#13#10);である)、または#13と全体のバーを上書きするのに十分な長さで始まる何か他のものとのいずれかで終わります。

2

このコンソールアプリケーションを試してみてください。

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. 

これが行うようなOSのコンソールアプリケーションでプログレスバーを表示する古い方法です。もちろん、より良い方法がたくさんありますが、うまくいくだけです。 デリーはCRTツールをサポートしていなかったので、画面をクリアするためにProcedureを追加します。

関連する問題