社区
资源
帖子详情
在线求教:CDC画出的线,怎么设置undo键来恢复到上一次画的界面?
zhonggengbo
2003-03-11 05:06:04
即:怎样记住后画的线?
...全文
98
6
打赏
收藏
在线求教:CDC画出的线,怎么设置undo键来恢复到上一次画的界面?
即:怎样记住后画的线?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
6 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
Yesy
2003-03-14
打赏
举报
回复
最近一次的画面上使用反转画就恢复了
isCrazy
2003-03-13
打赏
举报
回复
用CList之类的集合模板类保存所有要画线的点。画图时从此模板中按顺序将点连起来即可成线。如要UNDO,从集合中删除最后一个点,再Invaldate窗口,从而调用OnPaint/OnDraw之类函数。
laosanr
2003-03-13
打赏
举报
回复
多步Undo/Redo的实现
应用软件中,Undo/Redo功能为用户提供了方便,而多步Undo/Redo则更是如此。
本文利用C++面对象的程序设计技术,研究了多步Undo/Redo的实现方法。
首先,我们建立一个基类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类的析构函数中,清除阵列中的每一个CEditRecord对象。
下面给出一个例子说明如何建立CEditRecord对象,为方便计,假设进行的操作是从一个全局性
的字符串pText中删除一段内容,我们用Pos表示所删内容在pText中的相对位置, 用Len表示所删内
容的长度,并假设全局串pTetx的存储空间足够大。
1.从基类CEditRecord上派生出CEditCutString;
2.设置私有变量Pos、Len用于表示所删内容在pText中的相对位置、长度;设置私有变量pBuff
用于分配存储空间,保存所删内容;设置私有变量Avialiable用于表示可否进行Undo/Redo。
/////////////////////////////////////////////////////
// Example
//
#include "CEditRecord.h"
class CEditCutString:public CEditRecord
{
public:
CEditCutString(int,int);
~CEditCutString();
private:
int Pos;
int Len;
char* pBuff;
BOOL Avialiable;
public:
virtual BOOL Undo();
virtual BOOL Redo();
};
CEditCutString::CEditCutString(int p,int n)
{
Pos=p;
Len=n;
pBuff=new char[n];
if(pBuff==NULL)
Avialiable=FALSE;
esle
{
Avialiable=TRUE;
memcpy(pBuff,pText+Pos,Len);
}
}
CEditCutString::~CEditCutString
{
if(Avialiable)
delete []pBuff;
}
BOOL CEditCutString::Undo()
{
if(!Avialiable)
return FALSE;
int l=strlen(pText);
for(int i=l;i>=Pos;i--)
pText[i+Len]=pText[i];
for(int j=0;j<Len;j++)
pText[Pos+j]=pBuff[j];
return TRUE;
}
BOOL CEditCutString::Redo()
{
if(!Avialiable)
return FALSE;
int l=strlen(pText);
for(int i=Pos;i<=l-Len;i++)
pText[i]=pText[i+Len];
return TRUE;
}
grapeky
2003-03-13
打赏
举报
回复
用一个数组记下每个点的坐标,并且记下坐标点的个数(设为m_nNumPoint),在OnPaint()中,从数组0开始一直画到m_nNumPoint-1;如果要撤消一个直线的话,应该让m_nNumPoint--;Invalidate();应该就可以了实现撤消的功能了!
catmike
2003-03-11
打赏
举报
回复
remember the point(x,y)and the color of you use, after that you should call the you used color to fill.thank you please give me the fen.
曾经的猎狐
2003-03-11
打赏
举报
回复
把每次的坐标点都记住,,然后恢复到上一个坐标点就可以了
盘点Seata :
undo
-log 处理
首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> ???????????? 文章合集 : ???? https://juejin.cn/post/6941642435189538824 ...一 ....前面说了 Seata Client 的请求流程 , 这一篇来看一
Python使用turtle绘图:pos();
undo
();home()
欢迎大家转发,一起传播知识和正能量,帮助到更多人。期待大家提出宝贵改进建议,...【小白从小学Python、C、Java】【Python-计算机等级考试二级】撤销上
一次
操作:
undo
()返回初始位置:home()返回位置坐标:pos()...
Oracle
undo
表空间管理
当在做DML操作的时候,在修改buffer cache里面的数据块的时候,会对当前块的旧镜像信息做一个保存,保存的数据块就是
undo
块。
undo
块上面保存着数据修改前的信息。 生成
undo
块的几个作用: 当事务没有提交,
undo
...
MySQL日志系统:redo log、binlog、
undo
log 区别与作用
日志系统主要有redo log(重做日志)和binlog(归档日志)。redo log是InnoDB存储引擎层的日志,binlog是MySQL Server层记录的日志, 两者都是记录了某些操作的日志(不是所有)自然有些重复(但两者记录的格式不同)。...
VC++
界面
编程之--实现一个
画
板并提供文字输入功能(MsPaint)
必要时还得提供
UnDo
功能,供用户取消上
一次
绘制的功能。 利用业余时间,我制作了一个
画
板程序,包含了以下几个功能: 1. 可动态拉伸及移动位置的编辑框,供用户输入文字。 2. 可
画
直
线
,圆圈,箭头,
线
段及
线
条。 3....
资源
2,586
社区成员
18,437
社区内容
发帖
与我相关
我的任务
资源
VC/MFC 资源
复制链接
扫一扫
分享
社区描述
VC/MFC 资源
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章