各位高手: 大家好!   几乎所有的图形编辑软件都有undo与redo操作, 用c++builder或delphi如何
高效地编程实现 ??  高效地全程操作如何编程 ?? 听说与command 模式和堆栈
有关. 具体如何编程呢 ?? 
   
   请教具体编程思路, 请给出代码, 最好提供针对性的c++builder或delphi
完整例子. 谢谢 !!

解决方案 »

  1.   

    注: 如果大家引用别人的帖子太长, 请只给出URL, 不要把帖子内容直接帖上,
    以免影响大家阅读, 谢谢合作 !!
      

  2.   

    模式归模式, 实现UNDO 和 REDO 就是自己建立一个STACK就OK了.算法自己根据实际情况考虑吧,不同的应用有不同的算法. 我的网络布线辅助设计系统就是这样设计的.
      

  3.   

    to sanmaotuo(老冯)
    我升星了,你快加油啊!
      

  4.   

    我的图形编辑功能是这样的:能在画布上画上线条,圆,椭圆及各种图元等,这些图形加上后都能
    用鼠标选定, 移动, 旋转, 改变形状等, 还有, 整个图形(包括原画布及后来各种画上去的)
    能进行模糊,锐化等操作. 这样的软件实现UNDO 和 REDO如何编程啊?? 高效地全程操作如何编程啊 ?? 请把代码给我 [email protected]  谢谢!!
      

  5.   

    我升星了,你快加油啊!---------------------恭喜大哥, 我一定加倍努力.interfaceuses
      Classes;type
      TUnDoItem = class(TCollectionItem)
      private
        FActionName: string;
        FState: TStream; //Used to Save Your Graphics At Each Undo&Redo
      public
        constructor Create(Collection: TCollection); override;
        destructor Destroy; override;
        property ActionName: string read FActionName write FActionName;
        property State: TStream read FState;
      end;  TUnDoStack = class(TCollection)
      private
        FCurrent: Integer;
        //FNetGraphics: TNetGraphics;
        procedure ClearUndoStack;
        procedure PushState(const AActionName: string);
        procedure Undo;
        procedure Redo;
        function NextUndoAction: string;
        function NextRedoAction: string;
      protected
      public
        constructor Create(const ANetGraphics: TNetGraphics);
      end;implementation{ TUnDoItem }constructor TUnDoItem.Create(Collection: TCollection);
    begin
      inherited Create(Collection);
      FState := TMemoryStream.Create;
    end;destructor TUnDoItem.Destroy;
    begin
      FState.Free;
      inherited;
    end;{ TUnDoStack }procedure TUnDoStack.ClearUndoStack;
    begin
      Clear;
      FCurrent := -1;
      PushState('');
    end;constructor TUnDoStack.Create(ANetGraphics: TNetGraphics);
    begin
      inherited Create(TUnDoItem);
      Assert(ANetGraphics <> nil, 'ANetGraphics Is Nil');
      FNetGraphics := ANetGraphics;
      FCurrent := -1;
    end;function TUnDoStack.NextRedoAction: string;
    begin
      Result := '';
      //Change Condition From On Line to MutilLines Which Is From Martin Fowler's Refactor
      if FCurrent >= -1 then
        if FCurrent < Pred(Count) then
          Result := TUndoItem(Items[Succ(FCurrent)]).ActionName;
    end;function TUnDoStack.NextUndoAction: string;
    begin
      Result := '';
      //Change Condition From On Line to MutilLines Which Is From Martin Fowler's Refactor
      if FCurrent > -1 then
        if FCurrent < Count then
          Result := TUndoItem(Items[FCurrent]).ActionName;
    end;procedure TUnDoStack.PushState(const AActionName: string);
    begin
      while FCurrent < Pred(Count) do
        Items[Pred(Count)].Free;  with TUndoItem(Add) do
      begin
        ActionName := AActionName;
        //......
        {Save Your Graphics Here}
        FNetGraphics.SaveToStream(FState);//Here is My Application's Coding;
        //......
        Inc(FCurrent);
      end;  if Count > 20 then  //Set Max Count of UNDO&REDO
      begin
        Items[0].Free;
        Dec(FCurrent);
      end;
    end;procedure TUnDoStack.Redo;
    begin
      //Change Condition From On Line to MutilLines Which Is From Martin Fowler's Refactor
      if FCurrent >= -1 then
        if FCurrent < Pred(Count) then
      begin
        //......
        {Initial Your Graphics Here}
        FNetGraphics.Clear;  //Here is My Application's Coding;
        //......
        With TUndoItem(Items[Succ(FCurrent)]) do
        begin
          FState.Position := 0;
          //......
          {Load Your Graphics Here}
          FNetGraphics.LoadFromStream(FState); //Here is My Application's Coding;
          //......
        end;
        Inc(FCurrent);
      end;
    end;procedure TUnDoStack.Undo;
    begin
      //Change Condition From On Line to MutilLines Which Is From Martin Fowler's Refactor
      if FCurrent > 0 then
        if FCurrent <= Count then
      begin
        //......
        {Initial Your Graphics Here}
        FNetGraphics.Clear;  //Here is My Application's Coding;
        //......
        With TUndoItem(Items[Pred(FCurrent)]) do
        begin
          FState.Position := 0;
          //......
          {Load Your Graphics Here}
          FNetGraphics.LoadFromStream(FState); //Here is My Application's Coding;
          //......
        end;
        Dec(FCurrent);
      end;
    end;...........................版权所有 版权人: 老冯
      

  6.   

    学习冯老弟专业的undo和redo功能!我以前就用一个List加个Index变量解决的,汗...
      

  7.   

    请介绍针对性的c++builder或delphi
    完整例子. 谢谢 !!
      

  8.   


      我说的是"介绍"网上的针对性c++builder或delphi完整例子 !! 谁介绍200分全部给谁.
      

  9.   

    分给谁是你的权利和义务。 但CSDN不是培养懒虫的摇篮。
      

  10.   

    分给谁是你的权利和义务。 但CSDN不是培养懒虫的摇篮。
    =================================================================================
    老弟说的好!你就是给了他完整的例子,也不知道那天给你分。我在楼主另一帖给了较完整的例子,也没见说正确与否,更不见楼主有接帖的意思,没意思。所以我现在回帖前总是搜索一下发帖人是否有老帖未接的,如果问题基本解决楼主不接帖的,我就是知道也不回帖的。见楼主另一帖:http://community.csdn.net/Expert/topic/5185/5185934.xml?temp=.7544062
      

  11.   

    矢量图形引擎TCAD xp (CAD 组件) 
    详细信息请看:
    http://www.codeidea.com
      

  12.   

    使用堆栈的原理.http://www.codeidea.com/cn/
      

  13.   

    都成一烂尾贴啦, 湖州的朋友还在给你们HONGBIN老总卖广告啊, 歇菜吧。