Reputation: 59
I created a steganography(hide text in bitmap) application and I want to add a progress bar to show how long the process works.
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;
how do I make a progress bar for the process? and where I have to put the command progress bar?
Upvotes: 1
Views: 2446
Reputation: 108963
First, you need to move the code to its own thread. Otherwise the GUI will not respond. You also have to make sure the code is thread-safe.
Anyhow, inside the thread, you need to update the progress bar every now and then. If it so happens that you have an outer loop and an inner loop, where the outer loop iterates once a second or so, you could update the progress bar at that place. If you only have one big loop, you might not want to update the progress bar at every iteration; for instance, a single iteration might perhaps be done in only a few milliseconds.
Instead, you can make sure to update the progress bar once every second, or so. To accomplish this, you can use GetTickCount
:
tc := GetTickCount;
if Terminated then Exit;
if tc - oldtc > 1000 then
begin
PostMessage(FProgressBarHandle, PBM_SETPOS, TheNewPosition, 0);
oldtc := tc;
end;
This also shows a way to update the progress bar -- simply post it a message! You could also define your own message and send it to the main from.
Upvotes: 6