按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
Y 值(这是从装置坐标,也就是MM_TEXT ,的眼光来看) ;如果事非如此,它
根本不可能找出两个四方形的交集。因此我们必须在OnDraw 中做以下修改,
把逻辑坐标改为装置坐标:
void CScribbleView::OnDraw(CDC* pDC)
{
CScribbleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// Get the invalidated rectangle of the view; or in the case
// of printing; the clipping region of the printer dc。
CRect rectClip;
CRect rectStroke;
pDC…》GetClipBox(&rectClip);
pDC…》LPtoDP(&rectClip);
rectClip。InflateRect(1; 1); // avoid rounding to nothing
// Note: CScrollView::OnPaint() will have already adjusted the
// viewport origin before calling OnDraw(); to reflect the
// currently scrolled position。
// The view delegates the drawing of individual strokes to
// CStroke::DrawStroke()。
CTypedPtrList& strokeList = pDoc…》m_strokeList;
POSITION pos = strokeList。GetHeadPosition();
while (pos != NULL)
{
CStroke* pStroke = strokeList。GetNext(pos);
rectStroke = pStroke…》GetBoundingRect();
692
…………………………………………………………Page 755……………………………………………………………
第 12 章 列印與預樱А�
pDC…》LPtoDP(&rectStroke);
rectStroke。InflateRect(1; 1); // avoid rounding to nothing
if (!rectStroke。IntersectRect(&rectStroke; &rectClip))
continue;
pStroke…》DrawStroke(pDC);
}
}
分页
Scribble 程序的Document 大小固定是800x900,而且我们让它填满打印机的一页。因
此Scribble 并没有「将Document 分段打印」这种困扰。如果真要分段打印,Scribble 应
该改写OnPrepareDC,在其中视打印的页数调整DC 的原点和截割区域。
即便如此,Scribble 还是在分页方面加了一些动作。本例一份Document 打印时被视为
一张标题和一张图片的组合,因此打印一份Document 固定要耗掉两张打印纸。我们可
以这么设计:
BOOL CScribbleView::OnPreparePrinting(CPrintInfo* pInfo)
{
pInfo…》SetMaxPage(2); //文件总共有两页经线:
//第一页是标题页 (title page)
//第二页是文件页 (图形)
BOOL bRet = DoPreparePrinting(pInfo); // default preparation
pInfo…》m_nNumPreviewPages = 2; // Preview 2 pages at a time
// Set this value after calling DoPreparePrinting to override
// value read from 。INI file
return bRet;
}
接下来打算设计一个函数用以输出标题页,一个函数用以输出文件页。后者当然应该由
OnDraw 负责# 蛭U 馕募th页不是单纯的Document 内容,还有所谓的表头,而这
是打印时才做的东西,屏幕显示时并不需要的,所以我们希望把列打印头的工作独立于
OnDraw 之外,那么最好的安置地点就是OnPrint 了(请参考图12…5 之后的补充说明
的最后一点)。
693
…………………………………………………………Page 756……………………………………………………………
第篇 深入 MFC 程式設計
Scribble Step5 把列打印头的工作独立为一个函数。总共这三个额外的函数应该声明于
SCRIBBLEVIEW。H 中,其中的PrintPageHeader 在下一节列出。
class CScribbleView : public CScrollView
{
public:
virtual void OnPrint(CDC* pDC; CPrintInfo* pInfo);
void PrintTitlePage(CDC* pDC; CPrintInfo* pInfo);
void PrintPageHeader(CDC* pDC; CPrintInfo* pInfo; CString& strHeader);
。。。
}
#0001 void CScribbleView::OnPrint(CDC* pDC; CPrintInfo* pInfo)
#0002 {
#0003 if (pInfo…》m_nCurPage == 1) // page no。 1 is the title page
#0004 {
#0005 PrintTitlePage(pDC; pInfo);
#0006 return; // nothing else to print on page 1 but the page title
#0007 }
#0008 CString strHeader = GetDocument()…》GetTitle();
#0009
#0010 PrintPageHeader(pDC; pInfo; strHeader);
#0011 // PrintPageHeader() subtracts out from the pInfo…》m_rectDraw the
#0012 // amount of the page used for the header。
#0013
#0014 pDC…》SetWindowOrg(pInfo…》m_rectDraw。left;…pInfo…》m_rectDraw。top);
#0015
#0016 // Now print the rest of the page
#0017 OnDraw(pDC);
#0018 }
#0019
#0020 void CScribbleView::PrintTitlePage(CDC* pDC; CPrintInfo* pInfo)
#0021 {
#0022 // Prepare a font size for displaying the file name
#0023 LOGFONT logFont;
#0024 memset(&logFont; 0; sizeof(LOGFONT));
#0025 logFont。lfHeight = 75; // 3/4th inch high in MM_LOENGLISH
#0026 // (1/100th inch)
#0027 CFont font;
#0028 CFont* pOldFont = NULL;
#0029 if (font。CreateFontIndirect(&logFont))
#0030 pOldFont = pDC…》SelectObject(&font);
#0031
#0032 // Get the file name; to be displayed on title page
#0033 CString strPageTitle = GetDocument()…》GetTitle();
694
…………………………………………………………Page 757……………………………………………………………
第 12 章 列印與預樱А�
#0034
#0035 // Display the file name 1 inch below top of the page;
#0036 // centered horizontally
#0037 pDC…》SetTextAlign(TA_CENTER);
#0038 pDC…》TextOut(pInfo…》m_rectDraw。right/2; …100; strPageTitle);
#0039
#0040 if (pOldFont != NULL)
#0041 pDC…》SelectObject(pOldFont);
#0042 }
表头与页尾
文件名称以及文件内容的页码应该有地方呈现出来。屏幕上没有问题,文件名称可以出
现在窗口标题,页码可以出现在状态列;但输出到打印机上时,我们就应该设计文件的
表头与页尾,分别用来放置文件名称与页码,或其它任何你想要放的资料。显然,即使
是「所见即所得」,在打印机输出与屏幕输出两方面仍然存在至少这样的差异。
我们设计了另一个辅助函数,专门负责列打印头,并将OnPrint 的参数(一个打印机DC )
传给它。有一点很容易被忽略,那就是你必得在OnPrint 调用OnDraw 之前调整窗口的
原点和范围,以避免该页的主内容把表头页尾给盖掉了。
要补偿被表头页尾占据的空间,可以利用CPrintInfo 结构中的m_rectDraw ,这个字段
记录着本页的可绘图区域。我们可以在输出主内容之前先输出表头页尾,然后扣除
m_rectDraw 四方形的一部份,代表表头页尾所占空间。OnPrint 也可以根据m_rectDraw
的数值决定有多