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

📄 undostack.cpp

📁 《AE库通用模块及典型系统开发实例导航》光盘内容分享!
💻 CPP
字号:
// UndoStack.cpp: implementation of the CUndoStack class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SimpleEdit.h"
#include "UndoStack.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CUndoStack::CUndoStack()
{
	//将开始位置和结束位置均初始化为0
	m_Begin = 0;
	m_End = 0;
	for (int i = 0; i < UndoStackLen; i++)
	{
		m_List[i].LB = 0;
		m_List[i].lpData = NULL;
	}
}

CUndoStack::~CUndoStack()
{
	//清空堆栈中的数据并释放内存
	Clear();
}

bool CUndoStack::IsEmpty()
{
	//如果m_Begin和m_End相等则认为堆栈为空
	return m_Begin == m_End;
}

bool CUndoStack::IsFull()
{
	//因为本程序使用了循环的方式使用内存空间,
	//即在m_End等于UndoStackLen - 1时压栈会覆盖0这个位置,
	//同时m_Begin会加1,详细内容参考Push函数中的注释
	return ((m_End == UndoStackLen - 1) && (m_Begin == 0)) ||
		(m_End == m_Begin - 1);
}

void CUndoStack::Push(CUndoItem * ui)
{
	//堆栈为满
	if (IsFull())
	{
		//m_Begin和m_End都需要加1
		m_Begin++;
		m_End++;
		//循环使用堆栈的存储空间
		if (m_Begin >= UndoStackLen)
			m_Begin = 0;
		else if (m_End >= UndoStackLen)
			m_End = 0;
		//因为被覆盖,所以需要释放堆栈中原来的数据
		//根据不同的类别选择不同的释放方式
		//字符串类型按数组的方式来释放
		//LOGFONT类型直接释放
		if ((m_List[m_Begin].LB == 0) && (m_List[m_Begin].lpData))
		{
			delete [] LPTSTR(m_List[m_Begin].lpData);
			m_List[m_Begin].lpData = NULL;
		}
		else if (m_List[m_Begin].lpData)
		{
			delete m_List[m_Begin].lpData;	
			m_List[m_Begin].lpData = NULL;
		}
		if ((m_List[m_End].LB == 0) && (m_List[m_End].lpData))
		{
			delete [] m_List[m_End].lpData;
			m_List[m_End].lpData = NULL;
		}
		else if (m_List[m_End].lpData)
		{
			delete m_List[m_End].lpData;
			m_List[m_End].lpData = NULL;
		}
	}
	//堆栈为空
	else
	{
		m_End++;
		if (m_End >= UndoStackLen)
			m_End = 0;
	}
	m_List[m_End].LB = ui->LB;
	//存储的是字符串
	if (m_List[m_End].LB == 0)
	{
		//如果有数据,先释放
		if (m_List[m_End].lpData)
		{
			delete [] LPTSTR(m_List[m_End].lpData);
			m_List[m_End].lpData = NULL;
		}
		//重新分配空间
		m_List[m_End].lpData = new CHAR[strlen((LPSTR)(ui->lpData)) + 1];
		//复制字符串,用于保存
		strcpy((LPTSTR)(m_List[m_End].lpData), (LPSTR)(ui->lpData));
	}
	//存储的是字体
	else
	{
		//如果有数据,先释放
		if (m_List[m_End].lpData)
		{
			delete m_List[m_End].lpData;
			m_List[m_End].lpData = NULL;
		}
		//重新分配空间
		m_List[m_End].lpData = new LOGFONT;
		//复制字体,用于保存
		((LOGFONT *)(m_List[m_End].lpData))->lfHeight = ((LOGFONT *)(ui->lpData))->lfHeight;
		((LOGFONT *)(m_List[m_End].lpData))->lfWidth = ((LOGFONT *)(ui->lpData))->lfWidth;
		((LOGFONT *)(m_List[m_End].lpData))->lfEscapement = ((LOGFONT *)(ui->lpData))->lfEscapement;
		((LOGFONT *)(m_List[m_End].lpData))->lfOrientation = ((LOGFONT *)(ui->lpData))->lfOrientation;
		((LOGFONT *)(m_List[m_End].lpData))->lfWeight = ((LOGFONT *)(ui->lpData))->lfWeight;
		((LOGFONT *)(m_List[m_End].lpData))->lfItalic = ((LOGFONT *)(ui->lpData))->lfItalic;
		((LOGFONT *)(m_List[m_End].lpData))->lfUnderline = ((LOGFONT *)(ui->lpData))->lfUnderline;
		((LOGFONT *)(m_List[m_End].lpData))->lfStrikeOut = ((LOGFONT *)(ui->lpData))->lfStrikeOut;
		((LOGFONT *)(m_List[m_End].lpData))->lfCharSet = ((LOGFONT *)(ui->lpData))->lfCharSet;
		((LOGFONT *)(m_List[m_End].lpData))->lfOutPrecision = ((LOGFONT *)(ui->lpData))->lfOutPrecision;
		((LOGFONT *)(m_List[m_End].lpData))->lfClipPrecision = ((LOGFONT *)(ui->lpData))->lfClipPrecision;
		((LOGFONT *)(m_List[m_End].lpData))->lfQuality = ((LOGFONT *)(ui->lpData))->lfQuality;
		((LOGFONT *)(m_List[m_End].lpData))->lfPitchAndFamily = ((LOGFONT *)(ui->lpData))->lfPitchAndFamily;
		strcpy(((LOGFONT *)(m_List[m_End].lpData))->lfFaceName, ((LOGFONT *)(ui->lpData))->lfFaceName);
	}
}


bool CUndoStack::Pop(CUndoItem *ui)
{
	//如果堆栈为空或者用户没有传入用于保存Pop结果的结构指针,返回false
	if (IsEmpty() || ui == NULL)
		return false;

	//保存LB
	ui->LB = m_List[m_End].LB;
	
	//如果要出栈的为字符串
	if (m_List[m_End].LB == 0)
	{
		//释放原有空间
		if (ui->lpData)
		{
			delete [] ui->lpData;
			ui->lpData = NULL;
		}
		//分配并保存字符串
		ui->lpData = new CHAR[strlen((LPSTR)(m_List[m_End].lpData)) + 1];
		strcpy((char *)(ui->lpData), (char *)(m_List[m_End].lpData));
		//释放出栈内容所占的空间
		if (m_List[m_End].lpData)
		{
			delete [] m_List[m_End].lpData;
			m_List[m_End].lpData = NULL;
		}
	}
	//出栈的为字体类型
	else
	{
		//如果没有保存出栈字体的空间,则创建
		if (!ui->lpData)
		{
			ui->lpData = new LOGFONT;
		}
		
		//保存出栈的字体
		((LOGFONT *)(ui->lpData))->lfHeight = ((LOGFONT *)(m_List[m_End].lpData))->lfHeight;
		((LOGFONT *)(ui->lpData))->lfWidth = ((LOGFONT *)(m_List[m_End].lpData))->lfWidth;
		((LOGFONT *)(ui->lpData))->lfEscapement = ((LOGFONT *)(m_List[m_End].lpData))->lfEscapement;
		((LOGFONT *)(ui->lpData))->lfOrientation = ((LOGFONT *)(m_List[m_End].lpData))->lfOrientation;
		((LOGFONT *)(ui->lpData))->lfWeight = ((LOGFONT *)(m_List[m_End].lpData))->lfWeight;
		((LOGFONT *)(ui->lpData))->lfItalic = ((LOGFONT *)(m_List[m_End].lpData))->lfItalic;
		((LOGFONT *)(ui->lpData))->lfUnderline = ((LOGFONT *)(m_List[m_End].lpData))->lfUnderline;
		((LOGFONT *)(ui->lpData))->lfStrikeOut = ((LOGFONT *)(m_List[m_End].lpData))->lfStrikeOut;
		((LOGFONT *)(ui->lpData))->lfCharSet = ((LOGFONT *)(m_List[m_End].lpData))->lfCharSet;
		((LOGFONT *)(ui->lpData))->lfOutPrecision = ((LOGFONT *)(m_List[m_End].lpData))->lfOutPrecision;
		((LOGFONT *)(ui->lpData))->lfClipPrecision = ((LOGFONT *)(m_List[m_End].lpData))->lfClipPrecision;
		((LOGFONT *)(ui->lpData))->lfQuality = ((LOGFONT *)(m_List[m_End].lpData))->lfQuality;
		((LOGFONT *)(ui->lpData))->lfPitchAndFamily = ((LOGFONT *)(m_List[m_End].lpData))->lfPitchAndFamily;
		strcpy(((LOGFONT *)(ui->lpData))->lfFaceName, ((LOGFONT *)(m_List[m_End].lpData))->lfFaceName);
		
		//释放出栈内容所占的空间
		if (m_List[m_End].lpData)
		{
			delete m_List[m_End].lpData;
			m_List[m_End].lpData = NULL;
		}	
	}
	
	//将m_End减1,注意堆栈空间是循环使用的。
	if (m_End == 0)
	{
		m_End = UndoStackLen - 1;
	}
	else 
	{
		m_End--;
	}
	return true;
}

void CUndoStack::Clear()
{
	//如果堆栈为空则直接退出
	if (IsEmpty())
		return;

	int i;

	//如果m_End大于m_Begin,堆栈占用的是m_Begin + 1到m_End之间的空间。
	if (m_End > m_Begin)
	{
		for (i = m_Begin + 1; i <= m_End; i++)
		{
			if (m_List[i].lpData)
			{
				if (m_List[i].LB ==0)
				{
					delete [] m_List[i].lpData;
					m_List[i].lpData = NULL;
				}
				else
				{
					delete m_List[i].lpData;
					m_List[i].lpData = NULL;
				}
			}
		}
	}
	//如果m_End小于m_Begin,堆栈占用的是0到m_End与m_Begin + 1到UndoStackLen - 1之间的内存空间
	//这里虽然使用else,但不会出现m_End和m_Begin相等的情况,
	//因为当m_Begin和m_End相等时,IsEmpty()函数为true,在本方法的开始处就会退出
	else 
	{
		//使用0到m_End间的内存空间
		for (i = 0; i <= m_End; i++)
		{
			if (m_List[i].lpData)
			{
				if (m_List[i].LB == 0)
				{
					delete [] m_List[i].lpData;
					m_List[i].lpData = NULL;
				}
				else
				{
					delete m_List[i].lpData;
					m_List[i].lpData = NULL;
				}
			}
		}
		//释放m_Begin + 1到UndoStackLen - 1间的内存空间
		for (i = m_Begin + 1; i < UndoStackLen - 1; i++)
		{
			if (m_List[i].lpData)
			{
				if (m_List[i].LB == 0)
				{
					delete [] m_List[i].lpData;
					m_List[i].lpData = NULL;
				}
				else
				{
					delete m_List[i].lpData;
					m_List[i].lpData = NULL;
				}
			}
		}
	}
	//重置m_Begin,m_End
	m_Begin = 0;
	m_End = 0;
}

⌨️ 快捷键说明

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