手把手教你写、程序(续)
在第一篇文章“手把手教你写程序”里,我介绍了如何实现一个基于图像操作的我们的这些类应该在什么地方使用呢? 还记得我们的第一个 pCmd->Execute(this, pData);
if (pData)
{
// 如果外部传入的 // 我们就在进行真正的操作前先用 }
// 根据不同的派生类修改 下面我们还是以图像旋转这个具体操作来看如何实现 CImageRatate(float fAngle) : m_fRotateAngel(fAngle) {}
virtual bool Execute(CImageData * pData, CUndoData * pData)
{
if (pData) // 根据不同的操作类型, pData->m_fRotateAngle = -m_fRotateAngle;
pData->Rotate(m_fRotateAngle);
// 这里假定 }
float m_fRotateAngle;
在这种结构里有许多值得改进的地方。下面我就三个方面对前面介绍的结构进行改进·支持单步操作的多级·支持基于图像·实现 下面分别对每个方面进行单独说明。 单步操作的多级 先看看什么是单步操作的多级 特别说明:我下面所做的改进只能是体现了单步操作的多级它的基本实现方法如下 // 默认值直接设置为 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 * m_pSaved;
// 表示 unsigned int m_UndoNum;
现在我们已经有了新的 基于图像 下面就实现带 首先我们需要在添加一个矩形值成员变量,用来保存操作的范围。这个矩形值的保存位置有两个 如果保存在 // 保持原来的定义不变 RECT m_Rect;
virtual bool UndoAction(CImageData * pData)
{
// 根据 // 然后用新的数据调用内部 do{
m_pSaved[m_UndoNum-1].UndoAction(pData);
m_UndoNum--;
}while(m_UndoNum>0 );
return true;
}
如果保存在 实现 节省内存空间我们才需要实现 virtual bool UndoAction(CImageData * pData)
{
// 先从 // 把读取的数据与 // 把交换后的数据重新写入文件,必要时释放临时内存 }
// 指向 char * m_pszFilePath;
也许这些实现和改进都不值一提。如果能给部分初学者提供部分帮助足矣。
本文探讨了基于图像编辑的Undo/Redo机制,并提出了三种改进方案:支持单步操作的多级Undo/Redo、基于图像Select的Undo/Redo及Undo数据的磁盘保存。
4550

被折叠的 条评论
为什么被折叠?



