?? chap8_6.htm
字號(hào):
<html>
<head>
<title>8.6 打印和打印預(yù)覽</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
</head>
<body link="#3973DE" alink="#3973DE">
<font SIZE="5"><b><div align="center"><center>
<table border="0" width="615" cellspacing="0" cellpadding="0">
<tr>
</b><td><div align="center"><center><table border="0" width="615" cellpadding="0" cellspacing="0" height="20">
<tr>
<td width="377" bgcolor="#15397D" height="20"></td>
<td width="238" bgcolor="#000000" height="20"><p align="right"></font><span style="text-decoration: none"><a href="../../index.htm"><font color="#FFFFFF">電腦報(bào)Visual
C++網(wǎng)絡(luò)教程</font></a></span></td>
</tr>
</table>
</center></div><font FACE="Times New Roman" SIZE="4"><b><p ALIGN="CENTER"></b></font><font color="#3973DE" FACE="Times New Roman" size="5">8.6 </font><font color="#3973DE" size="5">打印和打印預(yù)覽</font><font size="4"></p>
<p></font><font SIZE="3">最后,我們要給繪圖程序增加打印和打印預(yù)覽功能。我們希望文檔分兩頁打印,第一頁為封面,打印文檔名字。第二頁輸出文檔內(nèi)容,并在頁眉上打印文檔名字。雖然</font><font FACE="Times New Roman" SIZE="3">AppWizard</font><font SIZE="3">已經(jīng)自動(dòng)生成了打印和打印預(yù)覽的代碼,但是許多情況下,并不能符合要求。</p>
<blockquote>
<p>這是因?yàn)椋?lt;/p>
</blockquote>
<blockquote>
<p>1.打印機(jī)和窗口(屏幕)顯示的分辨率不同:打印機(jī)的分辨率用每英寸多少個(gè)點(diǎn)來描述,屏幕分辨率用單位面積的像素點(diǎn)來表示。對(duì)于同樣的Arial字體下的一個(gè)字符,在屏幕上用20個(gè)像素表示,而在打印機(jī)上則需要50點(diǎn)。在編輯器程序中,使用的映射模式為MM_TEXT,在這種模式下,一個(gè)邏輯單位對(duì)應(yīng)于一個(gè)像素點(diǎn)。我們已經(jīng)知道,Windows是按照邏輯單位來繪圖的。這樣,根據(jù)MM_TEXT模式的邏輯單位(實(shí)際上也就是像素?cái)?shù)目)決定比例的原則打印出來得內(nèi)容自然要比屏幕上看到的要小的多。因此,前面在初始化視圖OnInitialUpdate時(shí)候,在選擇繪圖的映射模式上,沒有采用以前使用的缺省的MM_TEXT模式,而是采用了MM_LOENGLISH。</p>
<p>2.窗口和打印機(jī)對(duì)邊界的處理不同:窗口可以看作是無邊界的,可以在窗口外面畫,而不會(huì)引起錯(cuò)誤,窗口會(huì)自動(dòng)剪裁超出邊界的圖形。但打印機(jī)卻不同,它是按頁打印的。打印輸出時(shí)必須自己處理分頁和換頁,如果不作這樣的處理的話,行和行之間就會(huì)疊加起來。</p>
</blockquote>
<p>要正確打印輸出屏幕上的內(nèi)容,就必須解決以上兩個(gè)問題。對(duì)于第一個(gè)問題,有兩種方法:一是利用SetMapMode(int
nMode) 設(shè)置別的映射模式,比如采用MM_LOENGLISH,不用像素而是采用0.01inch來衡量。</font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">要處理打印分頁、換頁,就必須修改框架處理打印消息的缺省行為,在其中計(jì)算和換頁。此外,我們還希望在打印時(shí)在頁眉處能夠輸出標(biāo)題(使用文件名作為標(biāo)題)、在頁腳處輸出頁碼。</p>
<p>為了實(shí)現(xiàn)打印和打印預(yù)覽功能,首先需要了解MFC的打印體系結(jié)構(gòu),即框架是如何處理打印文檔的要求的。</p>
<p>MFC的打印工作大致上是這樣進(jìn)行的:</p>
<p>1.顯示Print對(duì)話框</p>
<p>2.創(chuàng)建一個(gè)與當(dāng)前打印機(jī)設(shè)置相匹配的設(shè)備上下文(CDC)對(duì)象。</p>
<p>3.設(shè)置要打印的頁數(shù)</p>
<p>4.調(diào)用CDC::StartDoc開始打印</p>
<p>5.用CDC::StartPage開始打印一頁</p>
<p>6.調(diào)用視圖的OnDraw()方法打印輸出一頁內(nèi)容</p>
<p>7.用CDC::EndPage結(jié)束一頁的打印</p>
<p>8.循環(huán)輸出全部內(nèi)容</p>
<p>9.用CDC::EndDoc結(jié)束打印</p>
<p>10.視圖作打印的清理工作</p>
<p>框架的打印文檔功能是從OnPreparePrinting(CPrintInfo* pInfo)開始的,在缺省的情況下,它只是簡單的調(diào)用視圖的DoPreparePrinting()函數(shù)。DoPreparePrinting()顯示Print對(duì)話框,并創(chuàng)建與打印機(jī)相匹配的設(shè)備上下文。如果要想改變打印機(jī)初始設(shè)置,可以在這里改。缺省設(shè)置下,使用1作為第一頁編號(hào)(注意:打印的頁號(hào)是從1開始編號(hào)而不是0),用0xFFFF作為文檔的最后一頁編號(hào)。因?yàn)镈raw要求分兩頁打印輸出,因此要在這里設(shè)置打印頁數(shù)。要設(shè)置打印頁數(shù),可以調(diào)用CPrintInfo::SetMaxPage(nMaxPage)。同時(shí)還將預(yù)覽頁數(shù)也設(shè)置為兩頁。</p>
<p>BOOL CDrawView::OnPreparePrinting(CPrintInfo* pInfo)</p>
<p>{</p>
<p><b> </p>
<p>pInfo->SetMaxPage(2); // the document is two pages long:</p>
<p>// the first page is the title page</p>
<p>// the second is the drawing</p>
<p>BOOL bRet = DoPreparePrinting(pInfo); // default preparation</p>
<p>pInfo->m_nNumPreviewPages = 2; // Preview 2 pages at a time</p>
<p>// Set this value after calling DoPreparePrinting to override</p>
<p>// value read from .INI file</p>
<p>return bRet;</b></p>
<p>}</p>
<p>DoPreparePrinting顯示Print對(duì)話框。返回時(shí),CPrintInfo結(jié)構(gòu)包含了用戶所指定的值,包括起止頁號(hào)、最大頁號(hào)、最小頁號(hào)等。</p>
<p>OnBeginPrinting()在OnPreparePrinting()被調(diào)用之后實(shí)際打印之前調(diào)用。OnBeginPrinting()用于分配GDI資源,這里使用缺省行為。</p>
<p>OnPrepareDC用作屏幕顯示時(shí),在繪圖前調(diào)整DC。在用于打印時(shí),OnPrepareDC也完成類似功能。</p>
<p>OnPrint完成真正的打印一頁文檔的工作。它把一個(gè)打印機(jī)設(shè)備上下文傳給OnDraw,由OnDraw負(fù)責(zé)打印輸出??梢园涯切┻m合于打印但是不適合于屏幕輸出的工作,如打印頁眉和頁腳,放在OnPrint()的重載中完成,然后再調(diào)用OnDraw完成打印和顯示都需要的工作?,F(xiàn)在,我們就在OnPrint中加入打印頁眉和頁腳的代碼。OnPrint不是由AppWizard自動(dòng)生成的,首先要用ClassWizard為CDrawView增加OnPrint()方法。然后添加繪圖程序的特殊打印代碼,見清單8.10。</p>
<p><b> </p>
<p>清單8.10 OnPrint()成員函數(shù)</b></p>
<p>void CDrawView::OnPrint(CDC* pDC, CPrintInfo* pInfo) </p>
<p>{</p>
<p><b> </p>
<p>// TODO: Add your specialized code here and/or call the base class</p>
<p>if (pInfo->m_nCurPage == 1) // page no. 1 is the title page</p>
<p>{</p>
<p>PrintTitlePage(pDC, pInfo);</p>
<p>return; // nothing else to print on page 1 but the page title</p>
<p>}</p>
<p>CString strHeader = GetDocument()->GetTitle();</p>
<p>PrintPageHeader(pDC, pInfo, strHeader);</p>
<p>// PrintPageHeader() subtracts out from the pInfo->m_rectDraw the</p>
<p>// amount of the page used for the header.</p>
<p>pDC->SetWindowOrg(pInfo->m_rectDraw.left,-pInfo->m_rectDraw.top);</p>
<p>// Now print the rest of the page</p>
<p>OnDraw(pDC); </b></p>
<p>}</p>
<p> </p>
<p>OnPrint()首先根據(jù)CPrintInfo類型的pInfo中m_nCurPage(保存當(dāng)前打印頁號(hào)信息)判斷當(dāng)前打印的是不是第一頁。如果是第一頁,就打印輸出封面。否則,首先調(diào)用PrintPageHeader打印頁眉。然后用SetWindowOrg調(diào)整打印輸出原點(diǎn)位置。m_rectDraw又是CPrintInfo結(jié)構(gòu)的一個(gè)重要數(shù)據(jù)成員,它保存的是打印輸出的矩形邊界。最后將與打印機(jī)匹配的設(shè)備上下文傳給OnDraw,由OnDraw在打印機(jī)上輸出。注意這里使用的映射模式為MM_LOENGLISH,它的y軸方向是向上遞增的。</p>
<p>PrintTitlePage打印輸出文檔的封面。它首先定義一種邏輯字體,設(shè)置邏輯字體屬性,然后由調(diào)用CreateFontIndirect由邏輯字體創(chuàng)建字體。SetTextAlign(TA_CENTER)將文本設(shè)置為居中輸出。然后調(diào)用TextOut在打印矩形m_rectDraw上輸出封面。PrintTitlePage函數(shù)定義見清單8.11。</p>
<p><b> </p>
<p>清單8.11 PrintTitlePage成員函數(shù)</p>
<p>void CDrawView::PrintTitlePage(CDC* pDC, CPrintInfo* pInfo)</p>
<p>{</p>
<p>// Prepare a font size for displaying the file name</p>
<p>LOGFONT logFont;</p>
<p>memset(&logFont, 0, sizeof(LOGFONT));</p>
<p>logFont.lfHeight = 75; // 3/4th inch high in MM_LOENGLISH</p>
<p>// (1/100th inch)</p>
<p>CFont font;</p>
<p>CFont* pOldFont = NULL;</p>
<p>if (font.CreateFontIndirect(&logFont))</p>
<p>pOldFont = pDC->SelectObject(&font);</p>
<p>// Get the file name, to be displayed on title page</p>
<p>CString strPageTitle = GetDocument()->GetTitle();</p>
<p>// Display the file name 1 inch below top of the page,</p>
<p>// centered horizontally</p>
<p>pDC->SetTextAlign(TA_CENTER);</p>
<p>pDC->TextOut(pInfo->m_rectDraw.right/2, -100, strPageTitle);</p>
<p>if (pOldFont != NULL)</p>
<p>pDC->SelectObject(pOldFont);</p>
<p>}</b></p>
<p>PrintPageHeader在頁眉位置輸出文件名,然后從m_rectDraw扣除頁眉的大小。</p>
<p><b> </p>
<p>void CDrawView::PrintPageHeader(CDC* pDC, CPrintInfo* pInfo,</p>
<p>CString& strHeader)</p>
<p>{</p>
<p>// Print a page header consisting of the name of</p>
<p>// the document and a horizontal line</p>
<p>pDC->SetTextAlign(TA_LEFT);</p>
<p>pDC->TextOut(0,-25, strHeader); // 1/4 inch down</p>
<p>// Draw a line across the page, below the header</p>
<p>TEXTMETRIC textMetric;</p>
<p>pDC->GetTextMetrics(&textMetric);</p>
<p>int y = -35 - textMetric.tmHeight; // line 1/10th inch below text</p>
<p>pDC->MoveTo(0, y); // from left margin</p>
<p>pDC->LineTo(pInfo->m_rectDraw.right, y); // to right margin</p>
<p>// Subtract out from the drawing rectange the space used by the header.</p>
<p>y -= 25; // space 1/4 inch below (top of) line</p>
<p>pInfo->m_rectDraw.top += y;</p>
<p>}</b></font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><font SIZE="3">作為一個(gè)練習(xí),讀者可以修改</font><font FACE="Times New Roman" SIZE="3">OnPrint()</font><font SIZE="3">并增加一個(gè)</font><font FACE="Times New Roman" SIZE="3">PrintPageFooter()</font><font SIZE="3">函數(shù),在每一頁的頁腳處輸出打印的頁號(hào)。注意調(diào)用</font><font FACE="Times New Roman" SIZE="3">OnDraw</font><font SIZE="3">之前,要從</font><font FACE="Times New Roman" SIZE="3">m_rectDraw</font><font SIZE="3">中扣除頁腳的高度。</font><font FACE="Times New Roman" SIZE="4"><b></p>
</b></font><div align="center"><center><table border="0" cellpadding="0" cellspacing="0" width="615">
<tr>
<td><a href="../chap2/chap2_4.htm">上一頁</a></td>
<td><p align="right"><a href="../chap2/chap2_6.htm">下一頁</a></td>
</tr>
</table>
</center></div><font SIZE="5"><hr noshade color="#3973DE" size="1">
<p align="center"></font><font size="2" color="#000000">本教程由<a href="http://vcdynasty.yeah.net">Visual C++王朝(Where programmers come together)</a>協(xié)助制作<br>
未經(jīng)許可,請(qǐng)勿以任何形式復(fù)制</font></td>
<b>
</tr>
</table>
</center></div>
<p ALIGN="CENTER"></b><font SIZE="5"> </font><font FACE="Times New Roman" SIZE="5"></p>
</font><font FACE="Times New Roman" SIZE="3">
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
</font></b>
<p><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p></font> </p>
</body>
</html>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -