网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 论文素材 设计下载 最新论文 下载排行 论文上传 在线投稿 联系我们
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > VC++ > 正文
多步Undo/Redo的实现
来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/15
下载{$ArticleTitle}原创论文样式

    首先,建立一个基类CEditRecord,对于每一种操作,都从该基类上派生出与操作相对应的类,记载操作过程,供以后进行具体的Undo/Redo操作;基类CEditRecord中的纯虚函数,为Undo、Redo操作提供接口。

    然后,建立一个用于控制Undo/Redo的类:CRecordCtrl。 CRecordCtrl类从基类CObArray上派生,用于记载已经进行过的操作,响应Undo/Redo命令等;其中nMaxStep变量表示允许Undo/Redo的次数,nCurrRecord变量表示当前的Undo的位置;函数Undo()和Redo()用于响应来自系统菜单、快捷键或者工具条的Undo和Redo命令;函数SetMaxStep()用于设置允许Undo/Redo的次数。

////////////////////////////////////////////////////////
// CEditRecord.h
// Class CEditRecord、CEditCtrl Definition
class CEditRecord : public CObject
{
public:
CEditRecord();
public:
virtual BOOL Undo( )=0;
virtual BOOL Redo( )=0;
};

class CRecordCtrl:public CObArray
{
public:
CRecordCtrl( );
~CRecordCtrl( );
private:
int nCurrRecord;
int nMaxStep;
public:
BOOL EnableUndo( );
BOOL EnableRedo( );
BOOL Undo( );
BOOL Redo( );
BOOL SetMaxStep(int n);
};

extern CEditCtrl Records;


////////////////////////////////////////////////////
// CEditRecord.Cpp
// Class CEdit、CEditCtrl Imeplemetion

#include "CEditRecord.h"
CRecordCtrl Records;

CEditRecord::CEditRecord( )
{
int mm=Records.GetSize( );
if(nCurrRecord==mm-1)
{
if(mm==nMaxStep)
{
//删除最早的记录
CEditRecord* pRec=(CEditRecord*)GetAt(0);
delete pRec;
Records.RemoveAt(0);
nCurrRecord--;
}
}
else
{
//删除所有Undo过的记录
for(int i=mm-1;i>nCurrRecord;i--)
{
CEditRecord* pRec=(CEditRecord*)GetAt(i);
delete pRec;
Records.RemoveAt(i);
}
}

nCurrRecord=Records.Add(this);
}

CRecordCtrl::CRecordCtrl( )
{
nCurrRecord=-1;
nMaxStep=5;
}

CRecordCtrl::~CRecordCtrl( )
{
for(int i=GetSize()-1;i>=0;i--)
{
CEditRecord* pUndo=(CEditRecord*)GetAt(i);
delete pUndo;
}
}

BOOL CRecordCtrl::EnableUndo( )
{
return (nCurrRecord>=0);
}

BOOL CRecordCtrl::EnableRedo( )
{
return (nCurrRecord<GetSize( )-1);
}

BOOL CRecordCtrl::Undo( )
{
if(!EnableUndo( )) return FALSE;

CEditRecord* pRec=(CEditRecord*)GetAt(nCurrRecord--);
if(pRec==NULL) return FALSE;

return pRec->Undo();
}

BOOL CRecordCtrl::Redo()
{
if(!EnableRedo( )) return FALSE;

CEditRecord* pRec=(CEditRecord*)GetAt(++nCurrRecord);
if(pRec==NULL) return FALSE;

return pRec->Redo();
}


BOOL CRecordCtrl::SetMaxStep(int n)
{
if(n<1) return FALSE;
int mm=GetSize( );

if(UndoStep<=n || mm<=n)
{
UndoStep=n;
return TRUE;
}
else
{
//压缩用于Undo的记录
int nPack=mm-n;
int u=min(nCurrRecord,nPack);
for(int i=u-1;i>=0;i--)
{
CEditRecord* pRec=(CEditRecord*)GetAt(i);
delete pRec;
nCurrRecord--;
}

//压缩用于Redo的记录
int v=nPack-u;
for(int i=0;i<v;i++)
{
CEditRecord* pRec=(CEditRecord*)GetAt(mm-i-1);
if(pRedo==NULL) delete pRec;
}
}
return TRUE;
}
在CEditRecord的生成函数中,首先判定是否达到允许的最大Undo次数; 如果未达到,直接把this指针加入到阵列中;如果超过,需要从阵列中,清除一些关于早期的操作的记录,然后把this指针加入到阵列中。

函数CRecordCtrl::SetMaxStep( )中,对于缩小Undo/Redo次数这种情况,特别是在阵列中已经记载了较多的操作,则需清除一些。

在CRecordCtrl类的析构函数中,清除阵列中的每一
  • 下一篇资讯: 深入了解异步套接字
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号