图像处理时的undo, 可以用保存图片到硬盘的办法来实现,这个我做过,肯定可行。
而且我做的是无限次undo,也可历史回溯, 最近才改了一个bug(图片保存路径有错了)
用堆栈是错的, 堆栈是后进先出的,肯定不可行。
应该用可变长的队列,队列的总长度随操作的执行而增长。这样既可以undo
也可以redo, 还可以任意跳转到其中任何一步。
文本编辑的undo也可以这样做,只不过,每执行一步编辑操作后,都需要将当前操作
记录下来(例如记录当前光标所有位置,具体执行的操作等,具体怎么记录操作,你恐
怕要好好地研究一下),并保存到一个足够大的数组中。
nCurrentOperationSN : integer;
//当前动作的序号, 用于记录当前历史记录
nMaxOperationSN : integer;
//当前动作的序号, 用于记录当前历史记录
proceduredo
SthForUndo(sThisAction :string);
//为undo做准备
procedure TFormMain.DoSthForUndo(sThisAction :string);
//为undo做准备
begin
SaveCurrentBitmap(Image1.Picture.Bitmap, sCurrentFile , sThisAction);
MainMenu1.Items.Items[1].Items[0].Caption :='恢复 '+sThisAction;
MenuProcess;
end;
procedure TFormMain.MenuProcess;
begin
if nCurrentOperationSN>1 then
MainMenu1.Items.Items[1].Items[0].Caption :='恢复'+sHistory[nCurrentOperationSN-1];
if nCurrentOperationSN=1000 then
MainMenu1.Items.Items[1].Items[0].Caption :='恢复'+sHistory[1];
if nCurrentOperationSN < nMaxOperationSN then
MainMenu1.Items.Items[1].Items[1].Enabled :=true
else
MainMenu1.Items.Items[1].Items[1].Enabled :=false;
if nCurrentOperationSN<=0 then
//置灰菜单
begin
MainMenu1.Items.Items[1].Items[0].Enabled :=false;
MainMenu1.Items.Items[1].Items[2].Enabled :=false;
end
else
begin
MainMenu1.Items.Items[1].Items[0].Enabled :=true;
MainMenu1.Items.Items[1].Items[2].Enabled :=true;
end;
end;
procedure TFormMain.mnuUndoClick(Sender: TObject);
{var
myFormMain : TFormMain;
begin
myFormMain := TFormMain.Create(Self);
try
myFormMain.Show;
myFormMain.TrayIcon.Active :=false;
finally
// myFormMain.Free;
end;
}
var
Bitmap: TBitmap;
begin
with NewBMPFormdo
begin
ActiveControl := WidthEdit;
try
if Image1.Picture.Graphic.Width>0 then
WidthEdit.Text := IntToStr(Image1.Picture.Graphic.Width);
if Image1.Picture.Graphic.Height>0 then
HeightEdit.Text := IntToStr(Image1.Picture.Graphic.Height);
except
end;
if ShowModal <> idCancel then
begin
Bitmap := nil;
try
Bitmap := TBitmap.Create;
Bitmap.Width := StrToInt(WidthEdit.Text);
Bitmap.Height := StrToInt(HeightEdit.Text);
Image1.Picture.Graphic := Bitmap;
// sCurrentFile := EmptyStr;
finally
Bitmap.Free;
end;
end;
end;
end;
procedure TFormMain.mnuNextStepClick(Sender: TObject);
var
bmp : Tbitmap;
sTemp : string;
begin
try
if nCurrentOperationSN >= nMaxOperationSN then
exit;
bmp := TBitmap.Create;
if LoadNextBitmap(bmp, sCurrentFile, sTemp ) then
//载入指定历史图片, 返回当前操作名
begin
image1.Picture.Bitmap.Assign(bmp);
MainMenu1.Items.Items[1].Items[0].Caption :='恢复 '+sHistory[nCurrentOperationSN];
end;
MenuProcess;
except
end;
end;
procedure TFormMain.mnuLastStepClick(Sender: TObject);
var
bmp : Tbitmap;
sTemp : string;
begin
if nCurrentOperationSN <=0 then
exit;
bmp := TBitmap.Create;
if LoadLastBitmap(bmp, sCurrentFile, sTemp ) then
//载入指定历史图片, 返回当前操作名
begin
image1.Picture.Bitmap.Assign(bmp);
MainMenu1.Items.Items[1].Items[0].Caption :='恢复'+sHistory[nCurrentOperationSN];
end;
MenuProcess;
end;