王朝网络
分享
 
 
 

手把手教你写Undo、Redo程序(续)

王朝other·作者佚名  2006-10-24
宽屏版  字体: |||超大  

手把手教你写Undo、Redo程序(续)

在第一篇文章“手把手教你写Undo、Redo程序”里,我介绍了如何实现一个基于图像操作的Undo, Redo框架结构。但是我们现在所讲的还只是Undo类的结构。还有一个非常重要的部分没有说明:我们的这些Undo类应该在什么地方使用呢?

还记得我们的第一个CImageData类吗?在ExcuteOperation函数的说明曾提到需要修改函数的参数。现在就是需要修改的时候了。

bool CImageData::ExecuteOperation(CImageOperation * pCmd, CUndoData * pData)

{

pCmd->Execute(this, pData);

}

bool CImageOperation::Execute(CImageData * pData, CUndoData *pData)

{

if (pData)

{

// 如果外部传入的Undo数据接口pData不空

// 我们就在进行真正的操作前先用pData构造好Undo数据

}

// 根据不同的派生类修改pData的图像数据

}

下面我们还是以图像旋转这个具体操作来看如何实现CImageRotate:

class CImageRatate : public CImageOperation

{

public:

CImageRatate(float fAngle) : m_fRotateAngel(fAngle) {}

virtual bool Execute(CImageData * pData, CUndoData * pData)

{

if (pData) // 根据不同的操作类型,pData实际上指向的是不同的派生类

pData->m_fRotateAngle = -m_fRotateAngle;

pData->Rotate(m_fRotateAngle);

// 这里假定Rotate函数是一个旋转图像的成员函数

}

private:

float m_fRotateAngle;

};

在这种结构里有许多值得改进的地方。下面我就三个方面对前面介绍的结构进行改进:

·支持单步操作的多级Undo/Redo

·支持基于图像Select的Undo/Redo

·实现Undo数据的磁盘保存

下面分别对每个方面进行单独说明。

1、 单步操作的多级Undo/Redo

先看看什么是单步操作的多级Undo/Redo: 在一些比较特殊的软件中,软件提供给用户的是执行某一步操作,但是在内部程序实现的时候会包含多个子操作。这多个子操作就形成了多级的Undo/Redo。当然,这种情况比较特殊,比如在绣花编辑软件中,用户的针脚操作在内部可能需要多个子操作,这样才能方便用户在后来根据子操作进行修改(比如针脚编辑).

特别说明:我下面所做的改进只能是体现了单步操作的多级Undo/Redo实现思想。之所以这么做主要是为了能利用前面的框架。为了把多个子操作的Undo/Redo封装起来。我们还需要一个Undo接口类。

它的基本实现方法如下:

class CUndoInfo

{

public:

// 默认值直接设置为1,因为m_pSaved至少有一个

CUndoInfo() : m_UndoNum(1) {}

virtual ~CUndoInfo() {}

virtual bool UndoAction(CImageData* pData)

{

do{

m_pSaved[m_UndoNum-1].UndoAction(pData);

m_UndoNum--;

}while(m_UndoNum>0 );

return true;

}

// 这里的CUndoData指针实际上可以是一个指针列表, 表示多个子操作

CUndoData * m_pSaved;

// 表示m_pSaved保存的指针个数

unsigned int m_UndoNum;

};

现在我们已经有了新的Undo接口类,所以给外部使用的文档接口类也需要改变。现在我们只需要把CUndoList中所有的CUndoData全部替换为CUndoInfo即可。怎么样,还算比较简单吧!

2、 基于图像Select的Undo/Redo

下面就实现带Select的Undo/Redo功能。在图像编辑时,如果用户在进行操作时,先选择了部分图像。那么我们在保存数据时就应该只保存修改的部分数据。这样才能节省空间,提高效率。

首先我们需要在添加一个矩形值成员变量,用来保存操作的范围。这个矩形值的保存位置有两个:如果你不想对前面定义的类做过多的修改,这个矩形值可直接放入CUndoInfo类;另一个位置是保存在CUndoData。

如果保存在CUndoInfo,我们就只需在CUndoInfo::UndoAction进行简单修改。

class CUndoInfo

{

// 保持原来的定义不变

RECT m_Rect;

virtual bool UndoAction(CImageData * pData)

{

// 根据m_Rect的值修改pData,也就是取pData部分数据形成新的pData

// 然后用新的数据调用内部Undo.

do{

m_pSaved[m_UndoNum-1].UndoAction(pData);

m_UndoNum--;

}while(m_UndoNum>0 );

return true;

}

};

如果保存在CUndoData抽象类中,我们就需要对每个派生类进行修改。很明显,这样的代价要比上一种方法大很多。所以我也不多做介绍。

3、 实现Undo数据的磁盘保存

节省内存空间我们才需要实现Undo数据的磁盘保存。保存在磁盘,更容易实现无穷级数的Undo、Redo操作。从前面的描述知道,可逆操作保存的是操作算法,这类操作一般占用的磁盘空间不多。我这里也就暂时不考虑实现对此类操作的磁盘保存。所以我们把保存在CFullImageUndo的CImageData数据直接保存在磁盘。我们对CFullImageUndo类做如下修改:

class CFullImageUndo

{

public:

virtual bool UndoAction(CImageData * pData)

{

// 先从m_pszFilePath读取文件的内容到临时内存

// 把读取的数据与pData的数据进行交换

// 把交换后的数据重新写入文件,必要时释放临时内存

}

public:

// 指向CImageData保存的图像数据位置

char * m_pszFilePath;

};

也许这些实现和改进都不值一提。如果能给部分初学者提供部分帮助足矣。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有