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

📄 celldoc.cpp

📁 类似Excel的设计器源代码,基本实现电子图表的功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// CellDoc.cpp : implementation of the CCellDoc class
//

#include "stdafx.h"
#include "Cell.h"

#include "CellDoc.h"
#include <math.h> 
#include <stdlib.h>

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


/////////////////////////////////////////////////////////////////////////////
// CCellObj

IMPLEMENT_SERIAL(CCellObj, CObject, 0)//版本0

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


BOOL IsDigtal(LPCTSTR lpszTxt)
{
	CString szTxt=lpszTxt;

	szTxt.TrimLeft();
	szTxt.TrimRight();//去掉左右空格

	if(szTxt.IsEmpty())
		return FALSE;

	int nDotNum=0;

	int nLen=szTxt.GetLength();
	int i;
	char ct;
	for(i=0;i<nLen;i++)
	{
		ct=szTxt[i];
		if(ct=='.')
		{
			nDotNum++;
			if(nDotNum>1)
				return FALSE;
			continue;
		}
		if((ct < '0') || (ct > '9'))
			return FALSE;
	}
	return TRUE;
}
BOOL IsTxt(LPCTSTR lpszTxt)
{
	CString szt=lpszTxt;
	if(szt.IsEmpty())
		return TRUE;
	if(IsDigtal(lpszTxt))
		return FALSE;

	if(szt[0]=='=')
		return FALSE;
	return TRUE;
}
int GetFunction(LPCTSTR lpszTxt)//取公式,返回FUN_XXX
{
	CString szTxt=lpszTxt;

	szTxt.TrimLeft();
	szTxt.TrimRight();//去掉左右空格

	if(szTxt.IsEmpty())
		return FUN_NONE;
	if(szTxt[0] != '=')
		return FUN_NONE;

	int nLen=szTxt.GetLength();
	int i;
	char ct;
	BOOL bFunNameOk=FALSE;
	CString szt;
	szt.Empty();
	for(i=1;i<nLen;i++)
	{
		ct=szTxt[i];
		if(ct == '(')
		{
			bFunNameOk=TRUE;
			break;
		}
		szt+=ct;
	}
	if(bFunNameOk)
	{
		szt.MakeUpper();
		if(szt == "SUM")
			return FUN_SUM;
		if(szt == "MAX")
			return FUN_MAX;
		if(szt == "MIN")
			return FUN_MIN;
		if(szt == "AVERAGE")
			return FUN_AVERAGE;
		if(szt == "CURDATE")
			return FUN_CURDATE;
		if(szt == "GETDATAMEM")
			return FUN_GETDATAMEM;
		if(szt == "GETDATABASE")
			return FUN_GETDATABASE;
	}
	return FUN_ERROR;
}

BOOL Abc2Int(LPCTSTR lpszAbc,int *pn);

BOOL ParaseRowColString(LPCTSTR lpszTxt,int *pnRow,int *pnCol)//解析字符串表示的行列值
{

	CString szt=lpszTxt,szCol,szRow;
	int i,nLen=szt.GetLength();
	char ct;	
	
	szt.MakeUpper();
	szt.TrimLeft();
	szt.TrimRight();

	szCol="";
	szRow="";
	
	BOOL bColStrOk=FALSE;
	for(i=0;i<nLen;i++)
	{
		ct=szt[i];
		if((ct >='A')&&(ct<='Z'))
			szCol+=ct;
		else if((ct>='0')&&(ct<='9'))
		{
			if(bColStrOk==FALSE)//处理列
			{
				bColStrOk=TRUE;
				if(!Abc2Int(szCol,pnCol))
					return FALSE;
			}
			szRow+=ct;
		}
		else return FALSE;
	}
	
	if(bColStrOk==FALSE)//处理列
		return FALSE;
	if(szRow.IsEmpty())
		return FALSE;
	*pnRow=atoi(szRow)-1;
	return TRUE;
}


int ParaseRowColArg(LPCTSTR lpszTxt,
					 int *pnRow1,int *pnCol1,
					 int *pnRow2,int *pnCol2)//解析字符串表示的行列值;//返回0,1,2表示解析的个数
{

	
	CString szt=lpszTxt,szt1,szt2;
	int nret=0,i,nLen=szt.GetLength();
	char ct;	
	
	szt.MakeUpper();
	szt.TrimLeft();
	szt.TrimRight();

	if(szt.Find(':') < 0)
		nret=1;
	else 
		nret=2;
	szt1="";
	szt2="";
	for(i=0;i<nLen;i++)
	{
		ct=szt[i];
		if(ct !=':')
			szt1+=ct;
		else break;
	}
	if(nret==2)
	{
		for(int k=i+1;k<nLen;k++)
			szt2+=szt[k];
	}
	if(!ParaseRowColString(szt1,pnRow1,pnCol1))//解析字符串表示的行列值	
		return 0;

	if(nret==2)
	{
		if(!ParaseRowColString(szt2,pnRow2,pnCol2))//解析字符串表示的行列值	
			return 0;
		else 
			return 2;
	}
	return 1;
		
}


CCellObj::CCellObj()
{
	m_bSelected=FALSE;
	::GetObject(GetStockObject(DEFAULT_GUI_FONT),sizeof(LOGFONT),&m_logfont);	
	if(m_logfont.lfHeight<0)
		m_logfont.lfHeight*=-1;
	if(m_logfont.lfHeight<14)
		m_logfont.lfHeight=14;
	m_dwFlags= CELL_AUTODISP;//自动显示
	m_dwTxtAdjust=CELL_TXTLEFT | CELL_TXTVMID;
	m_clrBk=RGB(255,255,255);
	m_clrTxt=RGB(0,0,0);

	m_szDisp="0";

	m_dblVal=0;
	m_lDot=2;
}

CCellObj::~CCellObj()
{

}

void CCellObj::Serialize(CArchive& ar)
{
	CObject::Serialize(ar);
	if (ar.IsStoring())
	{
		ar << m_szDef;//定义,数字、字符串、公式(公式以=开头)
		ar << m_szDisp;//显示内容
		ar << m_dwFlags;//相关标志
		ar << m_dwTxtAdjust;//文本对齐方式
			
		ar << m_clrTxt;//文字颜色
		ar << m_clrBk;//填充背景色
		ar << m_lDot;//小数位数
		
		ar << m_dblVal;

		ar.Write(&m_logfont, sizeof(LOGFONT));
	}
	else
	{
		// get the document back pointer from the archive
		
		ar >> m_szDef;//定义,数字、字符串、公式(公式以=开头)
		ar >> m_szDisp;//显示内容

		ar >> m_dwFlags;//相关标志
		ar >> m_dwTxtAdjust;//文本对齐方式
	
		ar >> m_clrTxt;//文字颜色
		ar >> m_clrBk;//填充背景色
		ar >> m_lDot;//小数位数
		ar >> m_dblVal;

		ar.Read(&m_logfont, sizeof(LOGFONT));
	}
}

DWORD	CCellObj::GetTxtAdjust(void)
{
	return m_dwTxtAdjust;
}

DWORD	CCellObj::SetTxtAdjust(DWORD dwFlag)
{
	
	if(dwFlag < 0XFFFF)
		m_dwTxtAdjust=(m_dwTxtAdjust & 0xFFFF0000)|dwFlag;
	else
		m_dwTxtAdjust=(m_dwTxtAdjust & 0x0000FFFF)|dwFlag;
	return m_dwTxtAdjust;
}


BOOL	CCellObj::IsAutoDisp(void)
{
	return (m_dwFlags & CELL_AUTODISP);
}
/*
BOOL	CCellObj::IsTxtUnderLine(void)
{
	return (m_dwFlags & CELL_TXTUNDERLINE);
}
BOOL	CCellObj::IsTxtFat(void)
{
	return (m_dwFlags & CELL_TXTFAT);
}
BOOL	CCellObj::IsTxtXt(void)
{
	return (m_dwFlags & CELL_TXTXT);
}*/
BOOL	CCellObj::IsTxtWordBreak(void)
{
	return (m_dwFlags & CELL_TXTWORDBREAK);
}
BOOL	CCellObj::IsDataOk(void)
{
	return (m_dwFlags & CELL_DATAOK);
}

void	CCellObj::DelAutoDisp(void)
{
	m_dwFlags &= ~CELL_AUTODISP;
}
/*
void	CCellObj::DelTxtUnderLine(void)
{
	m_dwFlags &= ~CELL_TXTUNDERLINE;
}

void	CCellObj::DelTxtFat(void)
{
	m_dwFlags &= ~CELL_TXTFAT;
}
void	CCellObj::DelTxtXt(void)
{
	m_dwFlags &= ~CELL_TXTXT;
}*/
void	CCellObj::DelTxtWordBreak(void)
{
	m_dwFlags &= ~CELL_TXTWORDBREAK;
}
void	CCellObj::DelDataOk(void)
{
	m_dwFlags &= ~CELL_DATAOK;
}


void	CCellObj::SetTxtUnderLine(BOOL bk)
{
	m_logfont.lfUnderline=bk;
}
void	CCellObj::SetTxtFat(BOOL bk)
{
	if(bk)
		m_logfont.lfWeight=800;
	else
		m_logfont.lfWeight=400;
	
}
void	CCellObj::SetTxtXt(BOOL bk)
{
	m_logfont.lfItalic=bk;
}

void CCellObj::SetLogFont(LOGFONT *pFont)
{
	int nFontSize=m_logfont.lfHeight;
	int nWeight=m_logfont.lfWeight;
	BOOL bItalic=m_logfont.lfItalic;
	BOOL bUnderline=m_logfont.lfUnderline;
	::memcpy(&m_logfont,pFont,sizeof(LOGFONT));

	m_logfont.lfWeight=nWeight;
	m_logfont.lfItalic=bItalic;
	m_logfont.lfUnderline=bUnderline;
	m_logfont.lfHeight=nFontSize;
	m_logfont.lfWidth = 0;
}

void CCellObj::SetFontSize(int nH)
{
	m_logfont.lfHeight=nH;
	m_logfont.lfWidth = 0;
	
}

LOGFONT *CCellObj::GetLogFont(void)
{
	return &m_logfont;
}
int    CCellObj::CalDrawFmtAndRect(CDC *pDC,
									UINT *uFmt,
									CRect &rtDraw,
									CString &szTxt,BOOL *bExtend)//计算显示格式、所占区域大小、显示用文本返回字符串高度,-1表示字符串空
{
	UINT uFormat;
	CRect rt;
	CString szt;
	int nDataType;
	int nFun;
	if(IsDigtal(m_szDef))//数值
	{
		szt=m_szDef;
		m_dblVal=atof(szt);

		CString szdotfmt;
		szdotfmt.Format("%C%C%d%C",'%','.',m_lDot,'f');
		m_szDisp.Format(szdotfmt,m_dblVal);
		
		szt=m_szDisp;
		nDataType=CELL_DIGTAL;
		goto lpdo;
	}
	nFun=GetFunction(m_szDef);
	if(nFun == FUN_NONE)
	{
		szt=m_szDef;
		nDataType=CELL_TXT;
		*bExtend=TRUE;
	}
	else if(nFun == FUN_ERROR)
	{
		szt="FUN=?";
		nDataType=CELL_TXT;
		*bExtend=FALSE;
	}
	else if(nFun == FUN_CURDATE)
	{
		SYSTEMTIME syst;
		::GetLocalTime(&syst);
		szt.Format("%04d/%02d/%02d %02d:%02d:%02d",
			syst.wYear,syst.wMonth,syst.wDay,
			syst.wHour,syst.wMinute,syst.wSecond);
		nDataType=CELL_TXT;
		*bExtend=TRUE;
	}
	else
	{
		CString szdotfmt;
		szdotfmt.Format("%C%C%d%C",'%','.',m_lDot,'f');
		m_szDisp.Format(szdotfmt,m_dblVal);
		
		szt=m_szDisp;
		nDataType=CELL_DIGTAL;
		*bExtend=FALSE;
	}
	
lpdo:
	if(IsAutoDisp())//自动显示
	{
		if(nDataType==CELL_TXT)
			uFormat=DT_SINGLELINE | DT_LEFT | DT_VCENTER;
		else if((nDataType==CELL_DIGTAL)||(nDataType==CELL_FUN))
			uFormat=DT_SINGLELINE | DT_RIGHT | DT_VCENTER;
		else 
			uFormat=DT_SINGLELINE | DT_LEFT | DT_VCENTER;
	}
	else
	{
		if(m_dwFlags &	CELL_TXTWORDBREAK)
			uFormat=DT_LEFT | DT_TOP | DT_WORDBREAK;
		else
		{
			uFormat=DT_SINGLELINE;
			if((m_dwTxtAdjust & 0X0000FFFF)==CELL_TXTLEFT)
				uFormat|=DT_LEFT;

			if((m_dwTxtAdjust & 0X0000FFFF)==CELL_TXTRIGHT)
				uFormat|=DT_RIGHT;

			if((m_dwTxtAdjust & 0X0000FFFF)==CELL_TXTHMID)
				uFormat|=DT_CENTER;


			if((m_dwTxtAdjust & 0XFFFF0000)==CELL_TXTTOP)
				uFormat|=DT_TOP;

			if((m_dwTxtAdjust & 0XFFFF0000)==CELL_TXTVMID)
				uFormat|=DT_VCENTER;

			if((m_dwTxtAdjust & 0XFFFF0000)==CELL_TXTBOTTOM)
				uFormat|=DT_BOTTOM;
		}
	}
	szt.TrimLeft();
	szt.TrimRight();
	

	rt.left=500;
	rt.top=500;
	rt.right=510;
	rt.bottom=510;
	int nh;
	if(!(szt.IsEmpty()))
		nh=pDC->DrawText(szt,rt,uFormat | DT_CALCRECT);
	else
		nh=-1;
	*uFmt=uFormat;
	rtDraw=rt;
	szTxt=szt;

	return nh;
}

int		CCellObj::DrawBk(CDC *pDC,CRect &rtCell)
{
	if(m_clrBk != RGB(255,255,255))
	{
		CRect rt=rtCell;
		rt.right-=1;
		rt.bottom-=1;
//		rt.DeflateRect(1,1);
		pDC->FillSolidRect(rt,m_clrBk);
	}
	return 0;
}

int		CCellObj::DrawFrm(CDC *pDC,CRect &rtCell)//边框
{
	CPen pen(PS_SOLID,1,RGB(0,0,0));
	CPen *oldPen;
	oldPen=pDC->SelectObject(&pen);

	if(m_dwFlags & CELL_FRMLEFT)
	{
		pDC->MoveTo(rtCell.left,rtCell.top);
		pDC->LineTo(rtCell.left,rtCell.bottom);
	}

	if(m_dwFlags & CELL_FRMRIGHT)
	{
		pDC->MoveTo(rtCell.right,rtCell.top);
		pDC->LineTo(rtCell.right,rtCell.bottom);
	}

	if(m_dwFlags & CELL_FRMTOP)
	{
		pDC->MoveTo(rtCell.left,rtCell.top);
		pDC->LineTo(rtCell.right,rtCell.top);
	}

	if(m_dwFlags & CELL_FRMBOTTOM)
	{
		pDC->MoveTo(rtCell.left,rtCell.bottom);
		pDC->LineTo(rtCell.right,rtCell.bottom);
	}
	if(m_dwFlags & CELL_FRMLT2RB)
	{
		pDC->MoveTo(rtCell.left,rtCell.top);
		pDC->LineTo(rtCell.right,rtCell.bottom);
	}

	if(m_dwFlags & CELL_FRMLB2RT)
	{
		pDC->MoveTo(rtCell.left,rtCell.bottom);
		pDC->LineTo(rtCell.right,rtCell.top);
	}
	return 0;
}
int		CCellObj::Draw(CDC *pDC,CRect &rtCell)
{
	COLORREF clrOld=pDC->SetTextColor(m_clrTxt);//
	UINT oldmode=pDC->SetBkMode(TRANSPARENT);//

	CFont fontTxt,*oldFont;
	fontTxt.CreateFontIndirect(&m_logfont);
	oldFont=pDC->SelectObject(&fontTxt);//

	CRect rtAct,rtDraw;
	UINT uFmt;
	CString szTxt;
	int nh;
	BOOL bExtend;
	nh=CalDrawFmtAndRect(pDC,&uFmt,rtAct,szTxt,&bExtend);//计算显示格式、所占区域大小、显示用文本返回字符串高度,-1表示字符串空
	if(nh==-1)
	{
		//恢复
		pDC->SetTextColor(clrOld);	
		pDC->SetBkMode(oldmode);
		pDC->SelectObject(oldFont);
		return 0;
	}
	rtDraw=rtCell;
	if((rtCell.Width() < rtAct.Width())&&(bExtend==TRUE))
	{
		if((uFmt & DT_CENTER)==DT_CENTER)
		{
			int nt=(rtAct.Width()-rtCell.Width())/2;
			rtDraw.right += nt;
			rtDraw.left -= nt;
		}
		else if((uFmt & DT_RIGHT)==DT_RIGHT)
			rtDraw.left -= rtAct.Width()-rtCell.Width();
		else
			rtDraw.right += rtAct.Width()-rtCell.Width();

	}
	
	pDC->DrawText(szTxt,rtDraw,uFmt);

	//恢复
	pDC->SetTextColor(clrOld);
	pDC->SetBkMode(oldmode);
	pDC->SelectObject(oldFont);
	return 0;
}

/////////////////////////////////////////////////////////////////////////////
// CCellRow

IMPLEMENT_SERIAL(CCellRow, CObject, 0)//版本0

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

CCellRow::CCellRow()
{
	
}

CCellRow::CCellRow(int nCellNum)
{
	m_ArrayCell.SetSize(nCellNum,10);
	CCellObj *pObj;
	for(int i=0;i<nCellNum;i++)
	{
		pObj=new CCellObj();
		m_ArrayCell[i]=pObj;
	}
}

CCellRow::~CCellRow()
{
	CCellObj *pObj;
	int i,nNum;
	nNum=m_ArrayCell.GetSize();
	for(i=0;i<nNum;i++)
	{
		pObj=m_ArrayCell[i];
		if(pObj!=NULL)
			delete pObj;
	}
	m_ArrayCell.RemoveAll();
}

void CCellRow::Serialize(CArchive& ar)
{
	CObject::Serialize(ar);
	if (ar.IsStoring())
	{
		m_ArrayCell.Serialize(ar);
	}
	else
	{
		// get the document back pointer from the archive
		CCellObj *pObj;
		int i,nNum;
		nNum=m_ArrayCell.GetSize();
		for(i=0;i<nNum;i++)
		{
			pObj=m_ArrayCell[i];
			if(pObj!=NULL)
				delete pObj;
		}
		m_ArrayCell.RemoveAll();
		m_ArrayCell.Serialize(ar);
	}
}


/////////////////////////////////////////////////////////////////////////////
// CCellDoc

IMPLEMENT_DYNCREATE(CCellDoc, CDocument)

BEGIN_MESSAGE_MAP(CCellDoc, CDocument)
	//{{AFX_MSG_MAP(CCellDoc)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCellDoc construction/destruction

CCellDoc::CCellDoc()
{
	// TODO: add one-time construction code here
	m_warrayCol.SetSize(14,10);
	m_warrayRow.SetSize(50,10);

	int i;
	for(i=0;i<14;i++)
		m_warrayCol[i]=72;
	for(i=0;i<50;i++)
		m_warrayRow[i]=20;

	m_nWidthFixCol=40;//固定列宽
	m_nHigthFixRow=20;//固定行高

	m_nTopX=41;
	m_nTopY=21;

	m_nTopLeftRowNo=0;//作上角行号
	m_nTopLeftColNo=0;//作上角列号

	m_ArrayRow.SetSize(50,10);
	CCellRow *pRow;
	for(i=0;i<50;i++)
	{
		pRow=new CCellRow(14);
		m_ArrayRow[i]=pRow;
	}
}

CCellDoc::~CCellDoc()
{
	CCellRow *pObj;
	int i,nNum;
	nNum=m_ArrayRow.GetSize();
	for(i=0;i<nNum;i++)
	{
		pObj=m_ArrayRow[i];
		if(pObj!=NULL)
			delete pObj;
	}
	m_ArrayRow.RemoveAll();
}

BOOL CCellDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}

⌨️ 快捷键说明

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