2012-12-09 177 views
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; 

我該如何爲進程設置進度條?以及我必須在哪裏放置命令進度條?

+0

@TLama:好吧,但是如果這是在GUI線程中運行的,那麼就有問題。 –

+1

您需要將計算移入單獨的線程。 –

+0

@Andreas,我寧願刪除我的評論... – TLama

回答

6

首先,您需要將代碼移至其自己的線程。否則,GUI將不會響應。您還必須確保代碼是線程安全的。

無論如何,在線程內部,你需要不時地更新進度條。如果碰巧你有一個外部循環和一個內部循環,外部循環每秒迭代一次,你可以在那個地方更新進度條。如果你只有一個大循環,你可能不想在每次迭代時更新進度條;例如,一次迭代可能只需幾毫秒即可完成。

相反,您可以確保每秒鐘更新一次進度條。要做到這一點,你可以用GetTickCount

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

這也顯示了一種方法來更新進度條 - 簡單地張貼的消息!您也可以定義自己的信息並將其發送給主要來源。

+0

我在哪裏下訂單? 我是否必須創建一個新的程序或功能? –

+0

我不知道'訂單'是什麼。但是上面的代碼片段應該放在'TThread.Execute'的'最內層循環'中。您必須學會如何使用線程才能正確完成此任務,並且需要相當多的知識和努力。我的回答只給出了主要的想法和原則。 –

+0

我仍然是一個新手,所以它是我很困惑,但我會嘗試,,,謝謝你的幫助。 –