我创建了一个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;
如何为流程制作进度条?我必须把命令进度条放在哪里?
答案 0 :(得分:4)
执行此类操作的正确方法是在后台线程中执行计算。否则,您的GUI将冻结,并且您可能无法添加Abort
按钮。因此,您必须学习如何使用线程(例如TThread
)来正确执行此操作。然后,您的代码必须是线程安全的,并且您应该只能以安全的方式在线程代码和GUI之间进行通信,例如,使用消息。主要观点见my previous answer。
无论如何,如果你想为教育用户或私人需要这样做,也许上面提到的问题并不那么严重。然后你可以这样做:
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项目。添加TProgressBar
和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
和其他肮脏的技巧。正确的方法是将计算放在自己的线程中,如前所述。