一个大型应用软件,怎么往里面添加重做和撤消功能啊。我把我现在的思路写在下面。我想把所有用户操作消息都存放到一个数组中,然后撤消就是重发一个相反的消息了。好多细节问题不能解决。大家在做大型应用软件时如何添加重做和撤消功能的啊。
解决方案 »
- VC++ BCG MFC
- C#转MFC求大神不吝赐教!
- 一个函数在一个线程阻塞,其他线程可以得到执行机会,为什么 啊
- 串口线程问题
- VC++调用SQL语句,提示:0x7c812a5b 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0012d710 处的 long
- 当鼠标离开窗口(CWnd)时响应了哪个事件????????????????????急!!!!!!
- 最后20分! 可否通过URL获得html文档的Ihtmldocument接口??
- 有一个警告:从“INT_PTR”转换到“int”,可能丢失数据,例如:int nCount=CUIntArray.GetCount,如何不让出这个警告
- 请问:vc6中,编译通过,但在debug模式下生成的可执行程序运行不了,release中生成的则可以正常运行。
- 在multiprocessor中,如何获得processor的数目
- ★★★送分啊,有关编译的简单问题,在线等... ★★★
- 在工具栏按钮按右键发送什么消息?
但是那两篇文章处理的操作很简单,我的应用软件中有很多种操作,就像PHOTOSHOP中那样,各种各样的数据结构我怎么用那么简单的类实现撤销重做操作啊?盼高手指点
谢谢你,但是数据种类又多,操作类型又复杂,能不能说具体点呵比如:有一个操作将图像中添加了伪彩,我怎么撤销呢?我总不能把原始图像数据拷个备份吧。这样内存肯定会:)
CDocument: That all depends on what you want it for.
CView: I need to make a change to one of your variables.
CDocument: Okay, I'm gonna send you a copy of my current DocVars package. Make whatever changes you need. When you're done, send it back to me.
CView: The whole package?! Geeze! I just want to make one teensy weensy change. Can't you just send me the one variable I want?
CDocument: DUDE! P-A-C-K-A-G-E. OK?
CView: Okay, but it seems like the hard way to do things.
CDocument: Quit yer complainin' and get back to work.
CView: Right, I've made the change to my DocVars copy. You want it?
CDocument: Yea, send it back to me.
CView: What happens now?
CDocument: I make a unique copy. If the DocVars has pointer variables, I have to allocate memory for new pointers and then fill them up with the parameters from the DocVars you just sent me. Afterwards, I send it along to CUpdateMgr. He adds it to his list and sends a copy back to me when he's done.
CView: You gotta be kiddin' me!! What a tangled bureaucracy!! You're as bad as the Department of Motor Vehicles.
CDocument: Please just shut yer yapper and let me do my job.
CDocument: Hello, CUpdateMgr? I got a new DocVars package for ya. Please update your list.
CUpdateMgr: Got it. I'm adding it to the end of the list. Done. Now I'm sending a copy back to you.
CDocument: Got it. Thanks. The package you returned to me is now my current DocVars.
LATER THAT DAY...
CMainFrame: Hey, CDocument! Some geek with a mouse just clicked the "UNDO" button.
CDocument: Thanks for the message. I'll tell CUpdateMgr.
CDocument: Hey, CUpdateMgr! I just got an Undo request.
CUpdateMgr: Okeeday. Let me scroll back one place on the list of DocVars. There it is. Okay, I'm sending you the older DocVars.
CDocument: Got it, and it is now my current DocVars.
MUCH LATER THAT DAY...
CView: Hey, CDocument! What you got?
CDocument: That all depends. What do you need?
CView: I just need to check the value of one of your DocVars variables.
CDocument: Okay, I'm gonna send you a pointer to my current DocVars.
CView: Beautiful!
CDocument: But you leave them variables alone. NO CHANGES! Ya Hear, BOY!?
CView: Why not?
CDocument: Because you will completely disintegrate the good thang me and CUpdateMgr got goin' here, and you'll ruin the whole Undo/Redo feature.
CView: Roger! No changes. Just lookin'. :)
{
UINT operateType;
UINT nSize;
void *pData;
}operateType 操作类型
pData 保存的数据
nSize pData的大小再定义两个函数分别为 PerformRedo 和 PerformUndoPerformRedo(struct StackElement element); Redo栈出栈时调用
PerformUndo(struct StackElement element); Undo栈出栈时调用
PerformRedo 和 PerformUndo 根据operateType 的不同来解释pData。这里 pData是在操作进栈之前就已经定好的,用来保存出栈时需要(必要)的数据,数据内容可以为任何东西。像你说的图像中添加了伪彩这种操作很可能要保存原来的整个图片,除非有更好的方法来恢复,你可以看看photoshop软件的Undo Redo操作只能恢复一步,windows自带的画笔只能恢复3步,原因就是需要保存的数据量(pData)太大。另外如果数据量特别大的情况下可以考虑磁盘文件的方式。