0

重複の可能性:
プログレスバーを表示するには?

steganalisys アプリケーションを作成しました。進行状況バーを追加して、プロセスの進行時間を示したいと考えています。

procedure TForm2.Button2Click(Sender: TObject);
var
   q,x,y,leastSigBit,currentPixel,newPixelValue: integer;
   pixels: PByteArray;
   bmp: TBitmap;
  begin

   memo1.lines.clear;
   Image2.Picture.Assign(Image1.Picture.Bitmap);
   bmp := Image2.Picture.Bitmap;

   for y := 0 to bmp.Height-1 do
   begin
      pixels := bmp.ScanLine[y];
      for x := 0 to bmp.Width-1 do
      begin
         currentPixel := pixels[x];
         leastSigBit := getBit(currentPixel, 0);
         newPixelValue:=setBit(newPixelValue ,7,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,6,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,5,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,4,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,3,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,2,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,1,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,0,leastSigBit);
        end;

         pixels[x] := newPixelValue;
         memo1.lines.append('pixel ke ' + inttostr(x) + ',' + inttostr(y) + ' desimal ' + inttostr(currentPixel) + ' (biner ' + toBinary(currentPixel) + ') ' +
         ' desimal baru ' + inttostr(newPixelValue) + ' (biner ' + toBinary(newPixelValue) + ')');
        end;
   end;
   memo1.lines.append('All done!');
   Button4.Enabled:=True;
   Button2.Enabled:=False;
   Button1.Enabled:=False;
   Button5.Enabled:=True;
        end;

プロセスの進行状況バーを作成するにはどうすればよいですか? コマンドの進行状況バーをどこに配置する必要がありますか?

4

1 に答える 1

4

このようなことを行う正しい方法は、バックグラウンド スレッドで計算を行うことです。そうしないと、GUI がフリーズし、Abortボタンの追加に問題が発生する可能性があります。TThreadしたがって、これを適切に行うには、スレッド (例: ) の使用方法を学ぶ必要があります。そして、コードはスレッドセーフでなければならず、スレッドコードと GUI の間で安全な方法 (メッセージなどを使用するなど) でのみ通信する必要があります。主なアイデアは私の以前の回答にあります。

いずれにせよ、教育目的または個人的な必要性のためにこれを行いたい場合、おそらく上記の問題はそれほど深刻ではありません. そして、次のように簡単に実行できます。

procedure TForm2.Button2Click(Sender: TObject);
var
  ...
begin

  ProgressBar1.Min := 0;
  ProgressBar1.Max := bmp.Height;
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;

  for y := 0 to bmp.Height-1 do
  begin

    for x := 0 to bmp.Width-1 do
    begin
    end;

    ProgressBar1.StepIt;
    ProgressBar1.Update;

  end;

end;

これを試すには、新しい VCL プロジェクトを作成します。TProgressBaraと aを追加しTButtonます。ボタンのOnClick場合は、次のコードを追加します。

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j: integer;
begin
  ProgressBar1.Min := 0;
  ProgressBar1.Max := 100;
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;

  for i := 0 to 99 do
  begin

    for j := 0 to 200 do
    begin
      sleep(1);
    end;

    ProgressBar1.StepIt;
    ProgressBar1.Update;

  end;
end;

ただし、このアプローチの最も重要な裏側に注意してください。「計算」全体でアプリケーションがフリーズします。アプリケーション ウィンドウを移動することさえできない可能性があり、その GUI を操作することはできません。Windows はプログラムがフリーズしたと報告し、プログラムを終了してバグ レポートを送信するオプションを提供することさえあります...最後に、GUI 全体がダウンしているため、[計算を停止] ボタンを追加する機会はありません。ソリューション?汚いものは使用することProcessMessagesであり、他の汚いトリックです。適切なのは、既に述べたように、計算を独自のスレッドに入れることです。

于 2012-12-09T20:49:24.110 に答える