2012-12-09 5 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가 응답하지 않습니다. 또한 코드가 스레드로부터 안전한지 확인해야합니다.

아무튼 스레드 내부에서 진행률 표시 줄을 매번 업데이트해야합니다. 외부 루프와 내부 루프가있는 경우 외부 루프가 1 초에 한 번 반복되는 경우 해당 위치의 진행률 막대를 업데이트 할 수 있습니다. 하나의 큰 루프 만있는 경우 모든 반복마다 진행률 막대를 업데이트하지 않을 수도 있습니다. 예를 들어, 단 하나의 반복은 아마도 수 밀리 초 만에 완료 될 수 있습니다.

대신 1 초마다 한 번 진행률 막대를 업데이트 할 수 있습니다. 이 작업을 수행하려면 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

나는 여전히 초보자이므로 나에게 매우 혼란 스럽다. 그러나 나는 그것을 시도 할 것이다. 도움을 주셔서 감사합니다. –

관련 문제