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

📄 demo2doc.cpp

📁 Viaual C++实战演练一书的源代码,对于C++程序员有实际的借鉴意义.
💻 CPP
字号:
// Demo2Doc.cpp : implementation of the CDemo2Doc class
//

#include "stdafx.h"
#include "Demo2.h"
#include "map.h"

#include "Demo2Doc.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDemo2Doc

IMPLEMENT_DYNCREATE(CDemo2Doc, CDocument)

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

/////////////////////////////////////////////////////////////////////////////
// CDemo2Doc construction/destruction

CDemo2Doc::CDemo2Doc()
{
	// TODO: add one-time construction code here
	m_pMemDC = NULL;
	m_pBitmap = NULL;
	m_pData = NULL;
	m_nMaxPoint = 0;
	//设置初始偏移位置
	m_nOffsetX = 0;
	m_nOffsetY = 0;
	//初始化文档标题
	m_strMapName = _T("无海图");
}

CDemo2Doc::~CDemo2Doc()
{
	if(m_aLayers.GetSize()>0)
	{
		int i;
		for(i = m_aLayers.GetSize(); i>0; i--)
		{
			delete m_aLayers.GetAt(i-1);
		}
		m_aLayers.RemoveAll();
	}

	if(m_pMemDC)
	{//清除程序创建的DC资源
		m_pMemDC->SelectObject(m_pDefaultBitmap);
		m_pMemDC->DeleteDC();
		m_pMemDC = NULL;
	}

	if(m_pBitmap)
	{//清除程序创建的BITMAP资源
		m_pBitmap->DeleteObject();
		delete m_pBitmap;
		m_pBitmap = NULL;
	}

	if(m_pData)
	{//清除绘图用整数数组
		m_nMaxPoint = 0;
		delete[] m_pData;
		m_pData = NULL;
	}
}

BOOL CDemo2Doc::OnNewDocument()
{//用户关闭文件时,程序调用该函数
	if (!CDocument::OnNewDocument())
		return FALSE;

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

	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CDemo2Doc serialization

void CDemo2Doc::Serialize(CArchive& ar)
{//读海图数据,同时绘制海图
	if (ar.IsStoring())
	{
		// TODO: add storing code here
		/*
		m_fMapjw[0]=105.0;//海图左边界经度
		m_fMapjw[1]=120.0;//海图右边界经度
		m_fMapjw[2]=28.0;//海图上边界纬度
		m_fMapjw[3]=15.0;//海图下边界纬度(南纬为负)
		m_fMaxCX = 8430;
		m_fMaxCY = 10562;
		m_strMapName = _T("中国东部海区");
		ar << 123456;//保存文件类型标志
		ar << m_strMapName;//海图名称
		ar << m_fMapjw[0] << m_fMapjw[1] << m_fMapjw[2] << m_fMapjw[3];//本海图经纬度范围
		ar << m_fMaxCX << m_fMaxCY ;//海图初始显示范围
		ar << 4;//图层数量
		CString layer;
		layer=_T("海岸线");//海岸线层名称
		ar << layer;
		layer=_T("Coast");//海岸线层文件名(不含扩展名)
		ar << layer;
		layer=_T("等深线");//等深线层名称
		ar << layer;
		layer=_T("Isobath");//等深线层文件名(不含扩展名)
		ar << layer;
		layer=_T("岛屿");//岛屿层名称
		ar << layer;
		layer=_T("Island");//岛屿层文件名(不含扩展名)
		ar << layer;
		layer=_T("大城市");//大城市层名称
		ar << layer;
		layer=_T("City");//大城市层文件名(不含扩展名)
		ar << layer;
		*/
	}
	else
	{
		// TODO: add loading code here
		long filestyle;
		ar >> filestyle;//读海图控制文件标志
		if(filestyle != 123456)
		{
			AfxMessageBox("文件类型错:打开文件非海图控制文件!");
			return;
		}

		InitData();//清理用户数据

		//获得海图数据所在的路径
		CString strPath=ar.GetFile()->GetFilePath();
		int len=strPath.GetLength();
		for(;strPath.GetAt(len-1) != '\\';len--);
		strPath = strPath.Left(len);//strPath为全路径名

		ar >> m_strMapName;//取海图名
		ar >> m_fMapjw[0] >> m_fMapjw[1] >> m_fMapjw[2] >> m_fMapjw[3];//取海图经纬度范围
		ar >> m_fMaxCX >> m_fMaxCY;//取海图初始大小
		int i, number;
		ar >>number;//取海图总层数
		CMapLayer *pMap;
		//读各海图层数据
		for(i=0;i<number;i++)
		{
			CString strLayername, strLayerfile;
			ar >> strLayername;//取海图图层名
			ar >> strLayerfile;//取海图文件名(无后缀)
			strLayerfile = strPath + strLayerfile + _T(".MIF");
			CFile file;
			if(file.Open(LPCTSTR(strLayerfile), CFile::modeRead))
			{
				CArchive lar(&file, CArchive::load);
				pMap = new CMapLayer(this, lar);
				pMap->m_strLayerName = strLayername;
				m_aLayers.Add(pMap);
				m_nMaxPoint = m_nMaxPoint > pMap->m_nMaxPoint ? m_nMaxPoint : pMap->m_nMaxPoint;
			}
		}
		m_pData = new long[m_nMaxPoint*2];//申请计算用临时内存
		DrawMap(m_pMemDC);//在位图上绘制海图
		SetLayerMenu();//设置屏幕菜单
	}
}

void CDemo2Doc::ConvToXY(double jing, double wei, long& cx, long& cy)
{
	cx = (long)((m_fMaxCX * (jing-m_fMapjw[0]))/(m_fMapjw[1]-m_fMapjw[0])+0.5);
	cy = (long)((m_fMaxCY * (relfa(m_fMapjw[2])-relfa(wei)))/(relfa(m_fMapjw[2]) - relfa(m_fMapjw[3]))+0.5);
}

void CDemo2Doc::ConvToXYs(double* jw, long* xy, int n)
{
	int i;
	double jing, wei;
	for(i=0;i<n;i++)
	{
		jing = *(jw + i*2);
		wei = *(jw + i*2 + 1);
		*(xy + i*2) = (long)((m_fMaxCX * (jing-m_fMapjw[0]))/(m_fMapjw[1]-m_fMapjw[0])+0.5);
		*(xy + i*2+1) = (long)((m_fMaxCY * (relfa(m_fMapjw[2])-relfa(wei)))/(relfa(m_fMapjw[2]) - relfa(m_fMapjw[3]))+0.5);
	}
}

void CDemo2Doc::ConvToJW(long cx, long cy, double& jing, double& wei)
{
	jing = m_fMapjw[0] + cx*(m_fMapjw[1] - m_fMapjw[0]) / m_fMaxCX;
	wei = (absfa(relfa(m_fMapjw[2]) - cy * (relfa(m_fMapjw[2]) - relfa(m_fMapjw[3])) / m_fMaxCY));
	for(; jing > 180.0 ; jing -=360);
	for(; jing < -180.0 ; jing += 360);
}

void CDemo2Doc::DrawMap(CDC* pDC)
{
	int i;
	int j = m_aLayers.GetSize();
	CMapLayer* player;

	//清空原位图
	pDC->BitBlt(0, 0, m_nViewWidth, m_nVeiwHeight, NULL, 0, 0, WHITENESS);

	//以下程序开始绘制海图
	//由于海图中各图元重叠时会互相遮挡,必须分别绘制
	//绘制顺序为:面图元,线图元,点图元(文字等)
	for(i=0; i<j; i++)
	{//遍历各海图层,绘区域图元
		player = m_aLayers.GetAt(i);
		if(player->m_bCanDraw)
		{
			player->Draw(pDC, IDS_POLYGON);
		}
	}
	for(i=0; i<j; i++)
	{//遍历各海图层,绘折线图元
		player = m_aLayers.GetAt(i);
		if(player->m_bCanDraw)
		{
			player->Draw(pDC, IDS_PLINE);
		}
	}
	for(i=0; i<j; i++)
	{//遍历各海图层,绘文字图元
		player = m_aLayers.GetAt(i);
		if(player->m_bCanDraw)
		{
			player->Draw(pDC, IDS_TEXT);
		}
	}
}

void CDemo2Doc::Zoom(float scale)
{
	m_fMaxCX *= scale;
	m_fMaxCY *= scale;
}

void CDemo2Doc::LPtoDPs(long* data, int n)
{
	int i;

	for(i=0; i<n; i++)
	{
		*(data + 2*i) += m_nOffsetX;
		*(data + 2*i+1) += m_nOffsetY;
	}
}

void CDemo2Doc::LPtoDP(long& x, long& y)
{
	x += m_nOffsetX;
	y += m_nOffsetY;
}

void CDemo2Doc::DPtoLP(long& x, long& y)
{
	x -= m_nOffsetX;
	y -= m_nOffsetY;
}

void CDemo2Doc::SetCenter(CPoint point)
{
	m_nOffsetX = m_nViewWidth / 2 - point.x;
	m_nOffsetY = m_nVeiwHeight / 2 - point.y;
}

void CDemo2Doc::MoveOffset(CPoint point)
{
	m_nOffsetX += point.x;
	m_nOffsetY += point.y;
}

void CDemo2Doc::SetLayerMenu(bool open)
{
	int iPos;
	CMenu *pMenu, *pLayerMenu = NULL;
	CMenu* pTopMenu = AfxGetMainWnd()->GetMenu();//获得主菜单句柄

	for (iPos = pTopMenu->GetMenuItemCount()-1; iPos >= 0; iPos--)
	{//遍历主菜单栏中各项
		pMenu = pTopMenu->GetSubMenu(iPos);//获得对应的子菜单
		if (pMenu && pMenu->GetMenuItemID(0) == ID_MENUITEM_LAYER1)
		{//检索指定的菜单项
			pLayerMenu = pMenu;
			break;
		}
	}
	ASSERT(pLayerMenu != NULL);
	//删除原有菜单
	for (iPos = pLayerMenu->GetMenuItemCount()-1; iPos >= 0; iPos--)
		pLayerMenu->DeleteMenu(iPos, MF_BYPOSITION);
	
	if(!open)
	{
		pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER1, _T("(空)"));
		return;
	}
	
	iPos = m_aLayers.GetSize();
	if(iPos == 0)
		pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER1, _T("(空)"));
	if(iPos >0)
		pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER1, m_aLayers.GetAt(0)->m_strLayerName);
	if(iPos >1)
		pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER2, m_aLayers.GetAt(1)->m_strLayerName);
	if(iPos >2)
		pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER3, m_aLayers.GetAt(2)->m_strLayerName);
	if(iPos >3)
		pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER4, m_aLayers.GetAt(3)->m_strLayerName);
}

void CDemo2Doc::InitData()
{
	if(m_aLayers.GetSize()>0)
	{
		int i;
		for(i = m_aLayers.GetSize(); i>0; i--)
		{
			delete m_aLayers.GetAt(i-1);
		}
		m_aLayers.RemoveAll();
	}

	if(m_nMaxPoint)
	{//清除绘图用整数数组
		m_nMaxPoint = 0;
		delete[] m_pData;
		m_pData = NULL;
	}

	//设置初始偏移位置
	m_nOffsetX = 0;
	m_nOffsetY = 0;

	//初始化文档标题
	m_strMapName = _T("无海图");
}

void CDemo2Doc::DisplayLocationOnStatusBar(CPoint point)
{
	if(!m_aLayers.GetSize())
	{//未打开海图
		return;
	}

	CStatusBar* pStatus = (CStatusBar*) AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
		//AFX_IDW_STATUS_BAR 为系统预定义常量(StatusBar的缺省ID)

	CPoint pt = point;
	double jing, wei;

	DPtoLP(pt.x, pt.y);//转换为逻辑坐标
	ConvToJW(pt.x, pt.y, jing, wei);//转换为经纬度
	CString strlon, strlat;
	int degree = jing;
	int minute = (jing - degree)*60;
	int secend = (jing - degree)*3600 - minute*60;
	if(jing<0)
		strlon.Format("  西经:%3d度 %2d分 %2d秒    ", -degree, -minute, -secend);
	else
		strlon.Format("  东经:%3d度 %2d分 %2d秒    ", degree, minute, secend);

	degree = wei;
	minute = (wei - degree)*60;
	secend = (wei - degree)*3600 - minute*60;
	if(wei<0)
		strlat.Format("南纬:%3d度 %2d分 %2d秒", -degree, -minute, -secend);
	else
		strlat.Format("北纬:%3d度 %2d分 %2d秒", degree, minute, secend);

	pStatus->SetPaneText(0, strlon+strlat);//在状态条中显示经纬度
}

/////////////////////////////////////////////////////////////////////////////
// CDemo2Doc diagnostics

#ifdef _DEBUG
void CDemo2Doc::AssertValid() const
{
	CDocument::AssertValid();
}

void CDemo2Doc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDemo2Doc commands


void CDemo2Doc::SetTitle(LPCTSTR lpszTitle) 
{
	// TODO: Add your specialized code here and/or call the base class
	//设置文档标题
	CDocument::SetTitle(LPCTSTR(m_strMapName));
}

⌨️ 快捷键说明

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