深入探索ScrollWindow
最近做WIN32 API开发时发现对ScrollWindow的一些工作原理并不是太清楚,于是做了相关研究,记载下来和大家共同学习。
首先在WM_CREATE中获取系统字符的宽度和高度
- case WM_CREATE:
- //获取系统字符的宽度和高度
- cxChar = LOWORD(GetDialogBaseUnits()) ;
- cyChar = HIWORD(GetDialogBaseUnits()) ;
- //显示字体大小
- sprintf(szBuffer, TEXT("字符高度:%d 字符宽度:%d"), cyChar, cxChar) ;
- MessageBox(hwnd, szBuffer, TEXT("字符大小"), MB_OK) ;
- return 0 ;
再在WM_SIZE中获取客户区大小
- case WM_SIZE:
- //获取客户区大小
- GetClientRect(hwnd, &rcClient) ;
- //显示客户区大小
- sprintf(szBuffer, TEXT("左上角:%d %d 右下角:%d %d"), rcClient.left, rcClient.top, rcClient.right, rcClient.bottom) ;
- MessageBox(hwnd, szBuffer, TEXT("客户区大小"), MB_OK) ;
- return 0 ;
为了增强滚动时的对比效果,在WM_PAINT中分别写左右两行文字
- case WM_PAINT:
- hdc = BeginPaint (hwnd, &ps) ;
- //获取重画区域大小
- sprintf(szBuffer, TEXT("%d %d %d %d"), ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom) ;
- MessageBox(hwnd, szBuffer, TEXT("重画区域"), MB_OK) ;
- TextOut(hdc, 0, (rcClient.bottom-rcClient.top)/2,
- TEXT("Text Out here left!"), lstrlen(TEXT("Text Out here left!"))) ;
- TextOut(hdc, (rcClient.right-rcClient.left)/2, (rcClient.bottom-rcClient.top)/2,
- TEXT("Text Out here right!"), lstrlen(TEXT("Text Out here right!"))) ;
- EndPaint (hwnd, &ps) ;
- return 0 ;
下面再加上滚动右边文字的代码
- case WM_KEYDOWN:
- CopyRect(&rect, &rcClient) ;
- rect.left = rcClient.right / 2 ;
- switch(wParam)
- {
- case VK_DOWN:
- ScrollWindow(hwnd, 0, cyChar, &rect, &rect) ;
- break ;
- case VK_UP:
- ScrollWindow(hwnd, 0, -cyChar, &rect, &rect) ;
- break ;
- }
- return 0 ;
运行依次进入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消息,这样也可加快绘制速度。
原创,转载请注明来自http://blog.csdn.net/wenzhou1219
http://blog.csdn.net/wenzhou1219/article/details/7798967
深入探索ScrollWindow的更多相关文章
- 探索Win32系统之窗口类(转载)
Window Classes in Win32 摘要 本文主要介绍win32系统里窗口类的运做和使用机制,探索一些细节问题,使win32窗口类的信息更加明朗化. 在本文中,"类", ...
- 【探索】机器指令翻译成 JavaScript
前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念.为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学. 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript ...
- 【探索】利用 canvas 实现数据压缩
前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...
- 探索C#之6.0语法糖剖析
阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...
- Mysql事务探索及其在Django中的实践(二)
继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...
- Linux学习之探索文件系统
Linux,一起学习进步- ls With it, we can see directory contents and determine a variety of important file ...
- 马里奥AI实现方式探索 ——神经网络+增强学习
[TOC] 马里奥AI实现方式探索 --神经网络+增强学习 儿时我们都曾有过一个经典游戏的体验,就是马里奥(顶蘑菇^v^),这次里约奥运会闭幕式,日本作为2020年东京奥运会的东道主,安倍最后也已经典 ...
- C++随笔:.NET CoreCLR之GC探索(4)
今天继续来 带大家讲解CoreCLR之GC,首先我们继续看这个GCSample,这篇文章是上一篇文章的继续,如果有不清楚的,还请翻到我写的上一篇随笔.下面我们继续: // Initialize fre ...
- C++随笔:.NET CoreCLR之GC探索(2)
首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话, ...
随机推荐
- 【bzoj2002】弹飞绵羊(分块)
题目分析 题意:每个点都有一个值$v_i$,从一个点出发,每走到一个点,会跳到i+vi的位置,问需要跳多少次能跳出n?带修改. 此题可以用lct做,此处使用了分块:将序列分块后,每个点记录从此点最少跳 ...
- [Android]对话框样式Activity获得窗口外点击事件
Dialog除了使用Dialog类来实现之外,还可以使用Dialog样式的Activity来实现,只需要在注册Activity时指明theme为adnroid:Theme.Dialog就行,这样的Di ...
- VS2017 安装过程
2017 安装过程 工欲善其事必先利其器 Visual Studio 2017 正式版官方下载地址:https://www.visualstudio.com/downloads/ 安装vs2017的时 ...
- spring-boot-sample-web-jsp
Pom文件需要配置的: <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl&l ...
- sdk manager 打不开
解决方法1: 提示 [SDK Manager] Failed to convert path to a short DOS path: C:\windows\system32\java.exe 打开t ...
- 分位数(quantiles)、Z-score 与 F-score
0. 分位数(quantiles) 因为累计分布函数(cdf,F−1)是单调增函数,因此其有反函数,不妨记为 F−1. 其真实的含义在于,如果 F 是 X 的 cdf,则 F−1(α) 的函数值为: ...
- VC中引用第三方库,常见的库冲突问题
Q:VC中引用第三方库,常见的库冲突问题 环境:[1]VS2008 [2]WinXP SP3 A1(方法一): [S1]第三方库(Binary形式的)如果同主程序冲突,则下载第三方库的源码[S2]保持 ...
- 微信小程序之商品属性分类
所提及的购物数量的加减,现在说说商品属性值联动选择. 为了让同学们有个直观的了解,到电商网截了一个图片,就是红圈所示的部分 现在就为大家介绍这个小组件,在小程序中,该如何去写 下图为本项目的图: wx ...
- linux下一个C语言要求CPU采用
部分 从灾难中 本来我想写一个小程序来测试CPU其他工具利用它可以检验类数据的性能.以后参考IPbench中间cpu_target_lukem插件实现我们的功能.原理非常简单:就是我们给程序设置了 ...
- 目标检测的图像特征提取(一)HOG特点
1.HOG特点: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检測的特征描写叙述子.它通过计算和统计图像局部区 ...