📄 ch21.htm
字号:
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Time Saver:</B></FONT><B> </B>By default, only one
page will be printed unless you override this function and set <TT>m_bContinuePrinting</TT>
to <TT>TRUE</TT>.
<HR>
</BLOCKQUOTE>
<H3><FONT COLOR="#000077"><B>Using the <TT>OnPrint</TT> Function</B></FONT></H3>
<P>The <TT>OnPrint</TT> function is the printing counterpart to <TT>OnDraw</TT>.
In fact, many programs can just use the default version of <TT>OnPrint</TT>, which
calls <TT>OnDraw</TT>. However, most printouts can benefit from providing page numbers,
headers, footers, or special fonts that aren't displayed in the view.</P>
<P><FONT COLOR="#000077"><B>New Term:</B></FONT><B> </B>A <I>twip</I> is one-twentieth
of a point. A <I>point</I>, in turn, is almost exactly 1/72 of an inch. This works
out to about 1,440 twips per inch.</P>
<P>When printing, the <TT>MM_TWIPS</TT> mapping mode is used. The really odd thing
about <TT>MM_TWIPS</TT> is that the mapping mode begins with the upper-left corner
at (0,0) and runs in a negative direction down the page, making the point one inch
below the origin (0,-1440). Like other modes, the mapping mode extends in a positive
direction to the right side of the page.</P>
<P>The <TT>OnPrint</TT> function is called once for every page. If you're printing
data that is arranged so that the page number can easily be determined, it's a good
idea to use the <TT>CPrintInfo</TT> parameter to determine the current page number.
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Just a Minute:</B></FONT><B> </B>Remember, the user
might ask for a range of pages to be printed, not just the entire document.
<HR>
</BLOCKQUOTE>
<H3><FONT COLOR="#000077"><B>Using the <TT>OnEndPrinting</TT> Function</B></FONT></H3>
<P>The <TT>OnEndPrinting</TT> function is called after the printout is finished.
This function can be called because the job was completed successfully or because
it has failed; you don't really know. The purpose of this function is to release
any resources that were allocated in the <TT>OnBeginPrinting</TT> function.
<H3><FONT COLOR="#000077"><B>Querying the Printing Device Context</B></FONT></H3>
<P>Unlike video displays, printing devices offer a wide variation in their capabilities.
It's a good idea to examine the capabilities of a printout device before attempting
graphics functions.</P>
<P>As shown in Listing 21.3, you can use the <TT>CDC::GetDeviceCaps</TT> function
to retrieve information about a selected output device.
<H4><FONT COLOR="#000077">TYPE: Listing 21.3. Using GetDeviceCaps to determine whether
BitBlt is supported.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>int nRasterFlags = pDC->GetDeviceCaps(RASTERCAPS);</TT>
<TT>if(nRasterCaps & RC_BITBLT)</TT>
<TT>{</TT>
<TT> // BitBlt is allowed</TT>
<TT>}</TT>
<TT>else</TT>
<TT>{</TT>
<TT> // BitBlt is not allowed</TT>
</FONT></PRE>
<P><TT>}</TT> <TT>GetDeviceCaps</TT> accepts an index as a parameter. This index
specifies the type of information returned from the function. In Listing 21.2, the
<TT>RASTERCAPS</TT> index results in a return value that contains flags which indicate
the raster capabilities of the device. If the <TT>RC_BITBLT</TT> flag is set, the
<TT>BitBlt</TT> function can be applied to that device.
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Time Saver:</B></FONT><B> </B>You can use this function
for any type of device--not just printers. This function can be used to return all
types of information. Check the online documentation for details.
<HR>
</BLOCKQUOTE>
<H2><FONT COLOR="#000077"><B>Adding More Functionality to MFCPrint</B></FONT></H2>
<P>The remaining part of this hour is used to add printing functionality to the MFCPrint
example, using the functions discussed in the earlier sections. The <TT>OnPreparePrinting</TT>
function supplied by AppWizard isn't changed for this example.
<H3><FONT COLOR="#000077"><B>The <TT>CMFCPrintView</TT> Constructor and Destructor</B></FONT></H3>
<P>The member variables added to the <TT>CMFCPrintView</TT> class must be initialized
in the <TT>CMFCPrintView</TT> constructor, and any allocated resources must be released
in the destructor. The source code for the constructor and destructor is provided
in Listing 21.4.
<H4><FONT COLOR="#000077">TYPE: Listing 21.4. The constructor and destructor for
CMFCPrintView.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>CMFCPrintView::CMFCPrintView()</TT>
<TT>{</TT>
<TT> COLORREF clrBlack = GetSysColor(COLOR_WINDOWFRAME);</TT>
<TT> m_penBlack.CreatePen(PS_SOLID, 0, clrBlack);</TT>
<TT> m_pFntBold = 0;</TT>
<TT> m_pFntBanner = 0;</TT>
<TT> m_pFntHighlight = 0;</TT>
<TT>}</TT>
<TT>CMFCPrintView::~CMFCPrintView()</TT>
<TT>{</TT>
<TT> // The fonts must be released explicitly</TT>
<TT> // since they were created with new.</TT>
<TT> delete m_pFntBold;</TT>
<TT> delete m_pFntBanner;</TT>
<TT> delete m_pFntHighlight;</TT>
</FONT></PRE>
<P><TT>}</TT> The usual practice with GDI objects is to defer actually creating the
object until it is needed. The constructor for <TT>CMFCPrintView</TT> sets each of
the <TT>CFont</TT> pointer variables to <TT>0</TT>; these objects are created on
the heap when the print job begins.</P>
<P>The destructor for <TT>CMFCPrintView</TT> deletes the dynamically allocated <TT>CFont</TT>
objects. Under normal execution, these pointers do not need to be freed because resources
are released at the end of a print job. However, this code protects you in case of
abnormal program termination, and because it is always safe to delete a pointer to
<TT>NULL</TT>, no harm will come to your program in the normal case.
<H3><FONT COLOR="#000077"><B>Allocating Resources in the <TT>OnBeginPrinting</TT>
Function</B></FONT></H3>
<P>As you learned earlier, the <TT>OnBeginPrinting</TT> function is called just before
printing begins. Add the source code provided in Listing 21.5 to the <TT>OnBeginPrinting</TT>
function. This version of <TT>OnBeginPrinting</TT> creates three new fonts that are
used in the printout. (You learned about creating fonts in Hour 13, "Fonts.")
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Just a Minute:</B></FONT><B> </B>To prevent compiler
warnings about unused variables, AppWizard comments out the <TT>pDC</TT> and <TT>pInfo</TT>
parameters. If you use these parameters, you must remove the comments, as shown in
Listing 21.5.
<HR>
</BLOCKQUOTE>
<H4><FONT COLOR="#000077">TYPE: Listing 21.5. Allocating new fonts in the OnBeginPrinting
function.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CMFCPrintView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)</TT>
<TT>{</TT>
<TT> ASSERT( m_pFntBold == 0 );</TT>
<TT> ASSERT( m_pFntBanner == 0 );</TT>
<TT> ASSERT( m_pFntHighlight == 0 );</TT>
<TT> m_nCurrentPrintedPage = 0;</TT>
<TT> pDC->SetMapMode( MM_TWIPS );</TT>
<TT> // Create the bold font used for the fields. TimesRoman,</TT>
<TT> // 12 point semi-bold is used.</TT>
<TT> m_pFntBold = new CFont;</TT>
<TT> ASSERT( m_pFntBold );</TT>
<TT> m_pFntBold->CreateFont( -240,</TT>
<TT> 0,</TT>
<TT> 0,</TT>
<TT> 0,</TT>
<TT> FW_SEMIBOLD,</TT>
<TT> FALSE,</TT>
<TT> FALSE,</TT>
<TT> 0,</TT>
<TT> ANSI_CHARSET,</TT>
<TT> OUT_TT_PRECIS,</TT>
<TT> CLIP_DEFAULT_PRECIS,</TT>
<TT> DEFAULT_QUALITY,</TT>
<TT> DEFAULT_PITCH | FF_ROMAN,</TT>
<TT> "Times Roman" );</TT>
<TT> // Create the normal font used for the Headline banner.</TT>
<TT> // TimesRoman, 18 point italic is used.</TT>
<TT> m_pFntBanner = new CFont;</TT>
<TT> ASSERT( m_pFntBanner );</TT>
<TT> m_pFntBanner->CreateFont( -360,</TT>
<TT> 0,</TT>
<TT> 0,</TT>
<TT> 0,</TT>
<TT> FW_NORMAL,</TT>
<TT> TRUE,</TT>
<TT> FALSE,</TT>
<TT> 0,</TT>
<TT> ANSI_CHARSET,</TT>
<TT> OUT_TT_PRECIS,</TT>
<TT> CLIP_DEFAULT_PRECIS,</TT>
<TT> DEFAULT_QUALITY,</TT>
<TT> DEFAULT_PITCH | FF_ROMAN,</TT>
<TT> "Times Roman" );</TT>
<TT> // Create the normal font used for the Headline highlight.</TT>
<TT> // This is the text used under the headline banner, and in</TT>
<TT> // the footer. TimesRoman, 8 point is used.</TT>
<TT> m_pFntHighlight = new CFont;</TT>
<TT> ASSERT( m_pFntHighlight );</TT>
<TT> m_pFntHighlight->CreateFont( -160,</TT>
<TT> 0,</TT>
<TT> 0,</TT>
<TT> 0,</TT>
<TT> FW_NORMAL,</TT>
<TT> TRUE,</TT>
<TT> FALSE,</TT>
<TT> 0,</TT>
<TT> ANSI_CHARSET,</TT>
<TT> OUT_TT_PRECIS,</TT>
<TT> CLIP_DEFAULT_PRECIS,</TT>
<TT> DEFAULT_QUALITY,</TT>
<TT> DEFAULT_PITCH | FF_ROMAN,</TT>
<TT> "Times Roman" );</TT>
<TT> CView::OnBeginPrinting(pDC, pInfo);</TT>
<TT>}</TT></FONT></PRE>
<H3><FONT COLOR="#000077"><B>Handling Multiple Pages in the <TT>OnPrepareDC</TT>
Function</B></FONT></H3>
<P>The <TT>OnPrepareDC</TT> function is called just before each page is printed.
The default version of this function allows one page to be printed. By modifying
the <TT>bContinuePrinting</TT> flag, you can use this function to continue the printout.
Add the source code provided in Listing 21.6 to the <TT>OnPrepareDC</TT> function.
<H4><FONT COLOR="#000077">TYPE: Listing 21.6. The OnPrepareDC function.</FONT></H4>
<PRE><FONT COLOR="#0066FF">
<TT>void CMFCPrintView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)</TT>
<TT>{</TT>
<TT> CView::OnPrepareDC(pDC, pInfo);</TT>
<TT> if( pInfo )</TT>
<TT> {</TT>
<TT> if( pInfo->m_nCurPage < 3 )</TT>
<TT> pInfo->m_bContinuePrinting = TRUE;</TT>
<TT> else</TT>
<TT> pInfo->m_bContinuePrinting = FALSE;</TT>
<TT> }</TT>
<TT>}</TT></FONT></PRE>
<H3><FONT COLOR="#000077"><B>Modifying the MFCPrint <TT>OnPrint</TT> Function</B></FONT></H3>
<P>The default implementation of <TT>OnPrint</TT> calls the <TT>OnDraw</TT> member
function. For this example, add the source code from Listing 21.7 to <TT>OnPrint</TT>,
which sends a header followed by several rows of text and a footer to the printer.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -