本贴转自http://www.drgraph.com/viewthread.php?tid=107&extra=page%3D1
2.3 创建类型
创建类型对应枚举量为cetCreate,经过窗口程序处理,调用BeginExecuteItem时,被选择对象中只有被创建对象object。
当然,对于Undo的需求而言,知道object就知道该如何撤销创建操作,即简单地删除object即可;但如果还想Redo,即重做时,还需要知道object的具体信息,如对象类型、位置等信息。
考虑更深入一点,即在Undo/Redo的过程实现中,不能对窗口程序的逻辑提出新的要求。如不能为了重做,而要求窗口程序在删除对象时,不进行物理删除。
因此,在TCbwExecuteItem类中,所有相关被操作对象均不以实例形式存在,而以文本方式进行描述,基于通用性,可采纳XML格式。
在TCbwExecuteItem类中,添加成员
当创建类型操作完成后,FOperateObjects将记录下被操作对象
则在TCbwGraphBaseForm::BeginExecuteItem中,加上初始化处理
SetOperateObject函数将维护被操作对象列表
而在其结束处理时,进行相应的XML文档流入处理
其Undo逻辑为:
void __fastcall TCbwExecuteItem::Undo(TCbwGraphBaseForm * destForm)
{ // 撤销本步操作
if(ExecuteType == cetCreate)
{
destForm->ObjectsFromXmlNode(FXmlNode); // 取得节点中所有对象cSelectedObjects
destForm->DeleteSelectedObjects(); // 删除所有被选择对象
return;
}
}
其Redo逻辑为:
测试:
序号 测试内容 Undo Redo
1. 创建单个图元 OK OK
2. 创建多个图元,连续Undo/Redo OK OK
3. 创建单个元件 OK OK
4. 创建多个元件,连续Undo/Redo OK OK
5. 创建思维图元 无现象 无现象
检查一下,原来思维图元中没有进行BeginExecuteItem与EndExecuteItem处理。在思维图窗口中创建思维图元处加上这两个函数,再测试。
序号 测试内容 Undo Redo
6. 创建思维图元 OK OK
7. 创建多个思维图元,连续Undo/Redo OK OK
看来,基本达到要求。
创建操作中,还有创建导线的操作,是否将之单独处理呢?想想看。
再做一些锦上添花的工作,即处理工具条按钮: