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

📄 apc.htm

📁 有关Visual C++ 6.0 编程实例与技巧方面的相关资料
💻 HTM
📖 第 1 页 / 共 4 页
字号:
need 120 pages. However, if you are printing a complex government tender with differentbill elements and formatted items, you'll probably need to measure the height ofall the different parts and calculate a page count after performing your own pagination.Either way, when you have the page count, OnPreparePrinting() is where you'll setit into the CPrintInfo object.</P><BLOCKQUOTE>	<P><HR><B>BYPASSING THE PRINT DIALOG BOX WHEN PRINTING</B></P>	<P>You don't always need to bother the user with the Print dialog box; this can be	bypassed by setting the pInfo-&gt;m_bDirect variable to TRUE in OnPreparePrinting().<HR></BLOCKQUOTE><P>To emphasize the difference between a full report and a window print, you canimplement a completely different drawing in the OnPrint() function than OnDraw(),as shown in Listing C.4. In this OnPrint(), the base class CView::OnPrint() functionisn't called at all, which means that the default call of OnDraw() isn't performed.So in this implementation, the printing output and the display output are entirelydifferent.</P><P><H4>LISTING C.4.&nbsp;LST23_4.CPP--IMPLEMENTING PAGE-SPECIFIC DRAWING IN OnPrint().</H4><PRE>1: void CPrintItView::OnPrint(CDC* pDC, CPrintInfo* pInfo)2: {3:    // TODO: Add your specialized code here 4:5:   // ** Create and select the font6:   CFont fnTimes;7:   fnTimes.CreatePointFont(720,&quot;Times New Roman&quot;,pDC);8:    CFont* pOldFont=(CFont*)pDC-&gt;SelectObject(&amp;fnTimes);9:10:    // ** Create and select the brush11:    CBrush brHatch(HS_CROSS,RGB(64,64,64));12:    CBrush* pOldBrush = 13:        (CBrush*)pDC-&gt;SelectObject(&amp;brHatch);14:15:    // ** Create the page text16:    CString strDocText;17:    strDocText.Format(&quot;Page Number %d&quot;,18:                         pInfo-&gt;m_nCurPage);19:20:    pDC-&gt;SetTextAlign(TA_CENTER+TA_BASELINE);21:22:    // ** Set up some useful point objects23:    CPoint ptCenter=pInfo-&gt;m_rectDraw.CenterPoint();24:    CPoint ptTopLeft=pInfo-&gt;m_rectDraw.TopLeft();25:  CPoint ptBotRight=pInfo-&gt;m_rectDraw.BottomRight();26:27:    // ** Create the points for the diamond28:    CPoint ptPolyArray[4]=29:    {30:        CPoint(ptTopLeft.x,ptCenter.y),31:        CPoint(ptCenter.x,ptTopLeft.y),32:        CPoint(ptBotRight.x,ptCenter.y),33:        CPoint(ptCenter.x,ptBotRight.y)34:    };35:36:    // ** Draw the diamond37:    pDC-&gt;Polygon(ptPolyArray,4);38:39:    // ** Draw the text40:    pDC-&gt;TextOut(ptCenter.x,ptCenter.y,strDocText);41:42:    // ** Unselect the fonts43:    pDC-&gt;SelectObject(pOldFont);44:    pDC-&gt;SelectObject(pOldBrush);45:}</PRE><P>In lines 6-12 of Listing C.4, the resources for the print (a font and a brush)are set up. Note that there is a better place to do this, as explained later in thischapter in the section &quot;Adding GDI Objects with OnBeginPrinting().&quot;</P><P>You can use the current page number to draw the different textual content of eachpage by its position in the printed document, as shown in line 17. In a real applicationyou would probably use this page number to reference the document and look up a specificitem of data. In the compact disc scenario mentioned earlier, this page number mightbe used to reference a specific CD, and the drawing functions would then use thatdata. I don't have space to demonstrate anything quite so sophisticated here, soI've just used the current page number from pInfo-&gt;m_nCurPage to illustrate thepoint.</P><P>Lines 22-37 set up a diamond-shaped polygon to draw as the background and line40 draws the text containing the current page in the middle of the page. Lines 43-44reselect the old font and brush.</P><P>If you build and run the program after making these changes to OnPrint() and thenclick the test application File menu and choose Print Preview, you should be ableto preview multiple pages using the Next Page<B> </B>and Prev Page<B> </B>buttonsshown in Figure C.3. If you have a printer attached, you'll also be able to printthe multipage document.</P><P><H3><A NAME="Heading9"></A>Using the Print Dialog Box</H3><P>Notice that when you print a multipage document, you are first presented witha dialog box that enables you to customize the print settings, as shown in FigureC.4. This is the standard Print dialog box and is called from the CView::DoPreparePrinting()function that was called from within the OnPreparePrinting() override. This dialogbox lets you set the page ranges to print, the number of copies, collation flags,the destination printer, and a whole host of things specific to the printer properties.</P><P><A HREF="javascript:popUp('23fig03.gif')"><B>FIGURE C.3.</B></A><B> </B><I>ThePrint Preview output of a multipage document.</I></P><P><A HREF="javascript:popUp('23fig04.gif')"><B>FIGURE C.4.</B></A><B> </B><I>Thestandard Print dialog box.</I></P><BLOCKQUOTE>	<P><HR><B>THE Collate CHECK BOX</B></P>	<P>If the user unchecks the Collate check box on the Print dialog box, the printer	driver will automatically repeat the same pages together. You don't need to do anything	special in your code to handle this--but the feature must be supported by the printer	driver; otherwise it will be disabled and inaccessible in the Print dialog box.<HR></BLOCKQUOTE><P>The user can change the print options from this dialog box, which will then updatethe settings in the CPrintInfo object before it is passed to your application. Youcan customize this dialog box to a small or great degree depending on the amountof customization you require and the work you're prepared to put into the job.</P><P>From the CPrintInfo class members in Table C.1, recall that there is an m_pPDpointer. This points to a CPrintDialog class that is an MFC wrapper class for thePrint dialog box. This class also holds an m_pd member, which is a PRINTDLG structureholding the default settings that are displayed in the Print dialog box. There aremany members of this structure, as shown in Listing C.5. This allows complete customizationof the dialog box defaults, even to the level of specifying a completely differentdialog box template than the default template (if you want a challenge). There isn'tenough space here to describe all these members in detail; one of the more obviousmembers is the nCopies member variable. You could change the default number of copiesdisplayed in this dialog box by setting the nCopies member of this structure directlybefore calling the CView::DoPreparePrinting() function. To do this, add the followingline to your OnPreparePrinting() function:</P><P><PRE>pInfo-&gt;m_pPD-&gt;m_pd.nCopies = 15;</PRE><P>When you open the Print dialog box after adding this line, the number of copieswill default to 15 (if your printer or printer driver supports multiple copies).You can set the other default values in the PRINTDLG accordingly.</P><BLOCKQUOTE>	<P><HR><B> USING THE </B>DevMode<B> STRUCTURE</B><BR>	</P>	<P>The DevMode structure holds many useful attributes that describe the technical	capabilities and configuration of the device. The structure pointer is returned by	the GetDevMode() function in the CPrintDialog class.<HR></BLOCKQUOTE><H4>LISTING C.5.&nbsp;LST23_5.CPP--THE PRINTDLG STRUCTURE.</H4><PRE>1:  typedef struct tagPD {2:  DWORD     lStructSize;3:  HWND      hwndOwner;4:  HANDLE    hDevMode;5:  HANDLE    hDevNames;6:  HDC       hDC;7:  DWORD     Flags;8:  WORD      nFromPage;9:  WORD      nToPage;10:  WORD      nMinPage;11:  WORD      nMaxPage;12:  WORD      nCopies;13:  HINSTANCE hInstance;14:  DWORD     lCustData;15:  LPPRINTHOOKPROC lpfnPrintHook;16:  LPSETUPHOOKPROC lpfnSetupHook;17:  LPCTSTR    lpPrintTemplateName;18:  LPCTSTR    lpSetupTemplateName;19:  HANDLE    hPrintTemplate;20:  HANDLE    hSetupTemplate;21:  } PRINTDLG;</PRE><P>After the user has confirmed OK in the Print dialog box, you can retrieve thechanges by using the CPrintDialog class access functions shown in Table C.2. So ifyou wanted to find the number of copies specified by the user before printing, youcould catch the value after it is returned from the CView::DoPreparePrinting() function,as shown in Listing C.6.</P><P>Obviously, any of the values in the PRINTDLG structure pInfo-&gt;m_pPD-&gt;m_pdcan be tested here also.</P><P><H4>TABLE C.2.&nbsp;CPrintDialog ACCESS FUNCTIONS.</H4><P><TABLE BORDER="1">	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT"><I>Function Name</I></TD>		<TD ALIGN="LEFT"><I>Description</I></TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">GetCopies()		</TD>		<TD ALIGN="LEFT">Returns the number of copies set by the user		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">GetFromPage()		</TD>		<TD ALIGN="LEFT">Returns the starting page as specified		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">GetToPage()		</TD>		<TD ALIGN="LEFT">Returns the last page as specified		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">GetPortName()		</TD>		<TD ALIGN="LEFT">Returns the selected printer port, for example, LPT1:		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">GetDriverName()		</TD>		<TD ALIGN="LEFT">Returns the selected print driver (destination printer)		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">GetPrinterDC()		</TD>		<TD ALIGN="LEFT">Returns a device context for the printer		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">PrintAll()		</TD>		<TD ALIGN="LEFT">Returns TRUE if all pages are selected		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">PrintCollate()		</TD>		<TD ALIGN="LEFT">Returns TRUE if collation is required		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">PrintRange()		</TD>		<TD ALIGN="LEFT">Returns TRUE if a range is specified		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">PrintSelection()		</TD>		<TD ALIGN="LEFT">Returns TRUE if a specific selection of pages is chosen		</TD>	</TR></TABLE><H4>LISTING C.6.&nbsp;&nbsp;LST23_6.CPP--VALIDATING THE STANDARD PRINT DIALOG BOXFOR A SPECIFIC NUMBER OF COPIES.</H4><PRE>1:  BOOL CPrintItView::OnPreparePrinting(CPrintInfo* pInfo)2:  {3:      pInfo-&gt;SetMinPage(1);4:      pInfo-&gt;SetMaxPage(10);5:6:      pInfo-&gt;m_pPD-&gt;m_pd.nCopies = 3;7:8:      do9:      {10:          // ** Check if user has cancelled print11:          if (DoPreparePrinting(pInfo) == FALSE)12:              return FALSE;13:14:          // ** Warn the user if too many copies             &Acirc;are specified15:          if (pInfo-&gt;m_pPD-&gt;GetCopies()&gt;5)16:              AfxMessageBox(&quot;Please choose less than                 &Acirc;5 copies&quot;);17:18:          // ** Keep looping until they specify a               &Acirc;valid number19:      } while(pInfo-&gt;m_pPD-&gt;GetCopies()&gt;5);20:      return TRUE;21:  }</PRE><P>In Listing C.6 the CView::DoPreparePrinting() returns FALSE if the user has pressedCancel in lines 11 and 12. Otherwise, the number of copies set is checked in line15, and a warning is issued if more than five copies have been selected (my arbitrarycriteria). The loop is repeated at line 19 until the user enters a valid number ofcopies or presses Cancel.</P><P><H3><A NAME="Heading10"></A>Using Portrait and Landscape Orientations</H3><P>If you click the File menu from the application and choose the Print Setup option,you can change the printer's orientation defaults. You can choose either Portraitor Landscape from the dialog. You don't need to make any code changes to handle Landscapeprinting; if you choose this option and then run a print preview, you should noticethat the device context is now drawn to the shape of the paper turned on its side.As long as your application takes note of the rectDraw member of the CPrintInfo object,it should be able to cope with landscape printing automatically.</P><P><H3><A NAME="Heading11"></A>Adding GDI Objects with OnBeginPrinting()</H3>

⌨️ 快捷键说明

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