imageobject.cpp

来自「深入浅出Visual C++入门进阶与应用实例 随书光盘 作者 何志丹」· C++ 代码 · 共 336 行

CPP
336
字号
// ImageObject.cpp: implementation of the CImageObject class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Ex070201.h"
#include "ImageObject.h"

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

//CImageObject====================================
IMPLEMENT_DYNCREATE(CImageObject, CObject)

CImageObject::CImageObject()
{
	m_iLayer = 1 ;
}

CImageObject::~CImageObject()
{

}

void CImageObject::Draw(CDC *pDC)
{
	switch(m_iLayer)//根据图层设置颜色
	{
	case 1: pDC->SetTextColor(RGB(255,0,0)); break;
	case 2: pDC->SetTextColor(RGB(0,255,0)); break;
	case 3: pDC->SetTextColor(RGB(0,0,255)); break;
	default:break ;
	}
}

CImageObject* CImageObject::ReadObject(CFile& file)
{
	//读取图形对象的类型,并构建对应类型的对象
	long iType ;
	if(file.Read(&iType,sizeof(iType)) < sizeof(iType) )
		return NULL ;
	//类名称必须对应 
	CRuntimeClass * pRunClass[] ={RUNTIME_CLASS(CImageObject), RUNTIME_CLASS(CSquareObject),RUNTIME_CLASS(CTextObject)};	
	CImageObject * pImage = (CImageObject*)pRunClass[iType]->CreateObject() ;
	if(NULL == pImage)
		return NULL ;
	pImage->Read(file);//调用对应类型的读文件
	return pImage ;					
}

bool CImageObject::Read(CFile &file)
{
	if(!file.Read(&m_iLayer,sizeof(m_iLayer)))
		return false ;

	return true ;
}

bool CImageObject::Write(CFile &file)
{
	file.Write(&m_iType,sizeof(m_iType)) ;
	file.Write(&m_iLayer,sizeof(m_iLayer)) ;
	
	return true ;
}

//CSquareObject=======================================
IMPLEMENT_DYNCREATE(CSquareObject, CImageObject)

CSquareObject::CSquareObject()
{
	m_iType = SQUARE ;
}

void CSquareObject::Draw(CDC *pDC)
{
	CImageObject::Draw(pDC);

	CRect r(m_ptTopLeft,m_ptTopLeft);
	r.right		+= m_nWidth ;
	r.bottom	+= m_nWidth ;
	pDC->Rectangle(r);	//画一个矩形
}

bool CSquareObject::Read(CFile &file)
{
	if(!CImageObject::Read(file))
		return false ;
	
	if(!file.Read(&m_ptTopLeft.x,sizeof(LONG)))
		return false ;
	if(!file.Read(&m_ptTopLeft.y,sizeof(LONG)))
		return false ;
	if(!file.Read(&m_nWidth,sizeof(long)))
		return false ;
	
	return true ;
}

bool CSquareObject::Write(CFile &file)
{
	if(!CImageObject::Write(file))
		return false ;

	file.Write(&m_ptTopLeft.x,sizeof(LONG)) ;
	file.Write(&m_ptTopLeft.y,sizeof(LONG));
	file.Write(&m_nWidth,sizeof(long));

	return true ;	
}

//CTextObject=========================================
IMPLEMENT_DYNCREATE(CTextObject, CImageObject)

CTextObject::CTextObject()
{
	m_iType = TEXT ;
}

void CTextObject::Draw(CDC *pDC)
{
	CImageObject::Draw(pDC);

	pDC->TextOut(m_ptTopLeft.x,m_ptTopLeft.y,m_strText);
}

bool CTextObject::Read(CFile &file)
{
	if(!CImageObject::Read(file))
		return false ;
	
	if(!file.Read(&m_ptTopLeft.x,sizeof(LONG)))
		return false ;
	if(!file.Read(&m_ptTopLeft.y,sizeof(LONG)))
		return false ;
	
	long nLeng ;
	if(!file.Read(&nLeng,sizeof(long)))
		return false ;
	char * pTmp = new char[nLeng+1];
	memset(pTmp,'\0',nLeng+1);
	if(!file.Read(pTmp,nLeng))
	{
		delete pTmp ;
		return false ;
	}
	m_strText = pTmp ;
	delete [] pTmp ;

	return true ;
}

bool CTextObject::Write(CFile &file)
{
	if(!CImageObject::Write(file))
		return false ;
	
	file.Write(&m_ptTopLeft.x,sizeof(LONG)) ;
	file.Write(&m_ptTopLeft.y,sizeof(LONG)) ;
	
	long nLeng = m_strText.GetLength() ;
	file.Write(&nLeng,sizeof(long));
	file.Write((LPCTSTR)m_strText,nLeng);

	return true ;	
}

//CImageObjectManage=====================
CImageObjectManage::CImageObjectManage()
{
	i_strFileName = "d:\\test.txt" ;
}

CImageObjectManage::~CImageObjectManage()
{
	Release();
}

void CImageObjectManage::Draw(CDC *pDC)
{
	for(int i = 0 ; i < m_objs.GetSize() ; i++ )
		m_objs[i]->Draw(pDC);
}

//nShowLayer为0表示读取所有的层
bool CImageObjectManage::ReadFile(long nShowLayer)
{
	Release();
	
	CFile file ;
	if(!file.Open(i_strFileName,CFile::modeRead))
		return false ;
	long nLayerNum = 0 ;
	file.Read(&nLayerNum,sizeof(long));
	if(0 == nShowLayer)//读所有的层
	{
		int nPos = sizeof(long) + sizeof(long)*2*nLayerNum ;
		file.Seek(nPos,CFile::begin);
		do
		{
			CImageObject * pObject = CImageObject::ReadObject(file);
			if(NULL == pObject)
				break ;//文件结束
			m_objs.Add(pObject);
		}while(true);
	}
	else
	{
		long nLayer,nPos ;
		for(int i = 0 ; i < nLayerNum ; i++ )
		{
			file.Read(&nLayer,sizeof(long));
			file.Read(&nPos,sizeof(long));
			if(nShowLayer == nLayer)
			{				
				file.Seek(nPos,CFile::begin);//移动文件指针到对应图层的起始处
				while(true)
				{
					CImageObject * pObject = CImageObject::ReadObject(file);
					if(NULL == pObject)
						break ;
					if(nShowLayer != pObject->m_iLayer)
					{//对图层的图像读取结束
						delete pObject ;
						break ;
					}
					m_objs.Add(pObject);
				}
				break;
			}	
		}
		
	}
	file.Close();
	return true ;
}

bool CImageObjectManage::WriteFile()
{
	const int nObjNum = m_objs.GetSize() ;
	if( 0 == nObjNum )
		return false ;
	//对图形元素按图层进行排序
	for(int i = 0 ; i < nObjNum -1 ; i++ )
		for(int j = i + 1 ; j < nObjNum ; j++ )
		{
			if(m_objs[i]->m_iLayer > m_objs[j]->m_iLayer)
			{
				CImageObject * pTmp = m_objs[i] ;
				m_objs[i] = m_objs[j] ;
				m_objs[j] = pTmp ;
			}
		}

    //取得图层的总数
	CMap<long,long,long,long> arLayerToPos ;
	long nCurLayer = m_objs[0]->m_iLayer ;
	arLayerToPos[nCurLayer] = 0 ;
	for(i = 0 ; i < nObjNum ; i++ )
	{
		if( nCurLayer != m_objs[i]->m_iLayer )
		{
			nCurLayer = m_objs[i]->m_iLayer ;
			arLayerToPos[nCurLayer] = 0 ;
		}
	}

	CFile file ;
	if(!file.Open(i_strFileName,CFile::modeCreate|CFile::modeWrite))
		return false ;
	//写文件主体部分
	file.Seek(sizeof(long) + sizeof(long)*2*arLayerToPos.GetCount(),CFile::begin);
	nCurLayer = m_objs[0]->m_iLayer ;
	arLayerToPos[nCurLayer] = file.Seek(0,CFile::current);//取得当前位置
	for(i = 0 ; i < nObjNum ; i++)
	{	
		if(nCurLayer != m_objs[i]->m_iLayer )
		{
			nCurLayer = m_objs[i]->m_iLayer ;
			arLayerToPos[nCurLayer] = file.Seek(0,CFile::current);
		}
		m_objs[i]->Write(file);		
	}
	//写文件头
	file.Seek(0,CFile::begin);
	const long nLayerNum = arLayerToPos.GetCount() ;
	file.Write(&nLayerNum,sizeof(long));
	for(POSITION pos = arLayerToPos.GetStartPosition() ; NULL != pos ; )
	{
		long nPos ;
		arLayerToPos.GetNextAssoc(pos,nCurLayer,nPos);
		file.Write(&nCurLayer,sizeof(long));
		file.Write(&nPos,sizeof(long));
	}
	file.Close();
	return true ;
}

void CImageObjectManage::Release()
{
	for(int i = m_objs.GetSize() - 1 ; i >= 0 ; i--)
	{
		delete m_objs[i] ;
	}
	m_objs.RemoveAll();
}

void CImageObjectManage::Init()
{
	Release();

	//随机生成数据
	for(int i = 0 ; i < 10 ; i++ )
	{//生成10个矩形对象
		CSquareObject * pObj = new CSquareObject();
		pObj->m_iLayer = 1 + rand () % 3 ;//图层随机生成,1~3之间
		pObj->m_ptTopLeft.x = rand() % 300 ;//左上角顶点的横坐标0~300之间
		pObj->m_ptTopLeft.y = rand() % 300 ;//左上角顶点的纵坐标0~300之间
		pObj->m_nWidth = rand()% 20 + 10 ;//宽在10~30之间
		m_objs.Add(pObj);
	}
	for(i = 0 ; i < 10 ; i++ )
	{//生成10个文字对象
		CTextObject * pObj = new CTextObject();
		pObj->m_iLayer = 1 + rand () % 3 ;//图层随机生成,1~3之间
		pObj->m_ptTopLeft.x = rand() % 300 ;//左上角顶点的横坐标0~300之间
		pObj->m_ptTopLeft.y = rand() % 300 ;//左上角顶点的纵坐标0~300之间
		pObj->m_strText = CString('A' + rand()% 26) ;//26个大写字母中的一个
		m_objs.Add(pObj);
	}
}

⌨️ 快捷键说明

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