📄 undostack.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 + -