小女子初来乍到 急求VC中关于撤消功能的实现,该如何解决
小女子初来乍到 急求VC中关于撤消功能的实现
有个用VC做的监控的项目,可以在界面上添加 直线等元素,并且可以更改这些元素的属性 及移动 复制,
现在需要增添一个撤销的功能,虚心请教高人指点,1)是用链表来做么? 2)希望提供详尽的代码或思路 不胜感激!!!!!!
------解决方案--------------------
有个用VC做的监控的项目,可以在界面上添加 直线等元素,并且可以更改这些元素的属性 及移动 复制,
现在需要增添一个撤销的功能,虚心请教高人指点,1)是用链表来做么? 2)希望提供详尽的代码或思路 不胜感激!!!!!!
------解决方案--------------------
- C/C++ code
class CRUAct { public: virtual ~CRUAct() {}; virtual void Redo()=0; virtual void Undo()=0; CString GetText(){ return m_strText;} void SetIsUndo(BOOL bIsUndo){ m_bIsUndo = bIsUndo;} BOOL IsUndo(){ return m_bIsUndo;} protected: BOOL m_bIsUndo; CString m_strText; }; typedef CList<CRUAct*, CRUAct*> CRedoUndoBuffer; class CRedoUndo { public: CRedoUndo(); ~CRedoUndo(); public: void AddUndo(CRUAct *pRUAct); void AddRedo(CRUAct *pRUAct); void Redo(int nNum); void Undo(int nNum); BOOL CanRedo(); BOOL CanUndo(); void GetRedoActions(CStringArray& lstActions); void GetUndoActions(CStringArray& lstActions); protected: void Clear(CRedoUndoBuffer& ru); void Fill(CRedoUndoBuffer& ru, CStringArray& lstActions); CRedoUndoBuffer m_redo; CRedoUndoBuffer m_undo; }; class CURRotate : public CRUAct { public: CURRotate(int nPage, int nRotate); virtual void Redo(); virtual void Undo(); protected: int m_nPage; int m_nRotate; }; CRedoUndo::CRedoUndo() { } CRedoUndo::~CRedoUndo() { Clear(m_undo); Clear(m_redo); } void CRedoUndo::Clear(CRedoUndoBuffer& ru) { POSITION pos; CRUAct *pRUAct; for (pos=ru.GetHeadPosition();pos != NULL;) { pRUAct = ru.GetNext(pos); ASSERT(pRUAct); delete pRUAct; } ru.RemoveAll(); } void CRedoUndo::AddUndo(CRUAct *pRUAct) { m_undo.AddHead(pRUAct); Clear(m_redo); } void CRedoUndo::AddRedo(CRUAct *pRUAct) { m_redo.AddHead(pRUAct); } void CRedoUndo::Redo(int nNum) { for (int i=0;i<nNum;i++) { CRUAct *pRUA = m_redo.GetHead(); pRUA->Redo(); m_redo.RemoveHead(); pRUA->SetIsUndo(TRUE); m_undo.AddHead(pRUA); } } void CRedoUndo::Undo(int nNum) { for (int i=0;i<nNum;i++) { CRUAct *pRUA = m_undo.GetHead(); pRUA->Undo(); m_undo.RemoveHead(); pRUA->SetIsUndo(FALSE); m_redo.AddHead(pRUA); } } BOOL CRedoUndo::CanRedo() { return m_redo.GetSize() > 0; } BOOL CRedoUndo::CanUndo() { return m_undo.GetSize() > 0; } void CRedoUndo::GetRedoActions(CStringArray& lstActions) { Fill(m_redo, lstActions); } void CRedoUndo::GetUndoActions(CStringArray& lstActions) { Fill(m_undo, lstActions); } void CRedoUndo::Fill(CRedoUndoBuffer& ru, CStringArray& lstActions) { CRUAct *pRUAct; for (POSITION pos = ru.GetHeadPosition(); pos != NULL;) { pRUAct = ru.GetNext(pos); ASSERT(pRUAct); lstActions.Add(pRUAct->GetText()); } } CURRotate::CURRotate(int nPage, int nRotate) { m_nPage = nPage; m_nRotate = nRotate; if (nRotate > 0) m_strText.LoadString(ID_VIEW_COUNTERCLOCKWISE); else m_strText.LoadString(ID_VIEW_CLOCKWISE); int nPos = m_strText.Find('\n'); if (nPos > 0) m_strText.SetAt(nPos,0); } void CURRotate::Redo() { Rotate(m_nPage,m_nRotate,FALSE); } void CURRotate::Undo() { Rotate(m_nPage,-m_nRotate,FALSE); }