关于图形编辑软件undo与redo的编程实现,用c++builder或delphi如何编程 ???

关于图形编辑软件undo与redo的编程实现(用c++builder或delphi如何编程 ??) Delphi / Windows SDK/API

http://www.delphi2007.net/DelphiMultimedia/html/delphi_2006120713533775.html

各位高手: 大家好!

几乎所有的图形编辑软件都有undo与redo操作, 用c++builder或delphi如何

高效地编程实现 ?? 高效地全程操作如何编程 ?? 听说与command 模式和堆栈

有关. 具体如何编程呢 ??

请教具体编程思路, 请给出代码, 最好提供针对性的c++builder或delphi

完整例子. 谢谢 !!

注: 如果大家引用别人的帖子太长, 请只给出URL, 不要把帖子内容直接帖上,

以免影响大家阅读, 谢谢合作 !!

搞搞命令模式先。

一般都是将更改历史保存在虚拟内存中,以为很多过程都是不可逆的。

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

各位:

能否给出代码 ?? 谢谢!!

可以. 全心全意为社员服务, 是我们的宗旨.

to sanmaotuo(老冯)

我升星了,你快加油啊!

我的图形编辑功能是这样的:能在画布上画上线条,圆,椭圆及各种图元等,这些图形加上后都能

用鼠标选定, 移动, 旋转, 改变形状等, 还有, 整个图形(包括原画布及后来各种画上去的)

能进行模糊,锐化等操作. 这样的软件实现UNDO 和 REDO如何编程啊?? 高效地全程操作如何编程啊 ?? 请把代码给我 happymanfreeman@sohu.com 谢谢!!

我升星了,你快加油啊!

---------------------

恭喜大哥, 我一定加倍努力.

interface

uses

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;

...........................版权所有 版权人: 老冯

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

请介绍针对性的c++builder或delphi

完整例子. 谢谢 !!

不可能给你完整例子。

我说的是"介绍"网上的针对性c++builder或delphi

完整例子 !! 谁介绍200分全部给谁.

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

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

=================================================================================

老弟说的好!你就是给了他完整的例子,也不知道那天给你分。我在楼主另一帖给了较完整的例子,也没见说正确与否,更不见楼主有接帖的意思,没意思。所以我现在回帖前总是搜索一下发帖人是否有老帖未接的,如果问题基本解决楼主不接帖的,我就是知道也不回帖的。

见楼主另一帖:

http://community.csdn.net/Expert/topic/5185/5185934.xml?temp=.7544062

不好意思, 由于事物繁忙, 一些帖子忘看, 大家不要见怪! 现在我看看上述贴子, 如问题解决,

马上给分, 结帖.

蹭分!!:)

什么人都有的

结帖是美得

矢量图形引擎TCAD xp (CAD 组件)

详细信息请看:

http://www.codeidea.com

使用堆栈的原理.

http://www.codeidea.com/cn/

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

如果你的操作对象不是很大,可以使用对象克隆的方法实现