最近做WIN32 API开发时发现对ScrollWindow的一些工作原理并不是太清楚,于是做了相关研究,记载下来和大家共同学习。 首先在WM_CREATE中获取系统字符的宽度和高度
为了增强滚动时的对比效果,在WM_PAINT中分别写左右两行文字
下面再加上滚动右边文字的代码
运行依次进入WM_CREATE,WM_PAINT,WM_SIZE消息
WM_CREATE中显示 WM_PAINT中显示 WM_SIZE中显示 可知 字符大小为高度16px 宽度8px 客户区大小为宽1009px 高488px 左边显示区域范围为左0px 上0px 右504px 下488px 右边显示区域范围为左504px 上0px 右1009px 下488px 按小键盘上的上下滚动键分别得到重绘区域为 上 下 对比计算 可知当使用ScrollWindow时左边区域并没有重绘 当右边向上滚动时 重绘区域为向上滚动后没有被滚动区域覆盖的最小面一行字符区域 当右边向下滚动时 重绘区域为向下滚动后没有被滚动区域覆盖的最上面一行字符区域 故 我们再看看微软MSDN中对ScrollWindow的描述 “如果在被滚动的窗口中含有^符,ScrollWindow将自动隐藏起^符,以防它被擦掉;当滚动结束后再恢复^符。^符的位置相应的被调整过来。 未被ScrollWindow覆盖的区域不再重画,但该区域会与窗口更新区域组合。应用程序最终收到WM_PAINT的消息,通知它结合区域必须被重画。为了在滚动操作的同时重画未覆盖区域,则应在调用ScrollWindow函数后马上调用UpdateWindow函数。 如果参数lpRect为NULL,则窗口中的任何子窗口的位置由参数XAmount和Yamount的数值决定偏移;窗体无效(未着色)的区域也偏移。IpRect为NULL时ScrollWindow执行地更快。 如果参数lpRect不为NULL,则窗口中的子窗口的位置不改变,窗口中无效(未着色)的区域也不偏移。为了防止lpRect不为NULL时更新的问题,需要在调用ScrollWindow前调用UpdateWindow函数重绘窗口。” 这里的未被scrollWindow覆盖的区域应该强调是scrollWindow使用的剪切区域中未被滚动操作覆盖的区域,这里是很多人难以理解的地方,务必注意。 那么如何高效的使用ScrollWindow这个API函数呢 这里笔者以每次滚动一行文字为例,提供两种方法 1.按照MSDN提供的方法来使用 调用完ScrollWindow后 ,立即调用UpdateWindow发送一个不进队的WM_PAINT消息。在WM_PAINT消息中可以按照滚动时的逻辑,整个区域都绘制但是利用重绘区域自动将多余的绘制剪切掉,只绘制未被滚动操作覆盖的一行;但是更高明的做法无疑是只绘制未被滚动操作覆盖的一行,加快绘制速度。 2.在调用ScrollWindow的非WM_PAINT消息中绘制 在调用按ScrollWindow后获得窗口DC,自己绘制未被滚动操作覆盖的一行,然后将整个滚动剪切区域设为有效,禁止其产生WM_PAINT消息,这样也可加快绘制速度。 |
|