深入浅出MFC第2版(PDF格式)-第129部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
到目前为止我们还没有办法观察一张比窗口还大的图,因为我们没有滚动条。
一个View 窗口没有滚动条,是很糟糕的事,因为通常Document 范围大而观景窗范围小。
我们不能老让Document 与View 窗口一样大。一个具备滚动条的View 窗口更具有「观
景窗」的意义。
Document
電腦資訊 ,是個洠в袀惱淼念I域 。「洠в袀惱怼沟囊馑迹褪谴蠹译S時可能歸零 ,任何永
IQ EQ
遠有機會爬到任何的頭。而切的成功,不是靠 ,是靠 。
View1
EQ 這個字眼最近引起大颍齽印N沂窃诖蠹s兩個月前與位讀友見面,從他口第次聽到的。
這位朋友是 ENT 執業醫師(ENT 者,ear/nose/throat 是也),他在專業以外的第素養,以及
追求新知的熱情,著實讓我感動。對於醫界沉痾的剴切直言,更讓執筆無責任書評的我,有吾
道不孤之感,呵呵。會拿起封了八個月的筆,與這位讀友的席談實有許多關係。
◆根魚刺 View2
葉醫師,我的這位讀友,對我提到最近的本奇特小書:資訊游俠列傳、無責任書評2、我的
電腦探索,並以種不勝幽然的口吻說:「看到這些年紀輕輕的小輩們頭角崢嶸,自己學個
Visual Basic 。。。
卻心力支絀,實在有莫大的打擊 」。侯捷是這本書的唯交集,本應遵循
「瓜田不迹模畈徽凇怪庞枺欢乙嘤懈~刺鯁在我的喉結裡。
這本書裡頭,資訊游俠列傳是個男對九個男的探索(別铡畷耍皇乔樯膶W);無
責任書評2是個「讀書懷獨行君子之節」的的技術評論與文關懷,非常私,十分另
類。我的電腦探索則是十個男對電腦資訊的深情告白。如果以結婚為分水嶺,劃分男與男
孩,那麼第本書其實是「個男與九個男孩」對電腦的深情告白。
。。。
图11…5a 一个具备滚动条的View 窗口更具 「观景窗」的意义
如果你有SDK 程序设计经验,你就会知道设计一个可卷动的窗口是多么烦琐的事(文
字的卷动还算好,图形的卷动更惨)。MFC 当然不可能对此一般性功能坐视不管,事实
上它已设计好一个CScrollView,其中的滚动条有实时卷动(边拉卷动杆边跑)的效果。
基本上要使View 窗口具备滚动条,你必须做到下列事情:
640
…………………………………………………………Page 703……………………………………………………………
第 11 章 View 功能之加強與重繪效率之提昇
Document
200
450
270
垂
目前垂直位置= 200
直
300 滚
目前水平位置 =270 动
条
水平頁大小= 450 范
900 围
900
水平滚动条范围 = 800
垂
直
頁
大
小
300
800
图11…5b 滚动条View 窗口与Document 之间的关系
定义Document 大小。如果没有大小,Framework 就没有办法计算滚动条尺寸,
以及卷动比例。这个大小可以是常数,也可以是个储存在每一Document 中的
变量,随着执行时期变动。
以CScrollView 取代CView。
只要Document 的大小改变,就将尺寸传给CScrollView 的SetScrollSizes 函
式。如果程序设定Document 为固定大小(本例就是如此),那么当然只要一
开始做一次滚动条设定动作即可。
注意装置坐标(窗口坐标)与逻辑坐标(Document 坐标)的转换。关于此点
稍后另有说明。
641
…………………………………………………………Page 704……………………………………………………………
第篇 深入 MFC 程式設計
Application Framework 对滚动条的贡献是:
■处理WM_HSCROLL 和WM_ VSCROLL 消息,并相对地卷动Document (其实
是移动View 落在Document 上的位置) 以及移动「滚动条拉杆」( 所谓的
thumb )。拉杆位置可以表示出目前窗口中显示的区域在整个Document 的位
置。如果你按下滚动条两端箭头,卷动的幅度是一行(line ),至于一行代表多
少,由程序员自行决定。如果你按下的是拉杆两旁的杆子,卷动的幅度是一页
(page ),一页到底代表多少,也由程序员自行决定。
向上卷动一行
向上卷动一页
垂直拉杆
向下卷动一页
向下卷动一行
水平拉杆 向右卷动一行
向左卷动一页
向右卷动一页
向左卷动一行
窗口一旦被放大缩小,立刻计算窗口的宽度高度与滚动条长度的比例,以重新设
定卷动比例,也就是一行或一页的大小。
以下分四个步骤修改Scribble 源代码:
1 定义Document 的大小。我们的作法是设定一个变量,代表大小,并在Document 初
始化时设定其值,此后全程不再改变(以简化问题)。MFC 中有一个CSize 很适合当
作此一变量类型。这个成员变量在文件进行文件读写(Serialization)时也应该并入文件
内容中。回忆一下,上一章讲到笔宽时,由于每一线条有自己的一个宽度,所以笔宽资
料应该在CStroke::Serialize 中读写,现在我们所讨论的文件大小却是属于整份文件的资
料,所以应该在CScribbleDoc::Serialize 中读写:
642
…………………………………………………………Page 705……………………………………………………………
第 11 章 View 功能之加強與重繪效率之提昇
// in SCRIBBLEDOC。H
class CScribbleDoc : public CDocument
{
protected:
CSize m_sizeDoc;
public:
CSize GetDocSize() { return m_sizeDoc; }
。。。
};
// in SCRIBBLEDOC。CPP
void CScribbleDoc::InitDocument()
{
m_bThickPen = FALSE;
m_nThinWidth = 2; // default thin pen is 2 pixels wide
m_nThickWidth = 5; // default thick pen is 5 pixels wide
ReplacePen(); // initialize pen according to current width
//预设Document 大小为800 x 900 个屏幕图素
m_sizeDoc = CSize(800;900);
}
void CScribbleDoc::Serialize(CArchive& ar)
{
if (ar。IsStoring())
{
ar 》 m_sizeDoc;
}
m_strokeList。Serialize(ar);
}
2 将CScribbleView 的父类别由CView 改变为CScrollView。同时准备改写其虚拟函数
OnInitialUpdate,为的是稍后我们要在其中,根据Document 的大小,设定卷动范围。
// in SCRIBBLEVIEW。H
class CScribbleView : public CScrollView
{
public:
virtual void OnInitialUpdate();
。。。
643
…………………………………………………………Page 706……………………………………………………………
第篇 深入 MFC 程式設計
};
// in SCRIBBLEVIEW。CPP
IMPLEMENT_DYNCREATE(CScribbleView; CScrollView)
BEGIN_MESSAGE_MAP(CScribbleView; CScrollView)
。。。
END_MESSAGE_MAP()
3 改写OnInitialUpdate,在其中设定滚动条范围。这个函数的被调用时机是在View 第
一次附着到Document 但尚未显现时,由Framework 调用之。它会调用OnUpdate,不
带任何Hint 参数(于是lHint 是0 而pHint 是NULL )。如果你需要做任何「只做一
次」的初始化动作,而且初始化时需要Document 的资料,那么在这里做就最合适了:
// in SCRIBVW。CPP
void CScribbleView::OnInitialUpdate()
{
SetScrollSizes(MM_TEXT; GetDocument()…》GetDocSize());
//这是CScrollView 的成员函数。
}
SetScrollSizes 总共有四个参数:
int nMapMode :代表映射模式(Mapping Mode)
SIZE sizeTotal:代表文件大小
const SIZE& sizePage :代表一页大小(预设是文件大小的1/10)
const SIZE& sizeLine :代表一行大小(预设是文件大小的1/100)
本例的文件大小是固定的。另一种比较复杂的情况是可变大小,那么你就必须在文件大
小改变之后立刻调用SetScrollSizes 。
窗口上增加滚动条并不会使View 的OnDraw 负担加重。我们并不因为滚动条把观察镜头移
动到Document 的中段或尾段,而就必须在OnDraw 中重新计算绘图原点与平移向量,
原因是绘图坐标与我们所使用的DC 有关。当滚动条移动了DC 原点,CScrollView 自动
644
…………………………………………………………Page 707……………………………………………………………
第 11 章 View 功能之加強與重繪效率之提昇
会做调整,让资料的某一部份显示而某一部份隐藏。
让我做更详细的说明。「GDI 原点」是DC (注)的重要特征,许许多多CDC 成员函
式的绘图结果都会受它的影响。如果我们想在绘图之前(也就是进入OnDraw 之前)调
整D