友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

深入浅出MFC第2版(PDF格式)-第91部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!



         CString GetDeviceName() const;  // return device name 

         CString GetPortName() const;    // return output port name 

         HDC GetPrinterDC() const;       // return HDC (caller must delete) 

         HDC CreatePrinterDC(); 

         。。。 

 }; 



  如果必要(从命令列参数中得知要直接打印某个文件到打印机上),利用::CreateDC 



   产生一个「打印机DC 」,并做打印动作。注意,printInfo 。m_bDirect 被设为TRUE,表 



   示跳过打印对话框,直接打印。 



                                                                                      677 


…………………………………………………………Page 740……………………………………………………………

                      第篇    深入  MFC  程式設計    



                       OnPreparePrinting 是一个虚拟函数,所以如果CView 的衍生类别改写了它,控制权 



                        就移转到衍生类别手中。本例将移转到CScribbleView 手中。 



                        CScribbleView::OnPreparePrinting 的预设内容(AppWizard  自动为我们产生)是调用 



                        DoPreparePrinting ,它并不是虚拟函数,而是CView 的一个辅助函数。以下是其调用堆 



                        叠,直至【打印】对话框出现为止。 



                            CView::OnFilePrint 

                            CView::OnFilePrint   (in VIEWPRNT。CPP) 



                                CScribbleView::OnPreparePrinting     (in SCRIBVW。CPP) 

                                 CScribbleView::OnPreparePrinting 



                                      CView::DoPreparePrinting     (in VIEWPRNT。CPP) 

                                       CView::DoPreparePrinting 



                                            CWinApp::DoPrintDialog    (in APPPRNT。CPP) 

                                             CWinApp::DoPrintDialog 



                                                 CWinApp::UpdatePrinterSelection      (in APPPRNT。CPP) 

                                                  CWinApp::UpdatePrinterSelection 



                                                       CPrintDialog::GetDefaults   (in DLGPRNT。CPP) 

                                                        CPrintDialog::GetDefaults 



                                                             ::PrintDlg  (Win32 API) 

                                                              ::PrintDlg 



                                                 CPrintDialog::DoModal     (in DLGPRNT。CPP) 

                                                  CPrintDialog::DoModal 



                                                       ::PrintDlg   (Win32 API) 

                                                        ::PrintDlg 



                      CView::DoPreparePrinting 将贮存在CPrintInfo 结构中的对话框CPrintDialog* m_pPD 



                      显示出来,借此收集使用者对打印机的各种设定,然后产生一个「打印机DC 」,储存在 



                     printinfo。m_pPD…》m_pd。hDC  之中。 



                       如果使用者在【打印】对话框中选按【打印到文件】,则再显示一个【Print to File 】 



                         对话框,让使用者设定档名。 



678 


…………………………………………………………Page 741……………………………………………………………

                                                             第 12 章    列印與預樱А�



 接下来取文件名称和输出设备的名称(可能是打印机也可能是个文件),并产生一个 



  DOCINFO  结构,设定其中的lpszDocName 和lpszOutput 字段。此一DOCINFO  结构 



  将在稍后的StartDoc 动作中用到。 



 如果使用者在【打印】对话框中按下【确定】钮,OnFilePrint 就在堆栈中制造出一 



   个CDC 对象,并把前面所完成的「打印机DC 」附着到CDC 对象上: 



    CDC dcPrint; 

    dcPrint。Attach(printInfo。m_pPD…》m_pd。hDC); 

    dcPrint。m_bPrinting = TRUE; 



 一旦CDC 完成, OnFilePrint 把CDC 对象以及前面的CPrintInfo 对象传给 



  OnBeginPrinting 作为参数。OnBeginPrinting 是CView 的一个虚拟函数,原本什么也没 



  做。你可以改写它,设定打印前的任何初始状态。 



 设定AbortProc 。这应该是一个callback 函数,MFC 有一个预设的简易函数 



   _AfxAbortProc  可兹利用。 



             CView::OnFilePrint (in VIEWPRNT。CPP) 

              CView::OnFilePrint 



                  CDC::SetAbortProc   (macro; defined in AFXWIN1。INL) 

                   CDC::SetAbortProc 



                        ::SetAbortProc  (Win32 API) 

                         ::SetAbortProc 



                                                                                    679 


…………………………………………………………Page 742……………………………………………………………

                   第篇    深入  MFC  程式設計    



                    把父窗口除能,产生【打印状态】对话框,根据文件名称以及输出设备名称,设定对 



                      话盒内容,并显示之: 



                       AfxGetMainWnd()…》EnableWindow(FALSE); 

                       CPrintingDialog dlgPrintStatus(this); 

                       。。。 //设定对话框内容 

                       dlgPrintStatus。ShowWindow(SW_SHOW); 

                       dlgPrintStatus。UpdateWindow(); 



                         CView::OnFilePrint  (in VIEWPRNT。CPP) 

                         CView::OnFilePrint 



                              CPrintingDialog::CPrintingDialog (in VIEWPRNT。CPP) 

                              CPrintingDialog::CPrintingDialog 



                                   CDialog::Create (产生对话框) 

                                    CDialog::Create 



                              CWnd::ShowWindow     (显示对话框) 

                              CWnd::ShowWindow 



                    StartDoc 通知打印机开始崭新的打印工作。这个函数其实就是激活Windows 打印引擎。 



                         CView::OnFilePrint 

                         CView::OnFilePrint (in VIEWPRNT。CPP) 



                              CDC::StartDoc    (macro; defined in AFXWIN1。INL) 

                               CDC::StartDoc 



                                    ::StartDoc (Win32 API) 

                                     ::StartDoc 



                    以for  循环针对文件中的每一页开始做打印动作。 



                    调用CView::OnPrepareDC。此函数什么也没做。如果你要在每页前面加表头,就请 



                      改写这个虚拟函数。 



                     修改【打印状态】对话框中的页次。 



                    StartPage 开始新的一页。 



680 


…………………………………………………………Page 743……………………………………………………………

                                                                         第 12 章    列印與預樱А�



      CView::OnFilePrint 

       CView::OnFilePrint 



            CDC::StartPage      (macro; defined in AFXWIN1。INL) 

             CDC::StartPage 



                   ::StartPage     (Win32 API) 

                    ::StartPage 



⑤ 调用CView::OnPrint ,它的内部只有一个动作:调用OnDraw 。我们应该在 



    CScribbleView 中改写OnDraw  以绘出自己的图形。 



      CView ::OnFilePrint 

       CView ::OnFilePrint 



            CView ::OnPrint 

             CView ::OnPrint 



                    CScribbleView ::OnDraw        (我们应该改写OnDraw 以绘出自己的图形) 

                    CScribbleView ::OnDraw 



 一页结束,调用一页结束,调用dcPrintdcPrint。。EndPageEndPage 



      CView ::OnFilePrint 

       CView ::OnFilePrint 



            CDC::EndPage         (macro; defined in AFXWIN1。INL) 

             CDC::EndPage 



                     ::EndPage     (Win32 API) 

                     ::EndPage 



 文件结束,调用EndDoc 



      CView::OnFilePrint 

       CView::OnFilePrint 



             CDC::EndDoc 

             CDC::EndDoc       (macro; defined in AFXWIN1。INL) 



                     ::EndDoc    (Win32 API) 

                      ::EndDoc 



 整个打印工作结束。如果有些什么绘图资源需要释放,你应该改写OnEndPrinting 函 



   式并在其中释放之。 



      CView::OnFilePrint 

       CView::OnFilePrint 



             CScribbleView::OnEndPrinting 

             CScribbleView::OnEndPrinting 



                                                                                                      681 


…………………………………………………………Page 744……………………………………………………………

                   第篇    深入  MFC  程式設計    



                     去除【打印状态】对话框。 



                      将「打印机DC 」解除附着,CPrintInfo 的析构式会把DC 还给Windows 。 



                       从上面这些分析中归纳出来的结论是,一共有六个虚拟函数可以改写,请看图12…5。 



                     Framework 调用次序              建议改写项目 



                     CMyView::OnPreparePrinting   设定Document 长度。调用CView::DoPreparePrinting 以显示 

                     CMyView::OnPreparePrinting   【Print】对话框并产生打印机DC。 



                     CMyView::OnBeginPrinting     设定以DC 为准的Document 长度;配置GDI 资源 

                     CMyView::OnBeginPrinting 



                     CDC::StartDoc 

                     CDC::StartDoc 



                     CMyView::OnPrepareDC         改变viewport 原点、剪截区、以及其它DC 属性。 

                     CMyView::OnPrepareDC 



                     CDC::StartPage 

                     CDC::StartPage 



                     CMyView::OnPrint  列打印头、页尾等等 

                     CMyView::OnPrint 



                                           CMyView::OnDraw      GDI 绘图动作 

                                            CMyView::OnDraw 

                     CDC::EndPage 

                     CDC::EndPage 



                     CDC::EndDoc 

                     CDC::EndDoc 



                     CMyView::OnEndPrinting    释放GDI 资源 

                     CMyView::OnEndPrinting 



                      图12…5 MFC 打印流程与我们的着力点 



682 


…………………………………………………………Page 745……………………………………………………………

                                                    第 12 章    列印與預樱А�



以下是图12…5 的补充说明。 



 ■当使用者按下【File/Print  】命令项, Application Framework 首先调用 



  CMyView::OnPreparePrinting 。这个函数接受一个CPrintInfo 指针做为参数,允许 



  使用者设定Document  的打印长度(从第几页到第几页)。预设页码是1 至 



  0xFFFF , 程序员应该在OnPreparePrinting 中调用SetMaxPage 预设页数。 



  SetMaxPage 之后,程序应该调用CView::DoPreparePrinting ,它会显示【打印】 



  对话框,并产生一个打印机DC 。当对话框结束,CPrintInfo 也从中获得了使用 



  者设定的各个打印项目(例如从第n1 页印到第n2 页) 。 



  Framework 如何得知使用者对于打印状态的设定?CPrintInfo 有五个函数可用,下一 



  节有更详细的说明。 



 ■针对每一页,Framework 会调用CMyView::OnPrepareDC,这函数在前一章介绍 



  CScrollView 时也曾提过,当时是因为我们使用卷动窗口,而由于卷动的关系, 



  绘图之前必须先设定DC  的映射模式和原点等性质。这次稍有不同的是,它收 



  到打印机DC 做为第一参数,CPrintInfo 对象做为第二参数。我们改写这个函 



  式,使它依目前的页码来调整DC ,例如改变打印原点和截割区域以保证印出 



  来的Document  内容的合适性等等。 



 ■稍早我一再强调所有绘图动作都应该集中在OnDraw 函数中,Framework 会自 



  动调用它。更精确地说,Framework 其实是先调用OnPrint,传两个参数进去, 



  第一参数是个DC , 第二参数是个CPrintInfo 指针。OnPrint  内部再调用 



   OnDraw,这次只传DC 过去,做为唯一参数: 



   // in VIEWCORE。CPP 



  void CView::OnPrint(CDC* pDC; CPrintInfo*) 



   { 



      ASSERT_VALID(pDC); 



      // Override and set printing variables based on page number 



       OnDraw(pDC); // Call Draw 



   } 



                                                                        683 


…………………………………………………………Page 746……………………………………………………………

                 第篇    深入  MFC  程式設計    



                 有了这样的差异,我们可以这么区分这两个函数的功能: 



                     z  OnPrint:负责「只在打印时才做(屏幕显示时不做)」的动作。例如印出 



                        表头和页尾。 



                     z  OnDraw :共通性绘图动作(包括输出到屏幕或打印机上)都在此完成。 



                 看看另一个函数OnPaint: 



                 // in VIEWCORE。CPP 

                 void CView::OnPaint() 

                 { 

                         // standard paint routine 

                         CPaintDC dc(this); 

                         OnPrepareDC(&dc); 

                         OnDraw(&dc); 

                 } 



                 你会发现原来它们是这么分工的: 



                  WM_MAND  

                                    CView::OnPrint 唯「打印」才有之工作,将在此进行 

                  (ID_FILE_PRI NT)  CView::OnPrint 



                                              CView::OnDraw 「打印」与「显示」共通的 

                                              CView::OnDraw 

                                                            工作,在此进行 



                   WM_ PA INT      CView ::OnPaint 唯「显示」才有的工作,将在此进行 

                                    CView::OnPaint 



                 所谓「显示」是指输出到屏幕上,「打印」是指输出到打印机上。 



                由同一函数完成显示(display )与打印(print )动作,才能够达到「所见即所得」(What 



                You See Is What You Get ,WYSIWYG )的目的。如果你不需要一个WYSIWYG 程序, 



                可以改写OnPrint 使它不要调用OnDraw,而调用另一个绘图例程。 



                 不要认为什么情况下都需要WYSIWYG 。一个文字编辑器可能使用粗体字打印但使用控 



                 制码在屏幕上代表这粗体字。 



684 


…………………………………………………………Page 747……………………………………………………………

                                               第 12 章    列印與預樱А�



Scribble 打印机制的增强 



    MFC 预设的打印机制够聪敏了,但还没有聪敏到解决所有的问题。这些问题包括: 



     ■打印出来的影像可能不是你要的大小 



     ■不会分页 



     ■没有表头(header ) 



     ■没有页尾(footer ) 



    毕竟屏幕输出和打印机输出到底还是有着重大的差异。窗口有卷动杆而打印机没有,这 



    伴随而来的就是必须计算Document  的大小和纸张的大小,以解决分页的问题;此外, 



    我们必须想想,在MFC 预设的打印机制中,改写哪一个地方,才能让我们有办法在 



    Document  的输出页加上表头或页尾。 



 打印机的页和文件的页 



    首先,我们必须区分「页」对于Document 和对于打印机的不同意义。从打印机观点来 



    看,一页就是一张纸,然而一张纸并不一定容纳Document  的一页。例如你想印一些通 



    讯资料,这些资料可能是要被折叠起来的,因此一张纸印的是Document  的第一页和最 



    后一页(亲爱的朋友,想想你每天看的报纸)。又例如印一个巨大的电子表格,它可能是 



    Document 上的一页,却占据两张A4 纸。 



    MFC 这个Application Framework 把关于打印的大部份信息都记录在CPrintInfo 中,其 



    中数笔资料与分页有密切关系。下表是取得分页资料的相关成员,其中只有SetMaxPage 



    和m_nCurPage 和m_nNumPreviewPages 在Scribble 程序中会用到,原因是Scribble 



    程序对许多问题做了简化。 



                                                                685 


…………………………………………………………Page 748……………………………………………………………

                第篇    深
返回目录 上一页 下一页 回到顶部 赞(9) 踩(10)
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!