⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 command.h

📁 实现撤销和恢复功能得远吗
💻 H
字号:
// Command.h: interface for the CCommand class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_COMMAND_H__413D14C5_DDA4_4F61_93D3_5405785E15FC__INCLUDED_)
#define AFX_COMMAND_H__413D14C5_DDA4_4F61_93D3_5405785E15FC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// 使用STL列表
#include <list>
using namespace std;

/////////////////////////////////////////////////////////////////////
//
// CCommand 类
//
// 这是一个纯虚类,必须由其子类实现其虚拟方法后才可用
// 相当于一个接口
//
class CCommand  
{
public:
	// 用于清理资源
	virtual ~CCommand(){ };

	// 用于执行命令
	virtual bool Execute() = 0;
	// 用于恢复命令
	virtual bool Unexecute() = 0;
};

/////////////////////////////////////////////////////////////////////
//
// CCommandManagerT 类
//
// 这是一个命令管理类,用于管理所有的命令集合
//
template <class T = CCommand>

class CCommandManagerT
{
// 数据成员
private:
	typedef list<T*>	CommandList;         // 命令列表定义
	CommandList         m_undoList;          // 回退命令列表
	CommandList         m_redoList;
	int                 m_nUndoLevel;
	int                 m_nCleanCount;

// 构造与析构方法
public:
	CCommandManagerT(int nUndoLevel = 100) : 
		m_nUndoLevel(nUndoLevel), 
		m_nCleanCount(0)
	{ }

	~CCommandManagerT()
	{
		Clear();   // 清空所有m_undoList与m_redoList内容
	}

// 属性
public:
	bool CanUndo() const
	{
		return (m_undoList.size() > 0);
	}

	bool CanRedo() const
	{
		return (m_redoList.size() > 0);
	}

	int getUndoLevel() const
	{
		return m_nUndoLevel;
	}

	void setUndoLevel(int newValue)
	{
		m_nUndoLevel = newValue;
	}

	bool IsDirty() const
	{
		return (m_nCleanCount != 0);
	}

	T* getLastUndoCommand() const
	{
		return m_undoList.back();
	}

	T* getLastRedoCommand() const
	{
		return m_redoList.back();
	}

// 个部接口方法
public:
	void DoCommand(T* pCommand)
	{
		// 清空redo列表
		ClearRedoList();
		// 执行命令并将其加入Undo列表
		if (pCommand->Execute())
			AddUndo(pCommand);
	}

	void Undo()
	{
		if (CanUndo())
		{
			m_nCleanCount--;
			T* pCommand = m_undoList.back();
			m_undoList.pop_back();
			if (pCommand->Unexecute())
				AddRedo(pCommand);
			else
				delete pCommand;
		}
	}

	void Redo()
	{
		if (CanRedo())
		{
			m_nCleanCount++;
			T* pCommand = m_redoList.back();
			m_redoList.pop_back();
			if (pCommand->Execute())
				AddUndo(pCommand);
			else
				delete pCommand;
		}
	}

	void Clear()
	{
		ClearUndoList();
		ClearRedoList();
	}

	void SetClean()
	{
		m_nCleanCount = 0;
	}

	void AddUndo(T* pCommand)
	{
		if (m_undoList.size() >= m_nUndoLevel)
		{
			delete m_undoList.front();
			m_undoList.pop_front();
		}
		m_undoList.push_back(pCommand);
		if (m_nCleanCount < 0 && m_redoList.size() > 0)
			m_nCleanCount = m_undoList.size() + m_redoList.size() + 1;
		else
			m_nCleanCount++;
	}

	void AddRedo(T* pCommand)
	{
		m_redoList.push_back(pCommand);
	}

	void ClearUndoList()
	{
		ClearCommandList(&m_undoList);
	}

	void ClearRedoList()
	{
		ClearCommandList(&m_redoList);
	}

	void ClearCommandList(CommandList* pList)
	{
		CommandList::iterator it;
		for (it = pList->begin(); it != pList->end(); it++)
			delete *it;
		pList->erase(pList->begin(), pList->end());
	}
};

typedef CCommandManagerT<>	CommandManager;

#endif // !defined(AFX_COMMAND_H__413D14C5_DDA4_4F61_93D3_5405785E15FC__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -