Dan*_*man 2 delphi paint bitmap delphi-7 undo-redo
我需要能够在我的简单delphi绘制中进行Undo和Redo操作.所以我决定制作一些容器来保存历史记录(不是完整的历史记录,只有少数以前的位图文件).
unit HistoryQueue;
interface
uses
Graphics;
type
myHistory = class
constructor Create(Size:Integer);
public
procedure Push(Bmp:TBitmap);
function Pop():TBitmap;
procedure Clean();
procedure Offset();
function isEmpty():boolean;
function isFull():boolean;
function getLast():TBitmap;
protected
end;
var
historyQueueArray: array of TBitmap;
historyIndex, hSize:Integer;
implementation
procedure myHistory.Push(Bmp:TBitmap);
var tbmp:TBitmap;
begin
if(not isFull) then begin
Inc(historyIndex);
historyQueueArray[historyIndex]:=TBitmap.Create;
historyQueueArray[historyIndex].Assign(bmp);
end else begin
Offset();
historyQueueArray[historyIndex]:=TBitmap.Create;
historyQueueArray[historyIndex].Assign(bmp);
end;
end;
procedure myHistory.Clean;
var i:Integer;
begin
{ for i:=0 to hSize do begin
historyQueueArray[i].Free;
historyQueueArray[i].Destroy;
end; }
end;
constructor myHistory.Create(Size:Integer);
begin
hSize:=Size;
SetLength(historyQueueArray, hSize);
historyIndex:=-1;
end;
function myHistory.isEmpty: boolean;
begin
Result:=(historyIndex = -1);
end;
function myHistory.isFull: boolean;
begin
Result:=(historyIndex = hSize);
end;
procedure myHistory.Offset;
var i:integer;
begin
//historyQueueArray[0]:=nil;
for i:=0 to hSize-1 do begin
historyQueueArray[i]:=TBitmap.Create;
historyQueueArray[i].Assign(historyQueueArray[i+1]);
end;
end;
function myHistory.Pop: TBitmap;
var
popBmp:TBitmap;
begin
popBmp:= TBitmap.Create;
popBmp.Assign(historyQueueArray[historyIndex]);
Dec(historyIndex);
Result:=popBmp;
end;
function myHistory.getLast: TBitmap;
var
tBmp:TBitmap;
begin
tBmp:= TBitmap.Create;
tBmp.Assign(historyQueueArray[historyIndex]);
Result:=tBmp;
end;
end.
Run Code Online (Sandbox Code Playgroud)
在我的程序中,我使用它.
保存在历史中:
procedure TMainForm.FormCreate(Sender: TObject);
begin
{...}
picHistory:=myHistory.Create(10); //FOR UNDO
tempHistory:=myHistory.Create(10); //FOR REDO
end;
//if mouse is up - that mean we finish to draw something on canvas, so we gonna save what we drew
procedure TMainForm.imgMainMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var bmp:TBitmap;
begin
mouseIsDown:=false;
bmp:=TBitmap.Create;
try
bmp.Assign(imgMain.Picture.Bitmap);
picHistory.Push(bmp);
finally
bmp.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
并进行撤消和重做.
procedure TMainForm.btnUndoClick(Sender: TObject);
var redBmp:TBitmap;
begin
if(not picHistory.isEmpty) then begin //if we draw something before
//prepare to save what've done into history for redo
redBmp:=TBitmap.Create;
redBmp.Assign(picHistory.getLast);
//showing what were done with image before on screen
MainForm.imgMain.Canvas.Draw(0,0, picHistory.Pop);
//but in case we want to be able get back our last changes we save it into redo history
tempHistory.Push(redBmp);
redBmp.Free;
end;
end;
{...}
procedure TMainForm.btnRedoClick(Sender: TObject);
begin
//if there were something into history for redo then show int on canvas
if(not tempHistory.isEmpty) then
MainForm.imgMain.Canvas.Draw(0,0, tempHistory.Pop);
end;
Run Code Online (Sandbox Code Playgroud)
但是有一些事情发生了 - 我Undo没有任何改变.当我继续推进时Redo- 它就像是Undo.
顺便说一句,当我宣布重做和撤消历史时,这种方式不同
procedure TMainForm.FormCreate(Sender: TObject);
begin
{...}
picHistory:=myHistory.Create(6); //FOR UNDO
tempHistory:=myHistory.Create(12); //FOR REDO
end;
Run Code Online (Sandbox Code Playgroud)
然后在步骤中发生的picHistory事情似乎就像它的数字长度不是6,它是12!所以我认为这两个对象使用同一个数组!为什么会发生这种情况以及如何使其正确?
您的两个myHistory类实例共享相同的全局数据.您必须将数据声明移动到类中,以使其成为每个实例数据而不是全局数据.
试试这个:
type
myHistory = class
private
historyQueueArray: array of TBitmap; //Now they are class members instead of global
historyIndex, hSize:Integer;
public
constructor Create(Size:Integer);
procedure Push(Bmp:TBitmap);
function Pop():TBitmap;
procedure Clean();
procedure Offset();
function isEmpty():boolean;
function isFull():boolean;
function getLast():TBitmap;
protected
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
143 次 |
| 最近记录: |