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

📄 fileserializeview.cpp

📁 深入学习VC++得很难得的一本好书 里面配有大量的源代码 并有详细的解释
💻 CPP
字号:
// FileSerializeView.cpp : implementation of the CFileSerializeView class
//

#include "stdafx.h"
#include "FileSerialize.h"

#include "FileSerializeDoc.h"
#include "FileSerializeView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CFileSerializeView

IMPLEMENT_DYNCREATE(CFileSerializeView, CScrollView)

BEGIN_MESSAGE_MAP(CFileSerializeView, CScrollView)
	//{{AFX_MSG_MAP(CFileSerializeView)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	//}}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()

/////////////////////////////////////////////////////////////////////////////
// CFileSerializeView construction/destruction

CFileSerializeView::CFileSerializeView()
{
}

CFileSerializeView::~CFileSerializeView()
{
}

BOOL CFileSerializeView::PreCreateWindow(CREATESTRUCT& cs)
{
	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CFileSerializeView drawing

void CFileSerializeView::OnDraw(CDC* pDC)
{
	CFileSerializeDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc);

	// 得到视图的无效矩形
	CRect rectClip;
	CRect rectStroke;
	pDC->GetClipBox(&rectClip);
	pDC->LPtoDP(&rectClip);
	rectClip.InflateRect(1, 1); 


	CTypedPtrList<CObList,CStroke*>& strokeList = pDoc->m_strokeList;
	POSITION pos = strokeList.GetHeadPosition();
	while (pos != NULL)
	{
		CStroke* pStroke = strokeList.GetNext(pos);
		rectStroke = pStroke->GetBoundingRect();
		pDC->LPtoDP(&rectStroke);
		rectStroke.InflateRect(1, 1); 
		
		// 判断两矩形的交际是否为空
		if (!rectStroke.IntersectRect(&rectStroke, &rectClip))
			continue;
		pStroke->DrawStroke(pDC);  //画线
	}
}

/////////////////////////////////////////////////////////////////////////////
// CFileSerializeView printing

BOOL CFileSerializeView::OnPreparePrinting(CPrintInfo* pInfo)
{
	pInfo->SetMaxPage(2);   // 文档最大页码2
	BOOL bRet = DoPreparePrinting(pInfo);   //默认打印准备
	pInfo->m_nNumPreviewPages = 2;  // 一次性预览2页

	return bRet;
}

void CFileSerializeView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
}

void CFileSerializeView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
}

/////////////////////////////////////////////////////////////////////////////
// CFileSerializeView diagnostics

#ifdef _DEBUG
void CFileSerializeView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CFileSerializeView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CFileSerializeDoc* CFileSerializeView::GetDocument() 
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFileSerializeDoc)));
	return (CFileSerializeDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CFileSerializeView message handlers

void CFileSerializeView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CClientDC dc(this);
	OnPrepareDC(&dc);   
	dc.DPtoLP(&point);

	// m_pStrokeCur是线条指针,其定义如下:
	// CStroke*    m_pStrokeCur;
	m_pStrokeCur = GetDocument()->NewStroke();	

	// 将第一个点加入新线条的m_pointArray
	m_pStrokeCur->m_pointArray.Add(point);

	SetCapture();       // 俘获鼠标,直到左键松开
	m_ptPrev = point;   // 作为MoveTo()的基点

	return;
}

void CFileSerializeView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (GetCapture() != this)
		return; 
	CFileSerializeDoc* pDoc = GetDocument();
	CClientDC dc(this);

    // OnPrepareDC经常在CScrollView中用来调整设备表信息
	OnPrepareDC(&dc);  
	dc.DPtoLP(&point);

	// 选进新笔,保存旧笔
	CPen* pOldPen = dc.SelectObject(pDoc->GetCurrentPen());
	dc.MoveTo(m_ptPrev);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);// 恢复旧笔
	m_pStrokeCur->m_pointArray.Add(point);

	// 乘此机会算出最小矩形
	m_pStrokeCur->FinishStroke();

	// 告诉其他视图我们已经加入了新的“线条”
	// 以便我们更新最小矩形指定的区域
	pDoc->UpdateAllViews(this, 0L, m_pStrokeCur);

	ReleaseCapture();   //释放鼠标
	return;
}

void CFileSerializeView::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (GetCapture() != this)
		return; //如果该视图没有俘获鼠标,那么不在该区域绘制

	CClientDC dc(this);
	OnPrepareDC(&dc);
	dc.DPtoLP(&point);
	m_pStrokeCur->m_pointArray.Add(point);
	CPen* pOldPen = dc.SelectObject(GetDocument()->GetCurrentPen());
	dc.MoveTo(m_ptPrev);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	m_ptPrev = point;

	return;
}

void CFileSerializeView::OnInitialUpdate() 
{
	SetScrollSizes(MM_LOENGLISH, GetDocument()->GetDocSize());
	CScrollView::OnInitialUpdate();
}

void CFileSerializeView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	// 文档通知该视图一部分数据已经改变
	if (pHint != NULL)
	{
		if (pHint->IsKindOf(RUNTIME_CLASS(CStroke)))
		{
			// 提示增加了一个线条或者被修改了
			// 所以我们必须更新该线条所在的矩形区域
			CStroke* pStroke = (CStroke*)pHint;
			CClientDC dc(this);
			OnPrepareDC(&dc);
			CRect rectInvalid = pStroke->GetBoundingRect(); //得到最小矩形
			dc.LPtoDP(&rectInvalid); //转换为设备坐标
			InvalidateRect(&rectInvalid); //更新之
			return;
		}
	}

	Invalidate(TRUE);
	return;
}

void CFileSerializeView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	if (pInfo->m_nCurPage == 1)  
	{
		PrintTitlePage(pDC, pInfo);
		return; //只打印标题
	}
	CString strHeader = GetDocument()->GetTitle();

	PrintPageHeader(pDC, pInfo, strHeader);

	pDC->SetWindowOrg(pInfo->m_rectDraw.left,-pInfo->m_rectDraw.top);

	// 现在打印剩下的页面
	OnDraw(pDC);
}

void CFileSerializeView::PrintTitlePage(CDC* pDC, CPrintInfo* pInfo)
{
	// 准备一个适当大小的字体来显示文件名字
	LOGFONT logFont;
	memset(&logFont, 0, sizeof(LOGFONT));
	logFont.lfHeight = 75;  //MM_LOENGLISH映射模式下有3/4 英寸高

	CFont font;
	CFont* pOldFont = NULL;
	if (font.CreateFontIndirect(&logFont))
	{
		pOldFont = pDC->SelectObject(&font);
	}

	// 得到文件名字,显示在标题页
	CString strPageTitle = GetDocument()->GetTitle();

    //将文件名字水平居中的显示在距离页面上端1英寸的位置
	pDC->SetTextAlign(TA_CENTER);
	pDC->TextOut(pInfo->m_rectDraw.right/2, -100, strPageTitle);

	if (pOldFont != NULL)
	{
		pDC->SelectObject(pOldFont);
	}
}

void CFileSerializeView::PrintPageHeader(CDC* pDC, CPrintInfo* pInfo,
	CString& strHeader)
{
	// 打印带水平线的文档名字
	pDC->SetTextAlign(TA_LEFT);
	pDC->TextOut(0,-25, strHeader);  // 1/4 inch down

	// 在文档头的下面画一条直线横穿页面
	TEXTMETRIC textMetric;
	pDC->GetTextMetrics(&textMetric);
	int y = -35 - textMetric.tmHeight; // 横线在距离文本下方1/10 英寸处
	pDC->MoveTo(0, y);    // 从左边空白处
	pDC->LineTo(pInfo->m_rectDraw.right, y);   // 到右边空白处

	y -= 25;    
	pInfo->m_rectDraw.top += y;
}

⌨️ 快捷键说明

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