一个大型应用软件,怎么往里面添加重做和撤消功能啊。我把我现在的思路写在下面。我想把所有用户操作消息都存放到一个数组中,然后撤消就是重发一个相反的消息了。好多细节问题不能解决。大家在做大型应用软件时如何添加重做和撤消功能的啊。

解决方案 »

  1.   

    http://www.codeguru.com/Cpp/Cpp/cpp_mfc/article.php/c4139/
      

  2.   

    http://www.codeguru.com/Cpp/Cpp/algorithms/general/article.php/c6361/
      

  3.   

    可使用CList等顺序容器。最好采用“后入先出”法则。
      

  4.   

    我看了雅克医生的两张帖子链接,谢谢。
    但是那两篇文章处理的操作很简单,我的应用软件中有很多种操作,就像PHOTOSHOP中那样,各种各样的数据结构我怎么用那么简单的类实现撤销重做操作啊?盼高手指点
      

  5.   

    to I_Love_CPP(我爱C++) :
    谢谢你,但是数据种类又多,操作类型又复杂,能不能说具体点呵比如:有一个操作将图像中添加了伪彩,我怎么撤销呢?我总不能把原始图像数据拷个备份吧。这样内存肯定会:)
      

  6.   

    你的疑惑也是我当初的疑惑,幸好我听到(其实是看到了)了一段对话。摘自 CodeGuru: Implementing Undo/Redo -- The DocVars MethodCView: Hey, CDocument! What you got? 
    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'. :)
      

  7.   

    说一个简单一点的,你可以触类旁通建立两个先进后出的栈,一个Undo栈,一个Redo栈。栈的存储单元的数据结构如下:struct StackElement
    {
      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)太大。另外如果数据量特别大的情况下可以考虑磁盘文件的方式。