友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

深入浅出MFC第2版(PDF格式)-第221章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






                  其中前三个参数分别是与打印机有关的信息字符串,可以从WIN。INI  的【windows 】section 



                  中获得,各以逗号分隔,例如: 



                      device=HP LaserJet 4P/4MP;HPPCL5E;LPT1: 



                  代表三项意义: 



                     Print Driver = HP LaserJet 4P/4MP 



                     Print Type = HPPCL5E 



                     Print Port = LPT1: 



                   SDK 程序中对于打印所需做的努力,最低限度到此为止。显然,困难度并不高,但是其 



                   中尚未参杂对打印机的控制,而那是比较麻烦的事儿。换句话说我们还得考虑「分页」 



                   的问题。以文字为例,我们必须取得一页(一张纸)的大小,以及字形的高度,从而计 



                   算扣除留白部份之后,一页可容纳几行: 



                      TEXTMETRIC TextMetric; 

                      int LineSpace; 

                      int nPageSize; 

                      int LinesPerPage; 



                      GetTextMetrics(hPr; &TextMetric);  //取得字形数据 

                      LineSpace = TextMetric。tmHeight + TextMetric。tmExternalLeading; // 计算字高 

                      nPageSize = GetDeviceCaps(hPr; VERTRES);  // 取得纸张大小 

                      LinesPerPage = nPageSize / LineSpace 1; // 一页容纳多少行 



                    然后再以循环将每一行文字送往打印机: 



                       Escape (hPr; STARTDOC; 4; 〃PrntFile text〃; (LPSTR) NULL); 

                       CurrentLine = 1; 

                       for (。。。) { 

                           。。。 // 取得一行文字,放在char pLine'128' 中,长度为LineLength。 



664 


…………………………………………………………Page 727……………………………………………………………

                                                                 第 12 章    列印與預樱А�



        TextOut (hPr; 0; CurrentLine*LineSpace; (LPSTR)pLine; LineLength); 

        if (++CurrentLine 》 LinesPerPage ) { 

            CurrentLine = 1;   //重设行号 

            IOStatus = Escape (hPr; NEWFRAME; 0; 0L; 0L);  //换页 

            if (IOStatus 《 0 || bAbort) 

                break; 

        } 

    } 

    if (IOStatus 》= 0 && !bAbort) { 

        Escape (hPr; NEWFRAME; 0; 0L; 0L); 

        Escape (hPr; ENDDOC; 0; 0L; 0L); 

    } 



    其中的Escape 用来传送命令给打印机(打印机命令一般称为escape code ),它是一个 



    Windows API  函数。 



    打印过程中我们还应该提供一个中断机制给使用者。Modeless 对话框可以完成此一使 



    命,我们可以让它出现在打印过程之中。这个对话框应该在打印程序开始之前先做起来, 



    外形类似图12…1d: 



    HWND hPrintingDlgWnd;  // 这就是【Printing】对话框 

    FARPROC lpPrintingDlg; // 【Printing】对话框的窗口函数 



    lpPrintingDlg =  MakeProcInstance(PrintingDlg; hInst); 

    hPrintingDlgWnd = CreateDialog (hInst; 〃PrintingDlg〃; hWnd; lpPrintingDlg); 

    ShowWindow (hPrintingDlgWnd; SW_NORMAL); 



    负责此一中断机制的对话框函数很简单,只检查【OK 】钮有没有被按下,并据以改变 



    bAbort  的值: 



    int FAR PASCAL PrintingDlg (HWND hDlg; unsigned msg; WORD wParam; LONG lParam) 

    { 

        switch(msg) { 

            case WM_MAND: 

                return (bAbort = TRUE); 



            case WM_INITDIALOG: 

                SetFocus(GetDlgItem(hDlg; IDCANCEL)); 

                SetDlgItemText(hDlg; IDC_FILENAME; FileName); 

                return (TRUE); 

            } 

        return (FALSE); 

    } 



                                                                                          665 


…………………………………………………………Page 728……………………………………………………………

                第篇    深入  MFC  程式設計    



                 从应用程序的眼光来看,这样就差不多了。然而资料真正送到打印机上,还有一大段曲 



                 折过程。每一个送往打印机DC  的绘图动作,其实都只被记录为metafile                (注)储存在 



                 你的TEMP  目录中。当你调用Escape(hPr ; NEWFRAME; 。。。),打印机驱动程序(。DRV) 



                 会把这些metafile 转换为打印机语言(control sequence 或Postscript ),然后通知GDI 模 



                 组,由GDI 把它储存为~SPL 文件,也放在TEMP  目录中,并删除对应之metafile 。之 



                 后,GDI 模块再送出消息给打印管理器Print Manager ,由后者调用Openm、 



                 Writem 等低阶通讯函数(也都是Windows API  函数),把打印机命令传给打印机。 



                 整个流程请参考图12…3。 



                 注:metafile 也是一种图形记录规格,但它记录的是绘图动作,不像bitmap 记录的是真 



                 正的图形资料。所以播放metafile  比播放bitmap 慢,因为多了一层绘图函数解读动作; 



                 但它的大小比bitmap 小很多。用在有许多四形、圆形、工程几何图形上最为方便。 



                 这个曲折过程之中就产生了一个问题。~SPL 这种文件很大,如果你的TEMP  目录空间 



                 不够充裕,怎么办?如果Printer Manager 把积存的~SPL  内容消化掉后能够空出足够磁 



                 碟空间的话,那么GDI 模块就可以下命令(送消息)给Printer Manager ,先把积存的 



                 ~SPL 档处理掉。问题是,在Windows 3。x 之中,我们的程序此刻正忙着做绘图动作, 



                 GDI 没有机会送消息给Printer Manager  (因为Windows 3。x 是个非强制性多任务系统) 。 



                 解决方法是你先准备一个callback 函数,名称随你取,通常名为AbortProc : 



                    FARPROC lpAbortProc; 



                    lpAbortProc = MakeProcInstance(AbortProc; hInst); 



                    Escape(hPr; SETABORTPROC; NULL; (LPSTR)(long)lpAbortProc; (LPSTR)NULL); 



                 GDI 模块在执行Escape(hPr ; NEWFRAME。。。) 的过程中会持续调用这个callback 函数,想 



                 办法让你的程序释放出控制权: 



                    int FAR PASCAL AbortProc(hDC hPr; int Code) 



                    { 



                     MSG msg; 



                      while (!bAbort && PeekMessage(&msg; NULL; NULL; NULL; TRUE)) 



                         if (!IsDialogMessage(hAbortDlgWnd; &msg)) { 



                              TranslateMessage(&msg); 



666 


………………………………………………
返回目录 上一页 下一页 回到顶部 赞(1) 踩(1)
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!