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

📄 ex_studentview.cpp

📁 郑阿奇主编< Visual C++教程> 配套的实验书的全部代码
💻 CPP
字号:
// Ex_StudentView.cpp : implementation of the CEx_StudentView class
//

#include "stdafx.h"
#include "Ex_Student.h"

#include "Ex_StudentDoc.h"
#include "Ex_StudentView.h"

#include "StuInfoDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CEx_StudentView

IMPLEMENT_DYNCREATE(CEx_StudentView, CListView)

BEGIN_MESSAGE_MAP(CEx_StudentView, CListView)
	//{{AFX_MSG_MAP(CEx_StudentView)
	ON_COMMAND(ID_STUINFO_ADD, OnStuinfoAdd)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEx_StudentView construction/destruction

CEx_StudentView::CEx_StudentView()
{
	// TODO: add construction code here
	memset(&m_pageInfo, 0, sizeof(m_pageInfo));		// 所有成员置为0
	double fontScale = 254.0/72.0;	// 一个点相当于多少0.1mm
	// 页眉字体
	m_pageInfo.lfHead.lfHeight = - (int)(9 * fontScale + 0.5);		// 9号字
	m_pageInfo.lfHead.lfWeight = FW_BOLD;
	m_pageInfo.lfHead.lfCharSet = GB2312_CHARSET;
	strcpy((LPSTR)&(m_pageInfo.lfHead.lfFaceName), "黑体");
	// 页脚字体
	m_pageInfo.lfFoot.lfHeight = - (int)(9 * fontScale + 0.5);		// 9号字
	m_pageInfo.lfFoot.lfWeight = FW_NORMAL;
	m_pageInfo.lfFoot.lfCharSet = GB2312_CHARSET;
	strcpy((LPSTR)&(m_pageInfo.lfFoot.lfFaceName), "楷体_GB2312");
	// 正文字体
	m_pageInfo.lfText.lfHeight = - (int)(11 * fontScale + 0.5);		// 11号字
	m_pageInfo.lfText.lfWeight = FW_NORMAL;
	m_pageInfo.lfText.lfCharSet = GB2312_CHARSET;
	strcpy((LPSTR)&(m_pageInfo.lfText.lfFaceName), "宋体");

}

CEx_StudentView::~CEx_StudentView()
{
}

BOOL CEx_StudentView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	cs.style |= LVS_REPORT;		// 报表风格
	return CListView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CEx_StudentView drawing

void CEx_StudentView::OnDraw(CDC* pDC)
{
	CEx_StudentDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

void CEx_StudentView::OnInitialUpdate()
{
	CListView::OnInitialUpdate();


	// TODO: You may populate your ListView with items by directly accessing
	//  its list control through a call to GetListCtrl().
	CListCtrl& m_ListCtrl = GetListCtrl();
	CString strHeader[]={"学号","姓名", "性别", "出生年月", "所学专业"};
	int nLong[] = {80, 80, 60, 100, 180};
	for (int nCol=0; nCol<sizeof(strHeader)/sizeof(CString); nCol++)
		m_ListCtrl.InsertColumn(nCol,strHeader[nCol],LVCFMT_LEFT,nLong[nCol]);
}

/////////////////////////////////////////////////////////////////////////////
// CEx_StudentView printing

BOOL CEx_StudentView::OnPreparePrinting(CPrintInfo* pInfo)
{
	ReadListViewData();
	int nSize =m_strContents.GetSize();
	if (nSize<1) pInfo->SetMaxPage(1);
	return DoPreparePrinting(pInfo);
}

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

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

/////////////////////////////////////////////////////////////////////////////
// CEx_StudentView diagnostics

#ifdef _DEBUG
void CEx_StudentView::AssertValid() const
{
	CListView::AssertValid();
}

void CEx_StudentView::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}

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

/////////////////////////////////////////////////////////////////////////////
// CEx_StudentView message handlers

void CEx_StudentView::OnStuinfoAdd() 
{
	CStuInfoDlg dlg;
	if (dlg.DoModal() != IDOK) return;
	// 在这里复制照片文件
	CString strFileTO;
	strFileTO.Format("c://%s.bmp", dlg.m_strNo);
	if (!dlg.m_strPhotoFilePath.IsEmpty())
		DoCopyFile(strFileTO, dlg.m_strPhotoFilePath);
	// 添加列表项
	CListCtrl& m_ListCtrl = GetListCtrl();
	int nItem = m_ListCtrl.GetItemCount();
	CString strSex("女");
	if (dlg.m_bMale) strSex = "男";
	m_ListCtrl.InsertItem( nItem, dlg.m_strNo );
	m_ListCtrl.SetItemText( nItem, 1, dlg.m_strName );
	m_ListCtrl.SetItemText( nItem, 2, strSex );
	m_ListCtrl.SetItemText( nItem, 3, dlg.m_tBirth.Format("%Y-%m-%d") );
	m_ListCtrl.SetItemText( nItem, 4, dlg.m_strSpecial);	
}

void CEx_StudentView::DoCopyFile(CString strFileTo, CString strFileFrom)
{
	CFile fileFrom, fileTo;

	if (!fileFrom.Open( strFileFrom, CFile::modeRead))
	{
		AfxMessageBox("源文件无法打开,复制失败!");
		return;
	}
	fileTo.Open( strFileTo, CFile::modeCreate | CFile::modeWrite );
	
	BYTE buffer[4096];
    DWORD dwRead;
    do{
         dwRead = fileFrom.Read(buffer, 4096);
         fileTo.Write(buffer, dwRead);
    } while (dwRead > 0);

	fileFrom.Close();
	fileTo.Close();
}

void CEx_StudentView::ReadListViewData()
{
	m_strContents.RemoveAll();
	CListCtrl& m_ListCtrl = GetListCtrl();
	int nCount = 0;
	CHeaderCtrl* pHeaderCtrl = m_ListCtrl.GetHeaderCtrl();
	if ( pHeaderCtrl!= NULL)	nCount = pHeaderCtrl->GetItemCount();
	// 读取表头信息作为第一行
	LVCOLUMN	column;
	TCHAR		lpBuffer[256];
	int			nWidthCharNum[100];
	CString str, strTemp;
	for (int nCol = 0; nCol < nCount; nCol++)	{
		column.mask		= LVCF_TEXT; 
		column.pszText		= lpBuffer;
		column.cchTextMax	= 256;
		m_ListCtrl.GetColumn( nCol, &column );
		nWidthCharNum[nCol] = (int)(m_ListCtrl.GetColumnWidth( nCol )/6.5);
		strTemp.Format("%s", lpBuffer);
		strTemp.TrimRight();
		int nDelta = nWidthCharNum[nCol] - strTemp.GetLength();
		if (nDelta>0)	strTemp = AppendStringSpace( strTemp, nDelta);
		else	strTemp = strTemp.Left(nWidthCharNum[nCol]);
		str = str + strTemp;
	}
	str.TrimRight();
	m_strContents.Add( str );
	// 读取各个列表项信息
	int nItemCount = m_ListCtrl.GetItemCount();
	for ( int nItem=0; nItem<nItemCount; nItem++)	{
		str.Empty();
		strTemp.Empty();
		for (int i=0; i<nCount; i++ )	{
			strTemp = m_ListCtrl.GetItemText(nItem, i);
			strTemp.TrimRight();
			int nDelta = nWidthCharNum[i] - strTemp.GetLength();
			if (nDelta>0)	strTemp = AppendStringSpace( strTemp, nDelta);
			else	strTemp = strTemp.Left(nWidthCharNum[i]);
			str = str + strTemp;
		}
		str.TrimRight();
		m_strContents.Add( str );
	}

}

CString CEx_StudentView::AppendStringSpace(CString str, int nNum)
{
	for (int i=0; i<nNum; i++)
		str.Insert( 500, ' ');		
	// 通常500是大于一个字符串长度的,当大于字符串长度,则
	// Insert在字符串末尾添加
	return str;
}

void CEx_StudentView::SetPageInfo(CDC *pDC, CPrintInfo *pInfo, PAGEINFO *pPage, int l, int t, int r, int b, int nLineSpace)
{
	// nLineSpace为行间距,l,t,r,b分别表示左上右下的页边距
	// 计算一个设备单位等于多少0.1mm
	double scaleX = 254.0/(double)GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSX);
	double scaleY = 254.0/(double)GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSY);

	int x = GetDeviceCaps(pDC->m_hAttribDC, PHYSICALOFFSETX);	
	int y = GetDeviceCaps(pDC->m_hAttribDC, PHYSICALOFFSETY);	
	int w = GetDeviceCaps(pDC->m_hAttribDC, PHYSICALWIDTH);	
	int h = GetDeviceCaps(pDC->m_hAttribDC, PHYSICALHEIGHT);	

	int nPageWidth = (int)((double)w*scaleX + 0.5);		// 纸宽,单位0.1mm 
	int nPageHeight = (int)((double)h*scaleY + 0.5);		// 纸高,单位0.1mm 

	int nPhyLeft = (int)((double)x*scaleX + 0.5);			// 物理左边距,单位0.1mm 
	int nPhyTop = (int)((double)y*scaleY + 0.5);			// 物理上边距,单位0.1mm 

	CRect rcTemp = pInfo->m_rectDraw;
	rcTemp.NormalizeRect();

	int nPhyRight = nPageWidth - rcTemp.Width() - nPhyLeft;	// 物理右边距,单位0.1mm
	int nPhyBottom = nPageHeight - rcTemp.Height() - nPhyTop;	// 物理下边距,单位0.1mm

	// 若边距小于物理边距,则调整它们
	if (l < nPhyLeft) l = nPhyLeft;
	if (t < nPhyTop) t = nPhyTop;
	if (r < nPhyRight) r = nPhyRight;
	if (b < nPhyBottom) b = nPhyBottom;

	pPage->nLMargin = l;
	pPage->nRMargin = r;
	pPage->nTMargin = t;
	pPage->nBMargin = b;
	pPage->nPhyLeft = nPhyLeft;
	pPage->nPhyRight = nPhyRight;
	pPage->nPhyTop = nPhyTop;
	pPage->nPhyBottom = nPhyBottom;

	pPage->sizePage = CSize(nPageWidth, nPageHeight);

	// 计算并调整pInfo->m_rectDraw的大小
	pInfo->m_rectDraw.left = l - nPhyLeft;
	pInfo->m_rectDraw.top  = - t + nPhyTop;
	pInfo->m_rectDraw.right -= r - nPhyRight;
	pInfo->m_rectDraw.bottom += b - nPhyBottom;

	// 计算字符的大小
	pPage->sizeChar = pDC->GetTextExtent("G");
	// 计算行的大小
	pPage->sizeLine = CSize(pInfo->m_rectDraw.Width(), pPage->sizeChar.cy + nLineSpace);
}

void CEx_StudentView::PrintHead(CDC *pDC, CPrintInfo *pInfo, PAGEINFO page, CString title, int margin, int mode)
{
	// mode表示页眉文本对齐模式,0为居中,>0表示右对齐,<0表示左对齐
	// title表示页眉内容, margin为页眉与顶边的距离
	CFont font;
	font.CreateFontIndirect(&page.lfHead);
	CFont* oldFont = pDC->SelectObject(&font);

	CSize strSize = pDC->GetTextExtent(title);
	CRect rc = pInfo->m_rectDraw;
	CPoint pt;

	margin = margin - page.nPhyTop;
	if (margin<0) margin = 0;

	// 根据mode计算绘制页眉文本的起点
	if (mode < 0) pt = CPoint(rc.left, -margin);
	if (mode == 0) pt = CPoint(rc.CenterPoint().x - strSize.cx/2, -margin);
	if (mode > 0) pt = CPoint(rc.right - strSize.cx, -margin);

	pDC->TextOut(pt.x, pt.y, title);	// 绘制页眉文本
	pt.y -= strSize.cy + 5;
	pDC->MoveTo(rc.left, pt.y);		// 画线
	pDC->LineTo(rc.right, pt.y);
	pt.y -= 10;
	int absY = pt.y>0 ? pt.y : -pt.y;
	
	if (absY > page.nTMargin) pInfo->m_rectDraw.top = pt.y; 

	pDC->SelectObject(oldFont);
	font.DeleteObject();
}

void CEx_StudentView::PrintFoot(CDC *pDC, CPrintInfo *pInfo, PAGEINFO page, CString title, int margin, int mode)
{
	// mode表示页脚文本对齐模式,0为居中,>0表示右对齐,<0表示左对齐
	// title表示页脚内容, margin为页脚与底边的距离
	CFont font;
	font.CreateFontIndirect(&page.lfFoot);
	CFont* oldFont = pDC->SelectObject(&font);

	CSize strSize = pDC->GetTextExtent(title);
	CRect rc = pInfo->m_rectDraw;
	CPoint pt;

	margin = page.nBMargin - margin - strSize.cy;

	// 根据mode计算绘制页眉文本的起点
	if (mode < 0) pt = CPoint(rc.left, rc.bottom - margin);
	if (mode == 0) pt = CPoint(rc.CenterPoint().x - strSize.cx/2,  rc.bottom - margin);
	if (mode > 0) pt = CPoint(rc.right - strSize.cx,  rc.bottom - margin);

	pDC->TextOut(pt.x, pt.y, title);	// 绘制页脚文本

	if (margin < 0) 
		pInfo->m_rectDraw.bottom -= margin;

	pDC->SelectObject(oldFont);
}

void CEx_StudentView::AdjustAllLine(CDC *pDC)
{
	int nLineNums =  m_strContents.GetSize();		// 文档总行数

	int tab = m_pageInfo.sizeChar.cx * 4;			// 为一个TAB设置4个字符

	// 将文档的每一行作换行处理,只处理一次,以提高预览速度
	// 处理的结果保存在arrText中
	CString str;
	m_arrText.RemoveAll();
	CSize strSize;
	for (int i=0; i<nLineNums; i++) 
	{
		str = m_strContents.GetAt(i);
		strSize = pDC->GetTabbedTextExtent(str, 1, &tab);
		CString strTemp = str;
		while ( strSize.cx > m_pageInfo.sizeLine.cx) {

			unsigned int pos = 0;
			for (pos = 0; pos<strlen(strTemp); pos++) {
				CSize size = pDC->GetTabbedTextExtent(strTemp, pos+1, 1, &tab);
				if (size.cx >= m_pageInfo.sizeLine.cx) break;
			}

			// 判断汉字双字符是否被分开
			int nCharHZ = 0;
			for (unsigned int chIndex = 0; chIndex <= pos; chIndex++)
				if (strTemp.GetAt(chIndex) < 0) nCharHZ++;
			if (nCharHZ % 2) pos = pos - 1;

			m_arrText.Add(strTemp.Left(pos+1));
			strTemp = strTemp.Mid(pos+1);
			strSize = pDC->GetTabbedTextExtent(strTemp, 1, &tab);
		}
		m_arrText.Add(strTemp);
	}
	m_nLineArray.RemoveAll();
	m_nLineArray.Add(0);	
}

void CEx_StudentView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	ReadListViewData();
	pDC->SetMapMode(MM_LOMETRIC);	// 单位0.1mm
	CListView::OnPrepareDC(pDC, pInfo);
	int nSize = m_strContents.GetSize();
	if ((pInfo)&&(nSize)){
		if (pInfo->m_nCurPage<= pInfo->GetToPage()) 
			pInfo-> m_bContinuePrinting = TRUE;
		else 
			pInfo-> m_bContinuePrinting = FALSE;
	} 
}

void CEx_StudentView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	CFont font;
	font.CreateFontIndirect(&m_pageInfo.lfText);
	CFont* oldFont = pDC->SelectObject(&font);		// 设置正文字体
	SetPageInfo(pDC, pInfo, &m_pageInfo, 250, 250, 250, 250, 35);	// 设置页边距和行距
	PrintHead(pDC, pInfo, m_pageInfo, "学生信息管理系统,设计者:丁有和", 200, -1);	// 打印页眉
	CString str;
	str.Format("- %d -", pInfo->m_nCurPage);
	PrintFoot(pDC, pInfo, m_pageInfo, str, 200, 0);	// 打印页脚

	if (m_strContents.GetSize() < 1)	return;		// 没有文档内容则返回

	AdjustAllLine(pDC);	// 调整每行的文本

	int nIndex = pInfo->m_nCurPage - 1;
	int nStartLine = m_nLineArray.GetAt(nIndex);

	CRect rc = pInfo->m_rectDraw;
	int y = rc.top;
	int nHeight = m_pageInfo.sizeLine.cy;
	int tab = m_pageInfo.sizeChar.cx * 4;				// 为一个TAB设置4个字符
	while (y >= pInfo->m_rectDraw.bottom) 
	{
		str =  m_arrText.GetAt(nStartLine);
		rc.top = y;
		pDC->TabbedTextOut(rc.left, y, str, 1, &tab, rc.left);  

		nStartLine++;
		if (nStartLine >= m_arrText.GetSize()) 
		{
			pInfo->SetMaxPage(pInfo->m_nCurPage);
			pInfo->m_pPD->m_pd.nToPage = pInfo->m_nCurPage;
			break;
		}

		y -= nHeight;
	}

	if (nIndex >= (m_nLineArray.GetSize() - 1)) 
		m_nLineArray.Add(nStartLine);	// 保存下一页的起始行号
	pDC->SelectObject(oldFont);	
	CListView::OnPrint(pDC, pInfo);
}

⌨️ 快捷键说明

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