1

ステガノグラフィー (ビットマップ内のテキストを非表示) アプリケーションを作成しました。進行状況バーを追加して、プロセスの動作時間を表示したいと考えています。

procedure TForm1.Button2Click(Sender: TObject);
var
   x,y,i,currentBit,bitInChar,currentChar,currentPixel,newPixelValue,pixelsToSkip,skippedPixels: integer;
   pixels: PByteArray;
   bmp: TBitmap;
   stringToHide: string;
begin
if Image1.Picture.Bitmap=nil then
showmessage('gambar belum dipilih')
else
   memo1.lines.clear;
   stringToHide := AntiKeyLoggerMemo1.text;

   stringToHide:= stringToHide + chr(terminator); // add terminator to indicate end of text
   Image2.Picture.Assign(Image1.Picture.Bitmap);
   bmp := Image2.Picture.Bitmap;
   x := 0;
   y := 0;
   pixels := bmp.ScanLine[y];

   // iterate over the chars in the string we want to hide
   for i := 1 to length(stringToHide) do
   begin
      currentChar := ord(stringToHide[i]);
      memo1.lines.append('');
      memo1.lines.append('Sembunyikan ' + stringToHide[i] + ' - Ascii ' + inttostr(currentChar) + ' (biner ' + toBinary(currentChar) + ')');
      // iterate over the bits in the current char
      for currentBit := 7 downto 0 do
      begin
         begin
            if (i = 1) and (currentBit = 7) then
               pixelsToSkip := 0
            else
               pixelsToSkip := 1;
         end;
         for skippedPixels := 1 to pixelsToSkip do
         begin
            inc(x);
            if x = bmp.width then
            begin
               x := 0;
               inc(y);
               if (y = bmp.height) and (i < length(stringToHide)) then raise Exception.create('gambar terlalu kecil');
               pixels := bmp.ScanLine[y];
            end;
         end;
         bitInChar := getBit(currentChar, currentBit);
         // get the value of the pixel at x,y
         currentPixel := pixels[x];
         // set the least significant bit of the pixel to the bit we read from the char
         newPixelValue := setBit(currentPixel, 0, bitInChar);
         pixels[x] := newPixelValue;
         memo1.lines.append('Bit karakter ' + inttostr(currentBit) + '=' + inttostr(bitInChar) +
            ', 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 ;
   Button5.Enabled:=True;
   Button1.Enabled:=False;
   AntiKeyLoggerMemo1.ReadOnly:=True;
     end;   

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

4

1 に答える 1

6

まず、コードを独自のスレッドに移動する必要があります。そうしないと、GUI は応答しません。コードがスレッドセーフであることも確認する必要があります。

とにかく、スレッド内では、進行状況バーを時々更新する必要があります。外側のループと内側のループがあり、外側のループが 1 秒に 1 回程度繰り返される場合は、その場所の進行状況バーを更新できます。大きなループが 1 つしかない場合は、反復ごとにプログレス バーを更新したくない場合があります。たとえば、1 回の反復はおそらく数ミリ秒で完了します。

代わりに、プログレス バーを 1 秒ごとに更新するようにすることができます。これを実現するには、次を使用できますGetTickCount

tc := GetTickCount;
if Terminated then Exit;
if tc - oldtc > 1000 then
begin
  PostMessage(FProgressBarHandle, PBM_SETPOS, TheNewPosition, 0);
  oldtc := tc;
end;

これは、プログレス バーを更新する方法も示しています。メッセージを投稿するだけです。独自のメッセージを定義して、メインの送信元に送信することもできます。

于 2012-12-09T19:38:26.767 に答える