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

📄 vc5 打 印 字 体 的 控 制 .htm

📁 VC的一些技巧性文档
💻 HTM
字号:
<html><body background="di2001.jpg"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><style type="text/css"><!--.10V {font-size: 9pt; font-family: 宋体;text-decoration:none;color="0000ff";}.12V {font-size: 12pt; font-family: 宋体;}--></style><title>VC5打印字体的控制 </title></head><body bgcolor="#FFFFFF"><font color="#0000ff"><h2 align="center">VC5 打 印 字 体 的 控 制 </font></h2><div align="center"><center><table border="0" cellspacing="0" cellpadding="0" width="80%">  <tr>    <td valign="top" width="80%"><font size="4">作者:华光科技股份有限公司开发中心     高洲平</font> <font color="#0000ff"></font><p><font color="#ffffff">----</font> VC5.0     为Windows 的 程 序 员 提 供 了 一 个 很 好 的C++ 开 发 环 境, 减 少     了 很 多 编 程 负 担, 但 同 时 也 为 我 们 在 程 序 中 加 入 自 己     的 思 想 增 加 了 难 度。 本 人 在 一 软 件 开 发 中, 想 控 制 文     字 打 印 时 的 字 体, 使 字 体 大 小 缩 小 一 倍, 以 节 省 打 印     纸。 经 过 一 段 时 间 的 摸 索, 终 于 解 决 了 这 一 问 题, 下     面 分 几 步 向 大 家 做 一 介 绍。 <font color="#a30004"></p>    <h3>一、 对VC5 自 动 生 成 的 程 序 框 架 进 行 改 进 </font><font    color="#ffffff">----</font> 这 里 用VC5 自 动 创 建 一 个 例 子 程 序Test,     单 文 档 界 面, 注 意 在 最 后 一 步 修 改view 的 继 承 类 为CEditView。     </h3>    <p><font color="#ffffff">----</font> 在view 类 中,VC5 已 经 自 动 创 建 了 三     个 用 于 支 持 打 印 的 函 数:OnPreparePrinting,OnBeginPrinting,OnEndPrinting。     为 了 实 现 我 们 的 功 能, 需 要 再 继 承 以 下 几 个 函 数:OnPrepareDC,OnPrint。     并 将OnPrepareDC 和OnEndPrinting 改 为 如 下 实 现: </p>    <pre>// OnPrepareDC()void CTestView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) {	CView::OnPrepareDC(pDC, pInfo);}// OnEndPrinting()void CTestView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) {	CView::OnEndPrinting(pDC, pInfo);}</pre>    <p><font color="#ffffff">----</font> 用CView 来 替 代 原 来 的CEditView, 用 以     避 免CEidtView 对 打 印 的 控 制。 控 制 字 体 及 输 出 的 功 能 主     要 在OnBeginPrinting 和OnPrint 两 个 函 数 来 实 现。 <font color="#a30004"></p>    <h3>二、 实 现OnBeginPrinting 函 数 </font><font color="#ffffff">----</font> 根 据VC5     编 程 机 制, 在OnBeginPrinting 函 数 实 现 打 印 前 的 准 备 工 作,     包 括 设 置 打 印 字 体, 根 据 打 印 机 当 前 页 面 尺 寸 计 算 所     需 页 数 等。 下 面 的 程 序 是 对 打 印 字 体 的 重 新 设 置 和 计     算 所 需 打 印 纸 页 数。 </h3>    <p><font color="#ffffff">----</font> 程 序 中 首 先 取 得 打 印 机 的 横 向     和 纵 向 分 辨 率, 再 得 到 当 前 打 印 字 体 的 大 小, 然 后 计     算 出 新 的 字 体 大 小, 为 默 认 字 体 的 一 半。 读 者 可 以 根     据 需 要 设 定 自 己 的 打 印 字 体 大 小。 </p>    <p><font color="#ffffff">----</font> 接 着, 取 得 当 前 打 印 纸 的 宽 度     和 高 度, 再 根 据 新 字 体 的 宽 度 和 高 度 计 算 出 每 行 的 最     大 字 符 数 和 每 页 的 最 大 行 数。 </p>    <p><font color="#ffffff">----</font> 由 于 打 印 文 件 中 有 些 行 的 宽 度     可 能 超 过 每 行 的 最 大 字 符 数, 所 以 程 序 中 调 用 函 数RedealTextData()     对 打 印 文 件 进 行 重 新 整 理, 函 数 的 实 现 在 下 面 介 绍。 </p>    <p><font color="#ffffff">----</font> 最 后, 程 序 中 计 算 并 设 置 所 需     的 打 印 页 数。 </p>    <p><font color="#ffffff">----</font> OnBeginPrinting() 函 数 实 现 如 下: </p>    <pre>//====================================// OnBeginPrinting//====================================void CTestView::OnBeginPrinting(CDC* pDC, 		CPrintInfo* pInfo) {	//设置新的缩小字体 ////////////////		//取打印机的横方向和纵方向的分辨率	//即每英寸点数	short cxInch = pDC-&gt;GetDeviceCaps(LOGPIXELSX);	short cyInch = pDC-&gt;GetDeviceCaps(LOGPIXELSY);	// 取当前字体大小	CFont	*curFont = pDC-&gt;GetCurrentFont();	LOGFONT	curLogFont;	LOGFONT	newLogFont;	curFont-&gt;GetLogFont( &amp;curLogFont );	long NewFontWidth = curLogFont.lfWidth;	long NewFontHeight = curLogFont.lfHeight;	newLogFont = curLogFont;	//计算新的字体大小 --缩小一倍	newLogFont.lfWidth =(long)((float)NewFontWidth/2.0				 * ((float)cxInch / 72.0));	newLogFont.lfHeight =(long)((float)NewFontHeight/2.0				 * ((float)cyInch / 72.0)); 		//创建并设置新的字体,保留以前的字体	CFont	newFont;	CFont *oldFont;	newFont.CreateFontIndirect(&amp;newLogFont);	oldFont = pDC-&gt;SelectObject(&amp;newFont );	/////////////////////////////////	//根据字体宽度、高度计算	//每行最大字数及每页最大行数	//取打印纸张高度和宽度	int nPageHeight, nPageWidth;	nPageHeight = pDC-&gt;GetDeviceCaps(VERTRES);	nPageWidth = pDC-&gt;GetDeviceCaps(HORZRES);	TEXTMETRIC TextM;	pDC-&gt;GetTextMetrics(&amp;TextM);	//字体高度	m_LineHeight = (unsigned short)TextM.tmHeight; 	//字体平均宽度	m_CharWidth=(unsigned short) 				TextM.tmAveCharWidth; 	//每行最大字数	m_MaxLineChar = nPageWidth / m_CharWidth - 8; 	//每页最大行数	m_LinesPerPage = nPageHeight/ m_LineHeight; 	//根据每行最大字数对文字进行重新调整	RedealTextData(); 	//////////////////////////////////////	//计算所需打印纸张数目	int nPrintableLineCount = INT_MAX/m_LineHeight;	// m_lines为文件总行数	if (m_lines <nPrintableLineCount) nPrintableLineCount="m_lines;" unsigned short MaxPage="(nPrintableLineCount" + m_LinesPerPage 1) / m_LinesPerPage; //设置所需打印纸张数目 pInfo->SetMaxPage(MaxPage);	pInfo-&gt;m_nCurPage = 1;  	//////////////////////////////////////////	//最后不要忘记将字体还原,这一句是必需的	pDC-&gt;SelectObject(oldFont );}</pre>    <p><font color="#ffffff">----</font> RedealTextData 函 数 根 据 每 行 最 大 宽     度 对 文 件 进 行 重 新 调 整。 主 要 是 计 算 文 件 中 每 行 的 宽     度, 如 果 超 过 最 大 宽 度 则 加 入 换 行 符(0x0d,0x0a)。 函 数     实 现 如 下: </p>    <pre>//=======================================// RedealTextData//注://pDoc-&gt;buffer为文件缓冲区//pDoc-&gt;file_length为文件字节长度//pDoc-&gt;TextLines为文件原行数//pDoc-&gt;MaxLineLength为文件原最大行字节宽度//=======================================void CTextView::RedealTextData(){  CDocViewDoc* pDoc = GetDocument();  ASSERT_VALID(pDoc);  short LineLengthMax = m_MaxLineChar;  unsigned short lines=0;  unsigned long	i,j;  //申请新的缓冲区保存调整后的文件  long	size = pDoc-&gt;file_length + pDoc-&gt;TextLines*	(pDoc-&gt;MaxLineLength/m_MaxLineChar+1);  m_newBuffer = new char [size ];  LPSTR newTempPtr = m_newBuffer;  m_file_length =pDoc-&gt;file_length;  //保存文件新的行数  m_lines = 1;				  i = 0;  //记录当前行的宽度  short	theLineLength=0;	  //记录当前行中汉字字节数,  //以防止将一半汉字分为两行  unsigned short halfChinese=0;  while(i <pDoc->file_length)  {   *newTempPtr++ = pDoc-&gt;buffer[i];		   j=i+1;   if( (pDoc-&gt;buffer[i] == 0x0d &amp;&amp; 	pDoc-&gt;buffer[j] == 0x0a))   {      m_lines++;      theLineLength = 0;   }   else   {      //如果是TAB字符,宽度加8      if(pDoc-&gt;buffer[i] == VK_TAB)		theLineLength += 8;      else       {      //大于0xa1的字节为汉字字节	if((unsigned char)pDoc-&gt;buffer[i] &gt;= 0xa1)		halfChinese++;	theLineLength++;	}	//如果行宽大于每行最大宽度,进行特殊处理	if(theLineLength &gt; LineLengthMax)	{	  char	buff[256];	  short m=255;	  newTempPtr--;          if((unsigned char )*newTempPtr &lt;0xa1) <fontcolor="#a30004"></pre>    <pre></font>//如果当前字符的前一个字符是数字、 //字母或一些特殊的前置符号时, </pre>    <pre>//指针循环向前取, //以防止将一个单词分为两行。</pre>    <pre> while((*newTempPtr&gt;='0' &amp;&amp; *newTempPtr&lt;='9')|| (*newTempPtr&gt;='a' &amp;&amp; *newTempPtr &lt;= 'z') || (*newTempPtr&gt;='A' &amp;&amp; *newTempPtr &lt;= 'Z') || *newTempPtr=&quot;=&quot; '_' || *newTempPtr=&quot;=&quot; '*' || *newTempPtr=&quot;=&quot; '^' || *newTempPtr=&quot;=&quot; '~' ) buff[m--]=&quot;*newTempPtr--;&quot; } else</pre>    <pre>//汉字 { //防止将一个汉字分为两行。 </pre>    <pre>if(halfChinese%2) buff[m--]=&quot;*newTempPtr--;&quot; } newTempPtr++; </pre>    <pre>//加入换行符,分为两行 </pre>    <pre>*newTempPtr++=&quot;0x0d;&quot; ;*newTempPtr++=&quot;0x0a;&quot; ; </pre>    <pre>for(short k=&quot;m+1;&quot; k&lt;256; k++) *newTempPtr++=&quot;buff[k];&quot; m_lines++; </pre>    <pre>theLineLength=&quot;0;&quot; m_file_length +=&quot;2;&quot; } } i++; } } </pre>    <h3><font color="#a30004">三、 实 现OnPrint 函 数 </font><font color="#ffffff">----</font>     在OnPrint 函 数 中 实 现 真 正 的 文 字 输 出, 主 要 功 能 包 括 设     置 打 印 字 体 大 小, 计 算 当 前 页 号 文 字 输 出 位 置, 以 及     文 字 的 输 出 打 印。 </h3>    <p><font color="#ffffff">----</font> 程 序 中 首 先 计 算 打 印 区 域, 文     字 在 这 个 打 印 区 域 内 输 出。 然 后 设 置 新 的 打 印 字 体。 </p>    <p><font color="#ffffff">----</font> 由 于OnPrint 函 数 是 每 打 印 一 页 被     调 用 一 次, 所 以 需 要 根 据 当 前 打 印 页 号 计 算 出 当 前 页     的 文 字 在 整 个 文 字 缓 冲 区 的 起 始 偏 移 量 和 终 止 偏 移     量。 这 里 程 序 中 调 用 了 函 数GetOffset(), 此 函 数 在 下 面 介     绍。 </p>    <p><font color="#ffffff">----</font> 最 后 调 用Windows 的DrawText() 函 数 实 现     文 字 的 输 出。 </p>    <p><font color="#ffffff">----</font> OnPrint() 函 数 实 现 如 下: </p>    <pre>//====================================// OnPrint//========================================void CTestView::OnPrint(CDC* pDC, 		CPrintInfo* pInfo) {	//计算打印区域 //////////////////	long yTopOfPage =(pInfo-&gt;m_nCurPage -1) * 		m_LinesPerPage * m_LineHeight;	//左边空出两个字符宽度	pDC-&gt;SetViewportOrg(m_CharWidth * 2, 				-yTopOfPage);		int nPageWidth = pDC-&gt;GetDeviceCaps(HORZRES);	CRect rectClip = CRect(0, 			yTopOfPage, 			nPageWidth,		 yTopOfPage + m_LinesPerPage * 		m_LineHeight);	/////设置缩小字体 ///////////////////	//取打印机的横方向和纵方向的分辨率	//即每英寸点数	short cxInch=pDC-&gt;GetDeviceCaps(LOGPIXELSX);	short cyInch= DC-&gt;GetDeviceCaps(LOGPIXELSY);	//取当前字体大小	CFont	*curFont = pDC-&gt;GetCurrentFont();	LOGFONT	curLogFont;	LOGFONT	newLogFont;	curFont-&gt;GetLogFont( &amp;curLogFont );	long NewFontWidth = curLogFont.lfWidth;	long NewFontHeight = curLogFont.lfHeight;	newLogFont = curLogFont;	//计算新的字体大小 --缩小一倍	newLogFont.lfWidth = (long)((float)NewFontWidth/2.0 			* ((float)cxInch / 72.0));	newLogFont.lfHeight = (long)((float)NewFontHeight/2.0 			* ((float)cyInch / 72.0)); 		//创建并设置新的字体,保留以前的字体	CFont	newFont;	CFont *oldFont;	newFont.CreateFontIndirect(&amp;newLogFont);	oldFont = pDC-&gt;SelectObject(&amp;newFont );	/////文字打印输出 /////////////////	unsigned short CurrentStartLine ,			 CurrentEndLine;	long	StartPrintOffset, 		EndPrintOffset, 		PrintSize;	LPSTR	tempPtr;	RECT	rect1,rect2;	//根据当前打印页号计算文字起始行	CurrentStartLine=(pInfo-&gt;m_nCurPage-1) * m_LinesPerPage;	//文字终止行	CurrentEndLine = CurrentStartLine+m_LinesPerPage;	if(CurrentEndLine &gt; m_lines)		CurrentEndLine = m_lines;	//计算打印文字的起始位置和终止位置	StartPrintOffset=GetOffset(m_newBuffer,			m_file_length, CurrentStartLine);	EndPrintOffset = GetOffset(m_newBuffer,			m_file_length,CurrentEndLine);	PrintSize = EndPrintOffset -	 StartPrintOffset;	tempPtr = m_newBuffer + StartPrintOffset;	//文字输出	pDC-&gt;DrawText(tempPtr, PrintSize,		&amp;rectClip,		DT_NOCLIP |DT_NOPREFIX 		|DT_EXPANDTABS);	//还原旧的打印字体	pDC-&gt;SelectObject(oldFont );}</pre>    <p><font color="#ffffff">----</font> 程 序 中 的 GetOffset 函 数 是 根 据 给 定     的 行 号 计 算 文 字 的 位 置, 其 实 现 如 下: </p>    <pre>//========================================// GetOffset ()  //========================================long	CTestView::GetOffset(LPSTR buffer, 		long buffer_length, 		unsigned short StartLine){	if(StartLine == 0) return 0;	unsigned short lines=0;	long	i,j;	i = 0;	while(i <buffer_length) { j="i+1;" if( (buffer[i++]="=" 0x0d && buffer[j]="=" 0x0a)) { lines++; if(lines="=" StartLine) return i; } } return buffer_length; } </pre><fontcolor="#ffffff">----</font> 以 上 是 本 人 在 编 程 中 的 一 点 心 得, 欢 迎 和 大 家 共 同 交 流。</pre>    </td>  </tr></table></center></div></body></html>

⌨️ 快捷键说明

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