专栏导航

上一篇:第4章,[标签 Win32] :SysMets3 程序讲解02,iVertPos

回到目录

下一篇:第4章,[标签 Win32] :SysMets3 程序讲解04,垂直滚屏重绘

本节前言

对于本节所讲解的知识,有可能,你会需要时不时地参考本专栏的其它文章。真的遇到了需要参考之前的文章的知识点,请你自行查阅。

我呢,也会提到一部分的参考课节。但是呢,你不应该依赖于我的主动提及。最好呢,你自己能够多去了解和查看本专栏目录。

关于 SysMets3,我个人认为,这是一个比较难的程序。我也认为,这个程序,需要讲解的地方有很多。

本节,我们来讲垂直滚屏原理。垂直滚屏原理,并非是严格对应着 SysMets3 的代码。我是将 SysMets3 的代码中,WM_PAINT 消息处理代码的运行机制的一部分,提取了出来,来予以讲解。

注意,我这里所说的 “原理”,也仅仅是我的一种理解与假说。实际的 Windows API,未必是这么来运作的。然而,这种假说,有助于我们理解滚屏操作,有助于我们理解滚屏函数 ScroolWindow 函数与 WM_PAINT 消息的联合运作机制。

我们在讲解 WM_PAINT 消息处理代码中的一部分难点代码时,也会以此 “原理” 为基本依据,来进行讲解。

我们开始。

一.    基础布局

首先呢,我们来看一个文本文件,它列出了计算机学科的部分课程名称。

图1

现在呢,我们来将窗口的纵向的距离予以缩小,同时将水平方向的距离也适当缩小,如下图所示。

图2

在图1 里面,文本编辑器软件,NotePad++ 可以完整地显示 15 个课程的名字,并且,下方还有几行剩余。缩小了以后,图2 里面,我们只令软件客户区显示课程1 到课程10 这十个课程。

我们若是以课程01 为si.nMin 的内容的话,则课程01 为范围的最小值 0,而课程15为范围的最大值14 。范围的最小值为 0,范围的最大值为 14,页面大小为 10,则滚动条滑块的位置最大值会被限定为 si.nMax - si.nPage + 1,也就是 14 - 10 + 1,6 。

本分节,我们先讲到这里,在下一分节,我们来讲解垂直滚屏的分解原理。

二.    垂直滚屏演示,点击滑块下方

现在,我们点击一下垂直滚动条滑块下方的空白区域。点击完了之后,按照我们目前所学,正常来讲,其显示结果如下。

图3

这是我们直接将显示结果展示出来了。

然而,我们还可以将显示结果予以分解。

(一)第一阶段

关于第一阶段,我们将结果展示一下。

图4

根据第一分节的讲解,范围的最小值为 0,范围的最大值为 14,页面大小为 10,滑块的最大值被限定为 5,原本的滑块位置为 0 。在这种情况下,当我们点击了滑块下方的滚动条空白区域的时候,原位置值 0 会加上页面大小 10,为 10 。而由于滑块位置的最大值被限定为 5,所以呢,滑块的新位置便是 5 。位置5 对应的内容是课程06 。

在图4 里面,课程06 居于最上方,再往下是课程07,课程08,课程09,课程10 。

这一阶段里,滚屏的计算过程是,滑块的原位置是 0,而新位置是 5 。当我们点击了滑块下方的滚动条空白区域的时候,下方的内容会相对于客户区网上卷动。具体地,原文档中,课程06 到课程10,也就是位置 5 到位置 9,会变到客户区最上方。其中,位置5 的内容课程06 会居于客户区的最上方。

在图 2 中,位置0 到位置9,也就是课程01 到课程10,是被明确地显示了出来的;而课程11 到课程15,也就是位置 10 到位置 14,是未被显示的。

由于在图2 中,位置0 到位置9 被显示出来了,而滚屏操作的新位置值是 5,所以呢,在滚屏操作的第一阶段里,位置5 到位置9 会被显示出来,如图4 所示,课程06 到课程10 都被显示出来了。

由于在图2 中,位置10 到位置14 在图2 中未被显示,那么,在滚屏操作的第一阶段中,涉及位置10与位置14 的部分,其显示结果就会是一个空白。如图4 所示,在课程10 的下方,没有关于课程11 到课程15 的内容。课程10 的下方为空白。

这样一来,第一阶段,我们就展示完了。

在本案例中,第一阶段,是将图2 中原本已显示了的位置5 到位置9,也就是课程06 到课程10 的文本行,卷动到客户区最上方;而图2 中未显示的位置10 到位置14,也就是课程11 到课程14的文本行,第一阶段的处理方法是不予以显示,对应的客户区内容显示为空白行。

(二)第二阶段

关于第二阶段,我们来展示结果。

图5

第二阶段的显示结果——图5,相对于第一阶段的显示结果——图4,仅仅是将位置10 到位置14,也就是课程11 到课程15 的文本行,给显示了出来而已。

原理讲述

对于本案例,第一阶段,是将图2 中已经显示了的位置5 到位置9,卷动到客户区的最上方。同时,在第一阶段的显示结果中,位置10 到位置14 的部分不予以显示,而显示未空白行。而第二阶段中,将第一阶段中的位置10 到位置14 的空白行,给显示出来。

为啥第一阶段的显示结果里,位置5 到位置9 会被显示出来,而位置10到位置14 会显示为空白呢?在滚屏之时,滚屏函数能看到的,只有位置 0 到位置 9,因此,在位置0 到位置9 这部分的内容,滚屏函数可以原封不动地将其作滚动处理,内容不变。而位置10 到位置14,滚屏函数不知道它的具体内容是什么,因为滚屏之前,这部分内容,在客户区里面并未显示,滚屏函数不知道它们具体是什么。对于这种未知的内容,滚屏函数在第一阶段,只好将其定义为空白,因此,在第一阶段,位置10 到位置14 为空白行。

不过呢,这种空白行你也需要作另外的理解。

如果,程序的背景是一个浅灰色纯色背景,则滚屏操作第一阶段的结果中,空白行的部分,应该是一个浅灰色纯色背景。如果程序背景时蓝色纯色背景,则滚屏操作的第一阶段的结果中,空白行的部分,应该是一个蓝色纯色背景。

这是我对空白行的解释。

而在第二阶段,空白行的部分显示了出来。空白行的显示,不是滚屏函数的功劳,而是 “重绘” 的结果。由于 “重绘”,程序将原本不在图2 的客户区的位置10 到位置14 的内容,显示出来了。

第一阶段的主要任务,是滚屏与显示空白行。第二阶段,空白行的重绘

讲完了点击滑块下方的运行机理以后,我们来看下一分节。

三.    垂直滚屏演示,点击滑块上方

我们还是以第一分节的例子为基本情况。

现在呢,我们以图5 的内容为起始情况。我们再次将图5 贴在下面。

图5 副本

然后呢,我们来点击滑块上方的滚动条空白区域,正常结果如下。

图6

现在呢,我们还是来分节演示滚屏运行机理。

(一)第一阶段

根据第一分节的讲解,范围的最小值为 0,范围的最大值为 14,页面大小为 10,滑块的最大值被限定为 5 。在起始情况图5 中,起始的滑块位置为 5 。在这种情况下,当我们点击了滑块上方的滚动条空白区域的时候,原位置值 5 会减去页面大小 10,为 -5 。而由于滑块位置的最小值被限定为 0,所以呢,滑块的新位置便是 0 。

滑块位置由旧位置5 变为新位置0,5 - 0 = 5,所以,本次滚屏卷动的是 5 行。原本,文档的位置5 为客户区顶行的内容,滚动结束后,文档的位置0 变为客户区的顶行(即第 1 行)内容。此时,位置5 的内容课程06 变动到客户区的第 6 行。

在这种滚屏操作中,位置5 的内容课程06,由原本的客户区第 1 行,变到客户区的第 6 行。也就是说,客户区原本的位置5的内容课程06 起始的几行,相对于客户区,是向下卷动了几行。具体卷动的,是 5 行。

由于客户区的原本内容相对于客户区向下滚动了 5 行,所以呢,原本的客户区内容,从下往上数的 5 行内容,都会被卷动客户区之外,变为不可见。可见的,只是课程06 到课程10的文本行,也就是只有位置 5 到位置 9 是可见的。

因此,在滚屏操作的第一阶段,显示结果如下。

图7

到这里,第一阶段结束。

(二)第二阶段

第二阶段,是将空白行给显示出来,也就是 “重绘” 出来。

在第一阶段中,课程06 的文本行,从客户区顶行,也就是第 1 行,变到了客户区第 6 行,那么,第一阶段滚屏结束之后,前 5 行,也就变为了空白行。

因此,在第二阶段中,操作任务就是,将客户区的第 1 行到第 5 行,给 “重绘” 出来。课程06 为位置5,位置5 前边的五行内容,自然是位置0 到位置4,也就是课程01 到课程05 的文本行。

重绘结果如下。

图6 副本

原理讲述

单击滑块上方的滚动条区域,也是分为两个阶段,第一阶段是滚屏与显示空白行,第二阶段是空白行的重绘

结束语

讲解程序,还是有难度啊。

想要详细讲解代码运行机制,还是会费点儿劲儿啊。如何组织语言,如何安排讲解思路,还是需要一番琢磨。耗时费力啊。

滚屏操作原理中,空白行的出现,和空白行的重绘,是本节的重难点所在。

希望大家能够学好本节内容。

专栏导航

上一篇:第4章,[标签 Win32] :SysMets3 程序讲解02,iVertPos

回到目录

下一篇:第4章,[标签 Win32] :SysMets3 程序讲解04,垂直滚屏重绘

更多推荐