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

📄 zmapview.cpp

📁 一个微型的地图浏览工具
💻 CPP
字号:
// zMapView.cpp : implementation of the CZMapView class
//

#include "stdafx.h"
#include "zMap.h"

#include "zMapDoc.h"
#include "zMapView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CZMapView

IMPLEMENT_DYNCREATE(CZMapView, CView)

BEGIN_MESSAGE_MAP(CZMapView, CView)
	//{{AFX_MSG_MAP(CZMapView)
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_SETCURSOR()
	ON_COMMAND(ID_ZOOM_IN, OnZoomIn)
	ON_COMMAND(ID_ZOOM_OUT, OnZoomOut)
	ON_UPDATE_COMMAND_UI(ID_ZOOM_IN, OnUpdateZoomIn)
	ON_UPDATE_COMMAND_UI(ID_ZOOM_OUT, OnUpdateZoomOut)
	ON_COMMAND(ID_PAN, OnPan)
	ON_UPDATE_COMMAND_UI(ID_PAN, OnUpdatePan)
	ON_COMMAND(ID_VIEW_ENTIRE, OnViewEntire)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CZMapView construction/destruction

CZMapView::CZMapView()
{
	// TODO: add construction code here
	m_nViewState = 0;
	m_bMoving = FALSE;

}

CZMapView::~CZMapView()
{
}

BOOL CZMapView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	m_nCursorType = 0;

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CZMapView drawing

void CZMapView::OnDraw(CDC* pDC)
{
	CZMapDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
		CRect rc;
	this->GetClientRect(&rc);
	int nWidth = rc.Width();
	int nHeight = rc.Height();


	CDC MemDC; //首先定义一个显示设备对象
	CBitmap MemBitmap;//定义一个位图对象
	
	//随后建立与屏幕显示兼容的内存显示设备
	MemDC.CreateCompatibleDC(NULL);
	//这时还不能绘图,因为没有地方画 ^_^
	//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
	MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
	
	//将位图选入到内存显示设备中
	//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
	CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
	
	//先用背景色将位图清除干净,这里我用的是白色作为背景
	//你也可以用自己应该用的颜色
	MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(192,192,192));

	CBrush newBrush(RGB(246,174,139));

	CBrush * pOldBrush = MemDC.SelectObject(&newBrush);


	// TODO: add draw code for native data here

	theApp.m_ptViewCenter.x = (theApp.m_rcViewBounds.left+theApp.m_rcViewBounds.right)/2;
	theApp.m_ptViewCenter.y = (theApp.m_rcViewBounds.top+theApp.m_rcViewBounds.bottom)/2;

	if(theApp.m_nRecCount>0)
	{
		CFile geoFile;
		geoFile.Open(theApp.m_strFileName,CFile::modeRead);
		
		for(int i=0;i<theApp.m_nRecCount;i++)
		{
			int nPos = theApp.m_geoInfos[i].nPos;
			geoFile.Seek(nPos,CFile::begin);
			int nA;
			geoFile.Read(&nA,sizeof(int));

			int nPtCount = 0;
			if(nA == 1)
			{
				geoFile.Read(&nPtCount,sizeof(int));
				
				CPoint *pts = new CPoint[nPtCount];
				CPoint2D  *geoPts = new CPoint2D[nPtCount];
				
				for(int j=0;j<nPtCount;j++)
				{
					geoFile.Read(&geoPts[j].m_dx,sizeof(double));
					geoFile.Read(&geoPts[j].m_dy,sizeof(double));
					WP2DP(geoPts[j],pts[j]);
				}
				
				MemDC.Polygon(pts,nPtCount);
				
				delete []geoPts;
				delete []pts;
			}
			else
			{
				int *pNI = new int[nA];
				for(int a=0;a<nA;a++)
				{
					geoFile.Read(&pNI[a],sizeof(int));
					nPtCount += pNI[a];
				}

				CPoint *pts = new CPoint[nPtCount];
				CPoint2D  *geoPts = new CPoint2D[nPtCount];
				
				for(int j=0;j<nPtCount;j++)
				{
					geoFile.Read(&geoPts[j].m_dx,sizeof(double));
					geoFile.Read(&geoPts[j].m_dy,sizeof(double));
					WP2DP(geoPts[j],pts[j]);
				}
				
				MemDC.PolyPolygon(pts,pNI,nA);
				
				delete []geoPts;
				delete []pts;

				delete []pNI;
			}

		}
		
	}

	MemDC.SelectObject(pOldBrush);


	//将内存中的图拷贝到屏幕上进行显示
	pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
	
	//绘图完成后的清理
	MemBitmap.DeleteObject();
	MemDC.DeleteDC();
}

/////////////////////////////////////////////////////////////////////////////
// CZMapView printing

BOOL CZMapView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CZMapView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CZMapView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CZMapView diagnostics

#ifdef _DEBUG
void CZMapView::AssertValid() const
{
	CView::AssertValid();
}

void CZMapView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CZMapDoc* CZMapView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CZMapDoc)));
	return (CZMapDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CZMapView message handlers
void CZMapView::WP2DP(CPoint2D &ptOrg, CPoint &ptDest)
{
	ptDest.x = (int)((ptOrg.m_dx - theApp.m_ptDtCenter.m_dx)*theApp.m_dZoomRatio/theApp.m_dScale+theApp.m_ptViewCenter.x);
	ptDest.y = (int)((theApp.m_ptDtCenter.m_dy-ptOrg.m_dy)*theApp.m_dZoomRatio/theApp.m_dScale+theApp.m_ptViewCenter.y);
}

BOOL CZMapView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	
	//return CView::OnEraseBkgnd(pDC);
	return TRUE;
}

void CZMapView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	if(m_nViewState == 3)
	{
		m_bMoving = TRUE;
		m_dCenterX = theApp.m_ptDtCenter.m_dx;
		m_dCenterY = theApp.m_ptDtCenter.m_dy;
		
		m_ptOrg = point;
	}
	CView::OnLButtonDown(nFlags, point);
}

void CZMapView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	switch(m_nViewState)
	{
	case 1:
		theApp.m_dZoomRatio *= 1.25;
		break;
	case 2:
		theApp.m_dZoomRatio /= 1.25;
		break;
	case 3:
		m_bMoving = FALSE;
		break;
	}
	Invalidate();
	CView::OnLButtonUp(nFlags, point);
}

void CZMapView::OnMouseMove(UINT nFlags, CPoint point) 
{
	if( m_bMoving)
	{
		theApp.m_ptDtCenter.m_dx = m_dCenterX - (point.x-m_ptOrg.x)*theApp.m_dScale*theApp.m_dZoomRatio; 
		theApp.m_ptDtCenter.m_dy = m_dCenterY - (m_ptOrg.y-point.y)*theApp.m_dScale*theApp.m_dZoomRatio;
		
		Invalidate();
	}
	CView::OnMouseMove(nFlags, point);
}

BOOL CZMapView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	switch(m_nCursorType)
	{
	case 0:
		SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
		break;
	case 1:
		SetCursor(theApp.LoadCursor(IDC_CURSOR_ZOOMIN));
		break;
	case 2:
		SetCursor(theApp.LoadCursor(IDC_CURSOR_ZOOMOUT));
		break;
	case 3:
		SetCursor(theApp.LoadCursor(IDC_CURSOR_PAN));
		break;
		
	}
	
	return TRUE;
	//return CView::OnSetCursor(pWnd, nHitTest, message);
}

void CZMapView::OnZoomIn() 
{
	if(m_nViewState != 1)
	{
		m_nViewState = 1;
		m_nCursorType = 1;
	}
	else
	{
		m_nViewState = 0;
		m_nCursorType = 0;
	}
}

void CZMapView::OnZoomOut() 
{
	if(m_nViewState != 2)
	{
		m_nViewState = 2;
		m_nCursorType = 2;
	}
	else
	{
		m_nViewState = 0;
		m_nCursorType = 0;
	}
}

void CZMapView::OnUpdateZoomIn(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(m_nViewState == 1);
}

void CZMapView::OnUpdateZoomOut(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(m_nViewState == 2);
}

void CZMapView::OnPan() 
{
	if(m_nViewState != 3)
	{
		m_nViewState = 3;
		m_nCursorType = 3;
	}
	else
	{
		m_nViewState = 0;
		m_nCursorType = 0;
	}
	
}

void CZMapView::OnUpdatePan(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(m_nViewState == 3);
}

void CZMapView::OnViewEntire() 
{
	theApp.m_dZoomRatio = 1.0;
	theApp.m_ptDtCenter = theApp.m_rc2DtBounds.CenterPoint();
	this->Invalidate();
}

⌨️ 快捷键说明

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