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

📄 demo2view.cpp

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

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

#include "Demo2Doc.h"
#include "Demo2View.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDemo2View

IMPLEMENT_DYNCREATE(CDemo2View, CView)

BEGIN_MESSAGE_MAP(CDemo2View, CView)
	//{{AFX_MSG_MAP(CDemo2View)
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(IDT_ZOOMIN, OnZoomin)
	ON_COMMAND(IDT_ZOOMOUT, OnZoomout)
	ON_COMMAND(IDT_MOVING, OnMoving)
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_UPDATE_COMMAND_UI(ID_MENUITEM_LAYER1, OnUpdateMenuitemLayer1)
	ON_UPDATE_COMMAND_UI(ID_MENUITEM_LAYER2, OnUpdateMenuitemLayer2)
	ON_UPDATE_COMMAND_UI(ID_MENUITEM_LAYER3, OnUpdateMenuitemLayer3)
	ON_UPDATE_COMMAND_UI(ID_MENUITEM_LAYER4, OnUpdateMenuitemLayer4)
	ON_COMMAND(ID_MENUITEM_LAYER1, OnMenuitemLayer1)
	ON_COMMAND(ID_MENUITEM_LAYER2, OnMenuitemLayer2)
	ON_COMMAND(ID_MENUITEM_LAYER3, OnMenuitemLayer3)
	ON_COMMAND(ID_MENUITEM_LAYER4, OnMenuitemLayer4)
	ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
	ON_UPDATE_COMMAND_UI(IDT_MOVING, OnUpdateMoving)
	ON_UPDATE_COMMAND_UI(IDT_ZOOMIN, OnUpdateZoomin)
	ON_UPDATE_COMMAND_UI(IDT_ZOOMOUT, OnUpdateZoomout)
	ON_UPDATE_COMMAND_UI(IDT_ARROW, OnUpdateArrow)
	ON_COMMAND(IDT_ARROW, OnArrow)
	//}}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()

/////////////////////////////////////////////////////////////////////////////
// CDemo2View construction/destruction

CDemo2View::CDemo2View()
{
	// TODO: add construction code here
	m_bMapMoving = false;
	m_nMouseMode = IDT_ARROW;
}

CDemo2View::~CDemo2View()
{
}

BOOL CDemo2View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	//获得自定义光标资源
	m_hcurHand = (HCURSOR)::LoadImage(cs.hInstance,
		MAKEINTRESOURCE(IDC_CURSOR_HAND), IMAGE_CURSOR,
		32, 32, LR_DEFAULTCOLOR);

	m_hcurZoomIn = (HCURSOR)::LoadImage(cs.hInstance,
		MAKEINTRESOURCE(IDC_CURSOR_ZOOMIN), IMAGE_CURSOR,
		32, 32, LR_DEFAULTCOLOR);

	m_hcurZoomOut = (HCURSOR)::LoadImage(cs.hInstance,
		MAKEINTRESOURCE(IDC_CURSOR_ZOOMOUT), IMAGE_CURSOR,
		32, 32, LR_DEFAULTCOLOR);

	//获得光标资源的另一种方法
	m_hcurArrow = AfxGetApp()->LoadCursor(IDC_CURSOR_ARROW);

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CDemo2View drawing

void CDemo2View::OnDraw(CDC* pDC)
{
	CDemo2Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CDC* dc = GetDC();

	dc->BitBlt(0, 0, pDoc->m_nViewWidth, pDoc->m_nVeiwHeight, pDoc->m_pMemDC,
		0, 0, SRCCOPY);

	ReleaseDC(dc);
}

/////////////////////////////////////////////////////////////////////////////
// CDemo2View printing

BOOL CDemo2View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	if( !GetDocument()->m_aLayers.GetSize() )
	{//无打开海图
		return false;
	}

	pInfo->SetMinPage(1);
	pInfo->SetMaxPage(1);//只打印一页

	return DoPreparePrinting(pInfo);
}

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

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

/////////////////////////////////////////////////////////////////////////////
// CDemo2View diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CDemo2View message handlers

void CDemo2View::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	CDC* pDC = GetDC();
	CDemo2Doc* pDoc = GetDocument();
	if(pDoc->m_pMemDC)
	{
		CDC dc;
		dc.CreateCompatibleDC(pDC);//创建兼容DC
		CBitmap *bitmap = new CBitmap;//重新创建BITMAP资源
		bitmap->CreateCompatibleBitmap(pDC, cx, cy);
		CBitmap* map = dc.SelectObject(bitmap);
		dc.BitBlt(0, 0, cx, cy, NULL, 0, 0, WHITENESS);//清空BITMAP
		dc.BitBlt(0, 0, cx, cy, pDoc->m_pMemDC, 0, 0, SRCCOPY);//复制
		dc.SelectObject(map);//恢复DC
		dc.DeleteDC();//删除DC
		pDoc->m_pMemDC->SelectObject(bitmap);//选出原BITMAP
		pDoc->m_pBitmap->DeleteObject();//删除BITMAP资源
		delete pDoc->m_pBitmap;//删除BITMAP对象
		pDoc->m_pBitmap = bitmap;
		if(pDoc->m_nViewWidth<cx || pDoc->m_nVeiwHeight<cy)
		{
			pDoc->m_nViewWidth = cx;
			pDoc->m_nVeiwHeight = cy;
			//重绘位图
			pDoc->DrawMap(pDoc->m_pMemDC);
			Invalidate();
		}
		pDoc->m_nViewWidth = cx;
		pDoc->m_nVeiwHeight = cy;
	}
	else
	{
		pDoc->m_pMemDC = new CDC;
		pDoc->m_pMemDC->CreateCompatibleDC(pDC);//创建CD
		pDoc->m_pBitmap = new CBitmap;
		pDoc->m_pBitmap->CreateCompatibleBitmap(pDC, cx, cy);//创建BITMAP
		pDoc->m_pDefaultBitmap = (CBitmap*)pDoc->m_pMemDC->SelectObject(pDoc->m_pBitmap);
		pDoc->m_pMemDC->BitBlt(0, 0, cx, cy, NULL, 0, 0, WHITENESS);//清空BITMAP
		pDoc->m_nViewWidth = cx;
		pDoc->m_nVeiwHeight = cy;
	}
}

void CDemo2View::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	double jing, wei;
	CDemo2Doc* pDoc = GetDocument();
	if( !pDoc->m_aLayers.GetSize() )
	{//未打开海图
		return;
	}
	CRect client;
	GetClientRect(&client);//获得客户区范围
	ClientToScreen(&client);//转化为屏幕坐标
	::ClipCursor(&client);//锁定鼠标移动范围

	switch(m_nMouseMode)
	{
		case IDT_ZOOMOUT://缩小
			pDoc->DPtoLP(point.x, point.y);
			pDoc->ConvToJW(point.x, point.y, jing, wei);//计算鼠标点经纬度
			pDoc->Zoom(0.625);//缩小海图
			pDoc->ConvToXY(jing, wei, point.x, point.y);//计算缩小后的逻辑坐标
			pDoc->SetCenter(point);
			pDoc->DrawMap(pDoc->m_pMemDC);//重绘海图
			Invalidate(false);//更新显示
			break;
		case IDT_ZOOMIN://放大
			pDoc->DPtoLP(point.x, point.y);
			pDoc->ConvToJW(point.x, point.y, jing, wei);//计算鼠标点经纬度
			pDoc->Zoom(1.6);//放大海图
			pDoc->ConvToXY(jing, wei, point.x, point.y);//计算放大后的逻辑坐标
			pDoc->SetCenter(point);
			pDoc->DrawMap(pDoc->m_pMemDC);//重绘海图
			Invalidate(false);//更新显示
			break;
		case IDT_MOVING://漫游
			m_ptOldPoint = point;
			m_bMapMoving = true;
			break;
		case IDT_ARROW:
			break;
	}
	CView::OnLButtonDown(nFlags, point);
}

void CDemo2View::OnZoomin() 
{
	// TODO: Add your command handler code here
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurZoomIn);
	m_nMouseMode = IDT_ZOOMIN;
}

void CDemo2View::OnZoomout() 
{
	// TODO: Add your command handler code here
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurZoomOut);
	m_nMouseMode = IDT_ZOOMOUT;
}

void CDemo2View::OnMoving() 
{
	// TODO: Add your command handler code here
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurHand);
	m_nMouseMode = IDT_MOVING;
}

void CDemo2View::OnArrow() 
{
	// TODO: Add your command handler code here
	::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)m_hcurArrow);
	m_nMouseMode = IDT_ARROW;
}

void CDemo2View::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	::ClipCursor(NULL);//释放鼠标锁定
	CDemo2Doc* pDoc = GetDocument();
	if( !pDoc->m_aLayers.GetSize() )
	{//未打开海图
		return;
	}
	switch(m_nMouseMode)
	{
		case IDT_MOVING:
			m_bMapMoving = false;
			pDoc->MoveOffset(point - m_ptOldPoint);
			pDoc->DrawMap(pDoc->m_pMemDC);//重绘海图
			Invalidate(false);//更新显示
			break;
	}
	CView::OnLButtonUp(nFlags, point);
}

void CDemo2View::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CDemo2Doc* pDoc = GetDocument();
	CDC* pDC = GetDC();//申请DC

	if(m_bMapMoving)
	{
		CPoint pt = point - m_ptOldPoint;//计算偏移量
		//清空显示区其他区域
		if(pt.x<0)
		{//pt.x<0,图像左移,清空右侧
			pDC->BitBlt(pDoc->m_nViewWidth + pt.x, 0, -pt.x, pDoc->m_nVeiwHeight,
				NULL, 0, 0, WHITENESS);
		}
		else if(pt.x>0)
		{//pt.x>0,图像右移,清空左侧
			pDC->BitBlt(0, 0, pt.x, pDoc->m_nVeiwHeight,
				NULL, 0, 0, WHITENESS);
		}
		if(pt.y<0)
		{//pt.y<0,图像上移,清空下侧
			pDC->BitBlt(0, pDoc->m_nVeiwHeight + pt.y, pDoc->m_nViewWidth, -pt.y,
				NULL, 0, 0, WHITENESS);
		}
		else if(pt.y>0)
		{//pt.y>0,图像下移,清空上侧
			pDC->BitBlt(0, 0, pDoc->m_nViewWidth, pt.y,
				NULL, 0, 0, WHITENESS);
		}
		pDC->BitBlt(pt.x, pt.y, pDoc->m_nViewWidth, pDoc->m_nVeiwHeight,
			pDoc->m_pMemDC, 0, 0, SRCCOPY);//复制图像(BITMAP)
	}
	else
	{
		pDoc->DisplayLocationOnStatusBar(point);
	}
	ReleaseDC(pDC);//释放DC资源

	CView::OnMouseMove(nFlags, point);
}

void CDemo2View::OnUpdateMenuitemLayer1(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(!pDoc->m_aLayers.GetSize())
		pCmdUI->Enable(false);
	else
	{
		pCmdUI->Enable();
		pCmdUI->SetCheck(pDoc->m_aLayers.GetAt(0)->m_bCanDraw);
	}
}

void CDemo2View::OnUpdateMenuitemLayer2(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(pDoc->m_aLayers.GetSize())
	{
		pCmdUI->Enable();
		pCmdUI->SetCheck(pDoc->m_aLayers.GetAt(1)->m_bCanDraw);
	}
}

void CDemo2View::OnUpdateMenuitemLayer3(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(pDoc->m_aLayers.GetSize())
	{
		pCmdUI->Enable();
		pCmdUI->SetCheck(pDoc->m_aLayers.GetAt(2)->m_bCanDraw);
	}
}

void CDemo2View::OnUpdateMenuitemLayer4(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(pDoc->m_aLayers.GetSize())
	{
		pCmdUI->Enable();
		pCmdUI->SetCheck(pDoc->m_aLayers.GetAt(3)->m_bCanDraw);
	}
}

void CDemo2View::OnMenuitemLayer1() 
{
	// TODO: Add your command handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(pDoc->m_aLayers.GetSize())
	{
		pDoc->m_aLayers.GetAt(0)->m_bCanDraw ^= true;
		pDoc->DrawMap(pDoc->m_pMemDC);
		Invalidate(false);
	}
}

void CDemo2View::OnMenuitemLayer2() 
{
	// TODO: Add your command handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(pDoc->m_aLayers.GetSize())
	{
		pDoc->m_aLayers.GetAt(1)->m_bCanDraw ^= true;
		pDoc->DrawMap(pDoc->m_pMemDC);
		Invalidate(false);
	}
}

void CDemo2View::OnMenuitemLayer3() 
{
	// TODO: Add your command handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(pDoc->m_aLayers.GetSize())
	{
		pDoc->m_aLayers.GetAt(2)->m_bCanDraw ^= true;
		pDoc->DrawMap(pDoc->m_pMemDC);
		Invalidate(false);
	}
}

void CDemo2View::OnMenuitemLayer4() 
{
	// TODO: Add your command handler code here
	CDemo2Doc* pDoc = GetDocument();

	if(pDoc->m_aLayers.GetSize())
	{
		pDoc->m_aLayers.GetAt(3)->m_bCanDraw ^= true;
		pDoc->DrawMap(pDoc->m_pMemDC);
		Invalidate(false);
	}
}

void CDemo2View::OnFileClose() 
{
	// TODO: Add your command handler code here
	CDemo2Doc* pDoc = GetDocument();

	pDoc->InitData();//初始化用户数据
	pDoc->SetLayerMenu(false);//清“图层”菜单
	pDoc->DrawMap(pDoc->m_pMemDC);//刷新海图
	Invalidate(false);//更新显示
	pDoc->OnNewDocument();//关闭“文档”。必须关闭,否则下次无法打开同一个文档
}

void CDemo2View::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class
	double maxx, maxy;
	long offsetx, offsety;
	long vwidth, vheight;
	CDemo2Doc* pDoc = GetDocument();
	//保存海图原设置
	maxx = pDoc->m_fMaxCX;
	maxy = pDoc->m_fMaxCY;
	offsetx = pDoc->m_nOffsetX;
	offsety = pDoc->m_nOffsetY;
	vwidth = pDoc->m_nViewWidth;
	vheight = pDoc->m_nVeiwHeight;
	//设置海图打印范围
	pDoc->m_nOffsetX = pInfo->m_rectDraw.left;//设置海图偏移
	pDoc->m_nOffsetY = pInfo->m_rectDraw.top;
	pDoc->m_nViewWidth = pInfo->m_rectDraw.right;//设置海图刷新范围
	pDoc->m_nVeiwHeight = pInfo->m_rectDraw.bottom;
	long mx = pInfo->m_rectDraw.Width();
	long my = pInfo->m_rectDraw.Height();
	float axy = maxx / maxy;
	if(my * axy < mx)
	{//打印纸过宽
		pDoc->m_fMaxCX = my*axy;
		pDoc->m_fMaxCY = my;
		pDoc->m_nOffsetX += (pInfo->m_rectDraw.right - pInfo->m_rectDraw.left - pDoc->m_fMaxCX)/2;
			//设置海图打印偏移量,在纸中间打印海图
	}
	else
	{//打印纸过长
		pDoc->m_fMaxCX = mx;
		pDoc->m_fMaxCY = mx/axy;
		pDoc->m_nOffsetY += (pInfo->m_rectDraw.bottom - pInfo->m_rectDraw.top - pDoc->m_fMaxCY)/2;
			//设置海图打印偏移量,在纸中间打印海图
	}
	
	//打印海图
	pDoc->DrawMap(pDC);
	
	//恢复海图设置
	pDoc->m_nOffsetX = offsetx;
	pDoc->m_nOffsetY = offsety;
	pDoc->m_fMaxCX = maxx;
	pDoc->m_fMaxCY = maxy;
	pDoc->m_nViewWidth = vwidth;
	pDoc->m_nVeiwHeight = vheight;
	//CView::OnPrint(pDC, pInfo);
}

void CDemo2View::OnUpdateMoving(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_MOVING);//保持按钮按下状态
}

void CDemo2View::OnUpdateZoomin(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_ZOOMIN);//保持按钮按下状态
}

void CDemo2View::OnUpdateZoomout(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_ZOOMOUT);//保持按钮按下状态
}

void CDemo2View::OnUpdateArrow(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_nMouseMode == IDT_ARROW);//保持按钮按下状态
}

⌨️ 快捷键说明

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