按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
#07 bAbort = FALSE;
#08
#09 Escape(hPr; STARTDOC; 4; 〃PrntFile text〃; (LPSTR) NULL);
#10
#11 // 设定Printing 对话框及其窗口函数
#12 lpPrintingDlg = MakeProcInstance(PrintingDlg; hInst);
#13 hPrintingDlgWnd = CreateDialog(hInst; 〃PrintingDlg〃; hWnd; lpPrintingDlg);
#14 ShowWindow (hPrintingDlgWnd; SW_NORMAL);
#15 EnableWindow(hWnd; FALSE); // 令其父窗口 (也就是程序的主窗口) 除能
#16 SetCursor(hSaveCursor); // 鼠标光标形状还原
#17
#18 GetTextMetrics(hPr; &TextMetric);
#19 LineSpace = TextMetric。tmHeight + TextMetric。tmExternalLeading;
#20 nPageSize = GetDeviceCaps (hPr; VERTRES);
#21 LinesPerPage = nPageSize / LineSpace 1;
#22 dwLines = SendMessage(hEditWnd; EM_GETLINECOUNT; 0; 0L);
#23 CurrentLine = 1;
#24
#25 for (dwIndex = IOStatus = 0; dwIndex 《 dwLines; dwIndex++) {
#26 pLine'0' = 128;
#27 pLine'1' = 0;
#28 LineLength = SendMessage(hEditWnd; EM_GETLINE;
#29 (WORD)dwIndex; (LONG)((LPSTR)pLine));
#30 TextOut(hPr; 0; CurrentLine*LineSpace; (LPSTR)pLine; LineLength);
#31 if (++CurrentLine 》 LinesPerPage ) {
#32 CurrentLine = 1;
#33 IOStatus = Escape(hPr; NEWFRAME; 0; 0L; 0L);
#34 if (IOStatus= 0 && !bAbort) {
#40 Escape(hPr; NEWFRAME; 0; 0L; 0L);
#41 Escape(hPr; ENDDOC; 0; 0L; 0L);
#42 }
668
…………………………………………………………Page 731……………………………………………………………
第 12 章 列印與預樱А�
#43
#44 EnableWindow(hWnd; TRUE);
#45
#46 DestroyWindow(hPrintingDlgWnd);
#47 FreeProcInstance(lpPrintingDlg);
#48 FreeProcInstance(lpAbortProc);
#49 DeleteDC(hPr);
上述各个Escape 调用,是在Windows 3。0 下的传统作法,在Windows 3。1 以及Win32 之
中有对应的API 函数如下:
Windows 3。0 作法 Windows 3。1 作法
Escape(hPr; SETABORTPROC; 。。。) SetAbortProc(HDC hdc; ABORTPROC lpAbortProc)
Escape(hPr; STARTDOC; 。。。) StartDoc(HDC hdc; CONST DOCINFO* lpdi)
Escape(hPr; NEWFRAME; 。。。) EndPage(HDC hdc)
Escape(hPr; ENDDOC; 。。。) EndDoc(HDC hdc)
MFC 预设的打印机制
好啦,关于打印,其实有许多一成不变的动作!为什么开发工具不帮我们做掉呢?好比
说,从WIN。INI 中取得目前打印机的资料然后利用CreateDC 取得打印机DC ,又好比
说设计标准的【打印中】对话框,以及标准的打印中断函数AbortProc 。
事实上MFC 的确已经帮我们做掉了一大部份的工作。MFC 已内含打印机制,那么将
Framework 整个纳入EXE 文件中的你当然也就不费吹灰之力得到了打印功能。只要
OnDraw 函数设计好了,不但可以在屏幕上显示资料,也可以在打印机上显示资料。有
什么是我们要负担的?没有了!Framework 传给OnDraw 一个DC ,视情况的不同这个
DC 可能是显示屏DC ,也可能是打印机DC ,而你知道,Windows 程序中的图形输出
对象完全取决于DC :
669
…………………………………………………………Page 732……………………………………………………………
第篇 深入 MFC 程式設計
当你改变窗口大小,产生WM_PAINT ,OnDraw 会收到一个「显示屏DC 」。
当你选按【File/Print。。。 】,OnDraw 会收到一个「打印机DC 」。
数章之前讨论CView 时我曾经提过,OnDraw 是CView 类别中最重要的成员函数,所
有的绘图动作都应该放在其中。请注意,OnDraw 接受一个「CDC 对象指针」做为它的
参数。当窗口接受WM_PAINT 消息,Framework 就调用OnDraw 并把一个「显示屏DC 」
传过去,于是OnDraw 输出到屏幕上。
Windows 的图形装置接口(GDI )完全与硬件无关,相同的绘图动作如果送到「显示屏
DC 」,就是在屏幕上绘图,如果送到「打印机DC 」,就是在打印机上绘图。这个道理
很容易就解释了为什么您的程序代码没有任何特殊动作却具备打印功能:当使用者按下
【File/Print 】,application framework 送给OnDraw 的是一个「打印机DC 」而不再是「显
示幕DC 」。
在MFC 应用程序中,View 和application framework 分工合力完成打印工作。Application
framework 的责任是:
显示【Print 】对话框,如图12…1b。
为打印机产生一个CDC 对象。
调用CDC 对象的StartDoc 和EndDoc 两函数。
持续不断地调用CDC 对象的StartPage ,通知View 应该输出哪一页;一页打印
完毕则调用CDC 对象的EndPage 。
我们(程序员)在View 对象上的责任是:
通知application framework 总共有多少页要打印。
application framework 要求打印某特定页时,我们必须将Document 中对应的部
份输出到打印机上。
配置或释放任何GDI 资源,包括笔、刷、字形。。。等等。
如果需要,送出任何escape 码改变打印机状态,例如走纸、改变打印方向等等。
670
…………………………………………………………Page 733……………………………………………………………
第 12 章 列印與預樱А�
送出escape 码的方式是,调用CDC 对象的Escape 函数。
现在让我们看看这两组工作如何交叉在一起。为实现上述各项交互动作,CView 定义了
几个相关的成员函数,当你在AppWizard 中选择【Printing and Print Preview 】选项之后,
除了OnDraw,你的View 类别内还被加入了三个虚拟函数空壳:
// in SCRIBBLEVIEW。H
class CScribbleView : public CScrollView
{
。。。
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC; CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC; CPrintInfo* pInfo);
。。。
};
// in SCRIBBLEVIEW。CPP
BOOL CScribbleView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CScribbleView::OnBeginPrinting(CDC* /*pDC*/; CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CScribbleView::OnEndPrinting(CDC* /*pDC*/; CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
改写这些函数有助于我们在framework 的打印机制与应用程序的View 对象之间架起
沟通桥梁。
为了了解MFC 中的打印机制,我又动用了我的法宝:Visual C++ Debugger 。我发现,
AppWizard 为我的View 做出这样的Message Map :
671
…………………………………………………………Page 734……………………………………………………………
第篇 深入 MFC 程式設計
BEGIN_MESSAGE_MAP(CScribbleView; CScrollView)
。。。
// Standard printing mands
ON_MAND(ID_FILE_PRINT; CView::OnFilePrint)
ON_MAND(ID_FILE_PRINT_PREVIEW; CView::OnFilePrintPreview)
END_MESSAGE_MAP()