📄 ch07.htm
字号:
<HTML>
<HEAD>
<TITLE>Special Edition Using Visual C++ 5 - Chapter 7</TITLE>
<LINK REL="Next" HREF="ch08.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/ch08.htm">
<LINK REL="Previous" HREF="ch06.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/ch06.htm"></HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H2><A ID="I1" NAME="I1"><B>Chapter 7</B></A></H2>
<H2><A ID="I2" NAME="I2"><A ID="I3" NAME="I3">Printing and Print Preview</A></A></H2>
<hr>
<ul>
<li> <B>How to create an application with basic printing capabilities</B></P>
<P> MFC does almost all the work required to get document printing and print preview incorporated into your AppWizard-generated application.</P>
<li> <B>How to use graphics mapping modes to scale printer output</B></P>
<P> The different Windows mapping modes use different units of measure when interpreting output coordinates.</P>
<li> <B>How to print a multiple-page document</B></P>
<P> Although MFC can handle basic printing tasks almost automatically, it needs a little help when it comes to multiple-page documents.</P>
<li> <B>How MFC class member functions control the printing process</B></P>
<P> Knowing which member functions to override is the key to controlling the printing and print preview process in your applications.</P>
</ul>
<P>If you brought together 10 Windows programmers and asked them what part of creating Windows applications they thought was the hardest, probably at least half of them would choose printing documents. Although Windows' device-independent nature makes it
easier for the user to get peripherals working properly, the programmer must take up some of the slack, by programming all devices in a general way. There was a time when printing from a Windows application was a nightmare that only the most experienced
programmers could handle. Now, however, thanks to application frameworks like MFC, the job of printing documents from a Windows application is much simpler.</P>
<H3><A ID="I4" NAME="I4"><A ID="I5" NAME="I5"><B>Understanding Basic Printing and Print Preview with MFC</B></A></A></H3>
<P>MFC handles so much of the printing task for you that, when it comes to simple one-page documents, there's little you have to do on your own. To see what I mean, follow these steps to create a basic MFC application that supports printing and print
preview:</P>
<ol>
<li><P> Choose <U>F</U>ile, <U>N</U>ew; then select the Projects tab and start a new AppWizard project workspace called Print1, as shown in Figure 7.1.</P>
</ol>
<A HREF="Ifig01.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch07/Ifig01.gif"><b>Fig. 7.1</b></A>
<P><I>Start an AppWizard project workspace called Print1.</I></P>
<ol start=2>
<li><P> Give the new project the following settings in the AppWizard dialog boxes. The New Project Information dialog box should then look like Figure 7.2.</P>
<P>Step 1: <U>S</U>ingle document</P>
<P>Step 2: Don't change the defaults presented by AppWizard</P>
<P>Step 3: Don't change the defaults presented by AppWizard</P>
<P>Step 4: Turn off all features except <U>P</U>rinting and Print Preview</P>
<P>Step 5: Don't change the defaults presented by AppWizard</P>
<P>Step 6: Don't change the defaults presented by AppWizard</P>
</ol>
<A HREF="Ifig02.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch07/Ifig02.gif"><b>Fig. 7.2</b></A>
<P><I>The New Project Information dialog box.</I></P>
<ol start=3>
<li><P> Expand the classes in ClassView, expand <font color="#008000">CPrint1View</font>, double-click the <font color="#008000">OnDraw()</font> function, and add the following line of code to it, right after the comment that says <font
color="#008000">TODO: </font><font color="#008000">add draw code for native data here</font>:</P>
<pre><font color="#008000"> pDC->Rectangle(20, 20, 220, 220);</font></pre>
<P> You've seen the <font color="#008000">Rectangle()</font> function twice already: in the Recs app of <A HREF="index05.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index05.htm" target="text">Chapter 5</A>, "Documents and Views" and the Paint1 app of <A HREF="index06.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index06.htm" target="text">Chapter
6</A>, "Drawing on the Screen." Adding this function to the <font color="#008000">OnDraw()</font> function of an MFC program's view class causes the program to draw a rectangle. This one is 200 pixels by 200 pixels, located 20 pixels down from
the top of the view and 20 pixels over from the left edge.</P>
</ol>
<blockquote><p><img src="tip.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/tip.gif">
<P>If you haven't read <A HREF="index06.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index06.htm" target="text">Chapter 6</A>, "Drawing on the Screen," and are not comfortable with device contexts, go back and read it now. Also, if you didn't read <A HREF="index05.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index05.htm" target="text">Chapter 5</A>,
"Documents and Views," and aren't comfortable with the document/view paradigm, you should read it, too. In this chapter, you override a number of virtual functions in your view class and work extensively with device contexts.</P>
<p><img src="bottom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/bottom.gif"></blockquote>
<P>Believe it or not, you've just created a fully print-capable application that can display its data (a rectangle) not only in its main window, but also in a print preview window and on the printer. To run the Print1 application, first compile and link
the source code by choosing <U>B</U>uild, <U>B</U>uild, or by pressing F7 on your keyboard. Then, choose <U>B</U>uild, E<U>x</U>ecute to run the program. When you do, you should see the window shown in Figure 7.3. This window contains the application's
output data, which is simply a rectangle. Next, choose <U>F</U>ile, Print Pre<U>v</U>iew. You see the print preview window shown in Figure 7.4. This window displays the document as it will appear if you print it. Go ahead and print the document (choose
<U>F</U>ile, <U>P</U>rint). These commands have been implemented for you, because you chose support for printing and print preview when you created this application with AppWizard.</P>
<A HREF="Ifig03.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch07/Ifig03.gif"><b>Fig. 7.3</b></A>
<P><I>Print1 displays a rectangle when you first run it.</I></P>
<A HREF="Ifig04.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch07/Ifig04.gif"><b>Fig. 7.4</b></A>
<P><I>The Print1 application automatically handles print previewing thanks to the MFC AppWizard.</I></P>
<H3><A ID="I6" NAME="I6"><A ID="I7" NAME="I7"><B>Scaling</B></A></A></H3>
<P>One thing you may notice about the printed document and the one displayed on-screen is that, although the screen version of the rectangle takes up a fairly large portion of the application's window, the printed version is pretty tiny. That's because
the pixels on your screen and the dots on your printer are different sizes. Although the rectangle is 200 dots square in both cases, the smaller printer dots yield a rectangle that appears smaller. This is how Windows' <font color="#008000">MM_TEXT</font>
graphics mapping mode, which is the default, works. If you want to scale the printed image to a specific size, you might want to choose a different mapping mode. Table 7.1 lists the mapping modes from which you can choose.</P>
<P><I>Table 7.1—Mapping Modes</I></P>
<TABLE BORDER>
<TR>
<TD>
<P><B>Mode</B></P>
<TD>
<P><b>Unit</b></P>
<TD>
<P><b>X</b></P>
<TD>
<P><b>Y</b></P>
<TR>
<TD>
<pre><font color="#008000">MM_HIENGLISH</font></pre>
<TD>
<P>0.001 inch</P>
<TD>
<P>Increases right</P>
<TD>
<P>Increases up</P>
<TR>
<TD>
<pre><font color="#008000">MM_HIMETRIC</font></pre>
<TD>
<P>0.01 millimeter</P>
<TD>
<P>Increases right</P>
<TD>
<P>Increases up</P>
<TR>
<TD>
<pre><font color="#008000">MM_ISOTROPIC</font></pre>
<TD>
<P>User defined</P>
<TD>
<P>User defined</P>
<TD>
<P>User defined</P>
<TR>
<TD>
<pre><font color="#008000">MM_LOENGLISH</font></pre>
<TD>
<P>0.01 inch</P>
<TD>
<P>Increases right</P>
<TD>
<P>Increases up</P>
<TR>
<TD>
<pre><font color="#008000">MM_LOMETRIC</font></pre>
<TD>
<P>0.1 millimeter</P>
<TD>
<P>Increases right</P>
<TD>
<P>Increases up</P>
<TR>
<TD>
<pre><font color="#008000">MM_TEXT</font></pre>
<TD>
<P>Device pixel</P>
<TD>
<P>Increases right</P>
<TD>
<P>Increases down</P>
<TR>
<TD>
<pre><font color="#008000">MM_TWIPS</font></pre>
<TD>
<P>1/1440 inch</P>
<TD>
<P>Increases right</P>
<TD>
<P>Increases up</P></TABLE>
<P>Working with graphics in <font color="#008000">MM_TEXT</font> mode causes problems when printers and screens can accommodate a different number of pixels per page. A better mapping mode for working with graphics is <font
color="#008000">MM_LOENGLISH</font>, which uses a hundredth of an inch, rather than a dot or pixel, as a unit of measure. To change the Print1 application so that it uses the <font color="#008000">MM_LOENGLISH</font> mapping mode, replace the line you
added to the <font color="#008000">OnDraw()</font> function with the following two lines:</P>
<pre><font color="#008000"> pDC->SetMapMode(MM_LOENGLISH);</font></pre>
<pre><font color="#008000"> pDC->Rectangle(20, -20, 220, -220);</font></pre>
<P>The first line sets the mapping mode for the device context. The second line draws the rectangle using the new coordinate system. Why the negative values? If you look at <font color="#008000">MM_LOENGLISH</font> in Table 7.1, you see that although X
coordinates increase to the right as you expect, Y coordinates increase upwards rather than downwards. Moreover, the default coordinates for the window are located in the lower-right quadrant of the Cartesian coordinate system, as shown in Figure 7.5.
Figure 7.6 shows the print preview window when the application uses the <font color="#008000">MM_LOENGLISH</font> mapping mode. When you print the document, the rectangle is exactly two inches square. This is because a unit is now 1/100 of an inch and the
rectangle is 200 units square.</P>
<B><A HREF="Ifig05.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch07/Ifig05.gif">FIG. 7.5</A></b>
<P><I>The </I><I>MM_LOENGLISH</I><I> mapping mode's default coordinates are derived from the Cartesian </I><I>coordinate system.</I></P>
<A HREF="Ifig06.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch07/Ifig06.gif"><b>Fig. 7.6</b></A>
<P><I>The rectangle to be printed matches the rectangle on the screen when you use </I><I>MM_LOENGLISH</I><I> </I><I>as your mapping mode.</I></P>
<H3><A ID="I8" NAME="I8"><A ID="I9" NAME="I9"><B>Printing Multiple Pages</B></A></A></H3>
<P>When your application's document is as simple as Print1's, adding printing and print previewing capabilities to the application is virtually automatic. This is because the document is only a single page and requires no pagination. No matter what you
draw in the document's window (except bitmaps), MFC handles all the printing tasks for you. Your view's <font color="#008000">OnDraw()</font> function is used for drawing on-screen, for printing to the printer, and for drawing the print preview screen.
Things get more complex, however, when you have larger documents that require pagination or some other special handling, like the printing of headers and footers.</P>
<P>To get an idea of the problems with which you're faced with a more complex document, you are going to modify Print1 so that it prints lots of rectangles—so many that they can't fit on a single page. This will give you an opportunity to deal with
pagination. Just to make things more interesting, you will add a member variable to the document class to hold the number of rectangles to be drawn, then allow the user to increase or decrease the number of rectangles by left or right-clicking. Follow
these steps:</P>
<ol>
<li><P> Expand <font color="#008000">CPrint1Doc</font> in ClassView, right-click it, and choose Add Member <U>V</U>ariable from the shortcut menu. The variable type is <font color="#008000">int</font>, the declaration is <font
color="#008000">m_numRects</font>, and the access should be public. This variable will hold the number of rectangles to display.</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -