滚动条由滚动滑块以及两端的滚动箭头组成, 滚动条的作用是当需要显示的内容超过窗口客户区大小时提供上下/左右的翻页使用户能够完整的阅读显示信息
Windows滚动条介绍
滚动条由滚动滑块以及两端的滚动箭头组成, 滚动条的作用是当需要显示的内容超过窗口客户区大小时提供上下/左右的翻页使用户能够完整的阅读显示信息, 滚动条的图示:
滚动条理论基础
1>. 上下滚动?
以垂直方向的滚动条为例, 当用户向下滚动滚动条时目的是想看到下方更多的的信息, 因此我们需要将下方的信息显示出来, 如何显示更多的信息?
解决方案: 将不需要被显示的信息显示到客户区外
, 令信息自动被Windows截掉, 图示说明:
由图示看出, 当用户向下翻动滚动条实际上我们是将起始输出部分的y坐标设为负数, 使已经显示过的信息输出到客户区的上部, 我们知道, 输出到客户区外部的信息会被Windows自动截掉, 所以用户不会再次看到已经显示过的信息, 取而代之的就是下方等待显示的信息, 上翻以及左右翻动的显示思路与下翻相同, 不再介绍。
2>. 如何创建一个带有滚动条的窗口?
创建带有水平/垂直的滚动条的窗口十分简单, 在CreateWindow函数中说明下即可, CreateWindow函数的原型回顾:
HWND CreateWindow( LPCTSTR lpClassName,//
窗口类名称
LPCTSTR lpWindowName, //
窗口标题
DWORD dwStyle, //
窗口样式
int
x, //窗口初始x坐标 int
y, //窗口初始y坐标 int
nWidth, //窗口初始x方向尺寸 int
nHeight, //窗口初始y方向尺寸 HWND hWndParent, //
父窗口句柄
HMENU hMenu, //
窗口菜单句柄
HANDLE hlnstance, //
程序实例句柄
LPVOID lpParam //
创建参数
);
要窗口带有滚动条的窗口, 只需要在第三个参数
DWORD dwStyle, //
窗口样式
也就是在窗口样式的属性中使用位或( | )运算对相关的标识符进行组合即可得到一个带有垂直/水平滚动条的窗口,
WS_HSCROLL //水平滚动条的标识符
WS_VSCROLL //垂直滚动条的标识符
例如要创建一个既含有垂直滚动条又含有水平滚动条的组合:
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL
3>. 对于滚动条, Windows需要做哪些事?
当带有滚动条的窗口创建好后, Windows就会做一些必要的处理来协助我们更好的使用滚动条, Windows需要做的事情如下:
1>. 处理滚动条中的所有鼠标消息;
2>. 当用户单击滚动条时提供被单击部分的轻微闪烁;
3>. 当用户拖动滑块时在滚动条内移动滑块;
4>. 当窗口大小被调整时, 自动调整滚动条的长度;
5>. 向滚动条所在的窗口发送滚动条的相关消息。
4>. 我们要做的事情:
相对于系统,我们需要做的事情已经较为轻松了
,
主要有4项任务
:
1>. 初始化滚动条的位置和滚动条的范围;
2>. 处理系统发来的消息;
3>. 根据发来的消息重置滑块的位置;
4>. 根据滚动条消息重绘客户区显示的内容。
5>. 将会收到哪些滚动条消息?
滚动条消息来源同其他消息一样, 伴随着wParam与lParam消息机制, 当窗口为父窗口时消息的来源为wParam, 此时可忽略lParam的值, lParam用于子窗口消息。
wParam参数分为两部分,&n
bsp;高位字与低位字, 其中高位字代表用户松开鼠标键时滑块的最终位置, 低位字上代表鼠标在滚动条上的动作, 以一个值的形式表现出来, 同样, 为了方便记忆, 有不同的标识符对这些值进行区分, 这些标识符定义在WINUSER.H头文件中, 以SB_开头, 有关滚动条的消息标识符如下:
#define
SB_LINEUP 0 //上翻一个单位#define
SB_LINELEFT 0 //左翻一个单位
#define SB_LINEDOWN 1 //下翻一个单位
#define SB_LINERIGHT 1 //右翻一个单位
#define SB_PAGEUP 2 //上翻一页
#define SB_PAGELEFT 2 //左翻一页
#define SB_PAGEDOWN 3 //下翻一页
#define SB_PAGERIGHT 3 //右翻一页
#define SB_THUMBPOSITION 4 //当鼠标放下滑块时
#define SB_THUMBTRACK 5 //移动滑块时
#define SB_TOP 6 //滑块到了顶端
#define SB_LEFT 6 //滑块到了左端
#define SB_BOTTOM 7 //滑块到了底端
#define SB_RIGHT 7 //滑块到了右端
#define SB_ENDSCROLL 8 //释放鼠标
6>. 需要使用到的新函数:
①. SetScrollRange
SetScrollRange函数的作用是设置所指定滚动条范围的最小值和最大值, 其函数的原型如下:
BOOL SetScrollRange( HWND hWnd,//
窗口句柄
int nBar, //被设置的滚动条类型
int nMinPos, //滚动条的最小位置
int nMaxPos, //滚动条的最大位置
BOOL bRedraw //
重绘标志
);
参数二int nBar为被设置的滚动条类型, SB_HORZ表示该窗口的水平滚动条, SB_VERT表示垂直滚动条;
参数四BOOL bRedraw指定滚动条是否被重绘以反映变化, 当参数为TRUE, 滚动条被重绘, FALSE则不被重绘。
②. SetScrollPos
SetScrollPos函数的作用是设置所指定滚动条中的滚动按钮的位置, 函数原型:
int
SetScrollPos( HWND hWnd,
//
窗体句柄
int
nBar, //被设置的滚动条类型 int
nPos, //滚动条的新位置BOOL bRedraw//
重绘标志);
实战滚动条
下面我们尝试着输出一些文字, 使其上下、左右均超过客户区的尺寸, 这样我们就可以实际练习下水平滚动条以及垂直滚动条了, 我们准备了很多行文字, 笔者也不知道到底有多少行, 而且最长的那行文字有多少个也不知道, 我们把他放在一个text.h头文件中, 并计算他到底有多少行以及最长的那行有多少字, 由于文字行数较多, 这里将它在代码框里折叠显示, 定义的头文件如下:
View Code - text.h
在这个头文件中, 其中有两句是十分重要的, 一是计算总行数:
#define
NUMLINES ( (int)(sizeof(statement) / sizeof(statement[0]) ) ) //
计算总行数
另一个是计算最长串字符个数的函数GetMaxLength, 该函数的定义如下:
int
GetMaxLength() {/*
*计算statement所有句子中最长语句的长度