按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
for (int i=1; i 《 m_pointArray。GetSize(); i++)
{
pt = m_pointArray'i';
m_rectBounding。left = min(m_rectBounding。left; pt。x);
m_rectBounding。right = max(m_rectBounding。right; pt。x);
m_rectBounding。top = min(m_rectBounding。top; pt。y);
m_rectBounding。bottom = max(m_rectBounding。bottom; pt。y);
}
m_rectBounding。InflateRect(CSize(m_nPenWidth; m_nPenWidth));
新的计算方式是:
for (int i=1; i 《 m_pointArray。GetSize(); i++)
{
pt = m_pointArray'i';
m_rectBounding。left = min(m_rectBounding。left; pt。x);
m_rectBounding。right = max(m_rectBounding。right; pt。x);
m_rectBounding。top = max(m_rectBounding。top; pt。y);
m_rectBounding。bottom = min(m_rectBounding。bottom; pt。y);
}
m_rectBounding。InflateRect(CSize(m_nPenWidth; …(int)m_nPenWidth));
这是因为在Y 轴向下的系统中,四方形的最顶点位置应该是找Y 坐标最小者;而在
Y 轴向上的系统中,四方形的最顶点位置应该是找Y 坐标最大者;同理,对于四方
形的最底点亦然。
691
…………………………………………………………Page 754……………………………………………………………
第篇 深入 MFC 程式設計
0 x y
min y max y
min y
max y
0
y x
2。 我们在OnDraw 中曾经以IntersectRect 计算两个四方形是否有交集。这个函数
也是CRect 成员函数,它假设:一个四方形的底坐标Y 值必然大于顶坐标的
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 在下一节列出。