Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 两个不同的对象使用一个内存区域?_Delphi_Bitmap_Delphi 7_Paint_Undo Redo - Fatal编程技术网

Delphi 两个不同的对象使用一个内存区域?

Delphi 两个不同的对象使用一个内存区域?,delphi,bitmap,delphi-7,paint,undo-redo,Delphi,Bitmap,Delphi 7,Paint,Undo Redo,我需要能够在我简单的delphi绘画中进行撤销和重做操作。所以我决定制作一些容器来保存历史记录(不是完整的历史记录,只有以前的一些位图文件) 在我的程序中,我就是这样使用它的 在历史中保存: procedure TMainForm.FormCreate(Sender: TObject); begin {...} picHistory:=myHistory.Create(10); //FOR UNDO tempHistory:=myHistory.Create(10); //FOR

我需要能够在我简单的delphi绘画中进行撤销和重做操作。所以我决定制作一些容器来保存历史记录(不是完整的历史记录,只有以前的一些位图文件)

在我的程序中,我就是这样使用它的

在历史中保存:

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;
以及撤销和重做

    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;
但是有很多事情发生了——我推动的
Undo
没有任何变化。当我按下“重做”,它的工作原理就像“撤消”

顺便说一下,当我以不同的长度声明重做和撤消的历史时

procedure TMainForm.FormCreate(Sender: TObject);
begin
 {...}
  picHistory:=myHistory.Create(6);   //FOR UNDO
  tempHistory:=myHistory.Create(12); //FOR REDO
end;

然后一步一步地看看
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;

谢谢,先生!我甚至没有意识到这一点,当我急着做某事的时候,我比以往更加愚蠢:c
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;