是指反复多次的重复,撤销,而不是它自身提供的一次性的重复,撤销.我已实现了对单个字符的重复,撤销.
对字符串的删除,拷贝等操作的撤销,重复不知道如何下手.
请大侠指点.

解决方案 »

  1.   

    你需要定义一个结构体,如:
    typedef struct _MYSTRUCT
    {
       CString  str;//保存操作串
       int      nStep;//保存是第几步
    }MYSTRUCT,*PMYSTRUCT;接下来定义一个结构数组,如:
    MYSTRUCT myStruct[10];//可以保存10个恢复状态接下来只要处理重复及撤消的事件了
    自己动动脑,写个好的算法^-^
      

  2.   

    如果需要比较全面的话,需要拦截edit的event。
      

  3.   

    首先要建立一个需要的undo_info
    enum undo_info
    {
    add, modified, delete, none
    };需要处理的情况很多,有一个vb的例子,拦截edit的event,vc下面可以简单的处理PretranslateMessage();
      

  4.   

    我是这么写的,有一个类专门实现存放管理undo,redo数据,这个类似网上下载的.
    该类主要内容如下:
    // ISee UndoÒýÇæºËÐÄÀà
    class CIUndoEngine  
    {
    public:
    CIUndoEngine();
    virtual ~CIUndoEngine(); int PushData(LPVOID pData, DWORD size, DWORD param1, DWORD param2, int *pIndex=NULL);
    int PopData(LPVOID *ppData, DWORD *pSize=NULL, DWORD *pParam1=NULL, DWORD *pParam2=NULL, int *pIndex=NULL);
    int RedoData(LPVOID *ppData, DWORD *pSize=NULL, DWORD *pParam1=NULL, DWORD *pParam2=NULL, int *pIndex=NULL); void Empty(void); bool GetUndoEngineStatus(void){return m_UndoStatus;};
    int GetUndoCount(void){return m_UndoCount;};
    int GetRedoCount(void){return m_RedoCount;};
    int GetRedoIndexInfo(int index, DWORD *pParam1=NULL, DWORD *pParam2=NULL);
    int GetUndoIndexInfo(int index, DWORD *pParam1=NULL, DWORD *pParam2=NULL);
    protected:
    bool m_UndoStatus; // UndoÒýÇæÆô¶¯±êÖ¾ int m_UndoCount; // ¿ÉÓÃUndoÊý¾Ý¿é¸öÊý
    int m_RedoCount; // ¿ÉÓÃRedoÊý¾Ý¿é¸öÊý
    CPtrList m_UndoDataList; // UndoÊý¾ÝË÷ÒýÐÅÏ¢±í CFile m_File; // ÁÙʱÎļþ£¨ÓÃÓÚ´æ·ÅÓû§µÄUndoÊý¾Ý£©
    TCHAR m_TempPath[MAX_PATH]; // ÁÙʱÎļþ·¾¶¼°ÎļþÃû
    private:
    LONG _get_current_overwrite_pos(void);
    int _remove_redo_list(void);
    int _make_filenamestr_for_temp(void);
    };#endif // __IUNDOENGINE_INC__另外在view类中添加 onchar处理函数如下:
    void CNoteView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    CData *myData;
    int iRet;
             //对于是字符,数字,回车,空格的字符进行入栈处理 
    if ((nChar >= 65 && nChar <=90) || (nChar >= 97 && nChar <= 122) || (nChar >= 48 && nChar <= 57) || (nChar == 32) || (nChar == 13))
    {
    iChange = 1;
    if (iFlag == 1)
    {
    iFlag = 0;
    }
    else
    {
    CEdit& mEdit = GetEditCtrl();
    mEdit.GetSel(iStart,iEnd);
     
        LPVOID lpBuff = (LPVOID) ::GlobalAlloc(GMEM_FIXED, sizeof(CData));    
             myData = (CData *) lpBuff;
                 
        myData->iRedoStart = iStart;
        myData->iRedoEnd   = iEnd;
        myData->iUndoStart = iStart;
        myData->iUndoEnd   = iStart;
        myData->nRedoChar  = nChar;
        myData->nUndoChar  = 46; //backspace
    strcpy(myData->sTmp,"");       iRet = MyUndo.PushData(lpBuff,sizeof(CData),0,0);
        if (iRet != 0)
    {
        ::GlobalFree(lpBuff);
    }
    }
    }

    CEditView::OnChar(nChar, nRepCnt, nFlags);
    }其中myData 结构定义如下:class CData
    {
    public:
    int iUndoStart;
    int iUndoEnd;
    int nUndoChar;
    int iRedoStart;
    int iRedoEnd;
    int nRedoChar;
    char sTmp[256];
    };于是添加对undo, redo 请求的函数如下:
    void CNoteView::OnEditUndo() 
    {
        CData *myData;
        LPVOID lpBuff;
    int iRet;
        
    iRet = MyUndo.PopData(&lpBuff,NULL,NULL,NULL,&iUndoCount);
    if (iRet != 1) 
    {        
    return ;
    }
    myData = (CData *) lpBuff;
    CEdit& mEdit = GetEditCtrl();
    mEdit.SetSel(myData->iUndoStart, myData->iUndoEnd);    if (myData->nUndoChar > 0)
    {
    iFlag = 1;
    ::PostMessage(CNoteView::GetSafeHwnd(), WM_KEYDOWN, myData->nUndoChar, 0);
    }
    else if (myData->nUndoChar == 0)
    {
    iFlag = 1;
    iRet = find_char(myData->sTmp[0]);
    if (iRet != -1)
        ::PostMessage(CNoteView::GetSafeHwnd(), WM_CHAR, iRet, 0);
    }
    ::GlobalFree(lpBuff);
    }void CNoteView::OnEditRedo() 
    {
    CData *myData;
    LPVOID lpBuff;
    int iRet;
       
    iRet = MyUndo.RedoData(&lpBuff,NULL,NULL,NULL,&iRedoCount);
    if (iRet != 1)
    {
    return ;
    }
    myData = (CData *) lpBuff;
    CEdit& mEdit = GetEditCtrl();
    mEdit.SetSel(myData->iRedoStart, myData->iRedoEnd);
        
        if (myData->nRedoChar > 0)
    {
    iFlag = 1;
    if (myData->nRedoChar == 13)
    ::PostMessage(CNoteView::GetSafeHwnd(),WM_KEYDOWN, (WPARAM)(VK_RETURN), (LPARAM)(1));
    else
    ::PostMessage(CNoteView::GetSafeHwnd(),WM_CHAR,myData->nRedoChar,0);
    }
    else if (myData->nRedoChar == -1)
    {
    ::PostMessage(CNoteView::GetSafeHwnd(),WM_CHAR,8,0);
    }
    ::GlobalFree(lpBuff);
    }目前就能完全满足单个字符的undo,rendo