关于滚动条

窗口可以显示大于窗口工作区的数据对象,例如文档或位图。 当提供滚动条时,用户可以滚动客户端区域中的数据对象,以使对象的延伸超出窗口边界的部分进入视野。

滚动条应包含在客户端区域的内容超出窗口边界的任何窗口中。 滚动条的方向决定了用户操作滚动条时滚动的方向。 水平滚动条允许用户向左或向右滚动窗口的内容。 垂直滚动条允许用户向上或向下滚动内容。

以下是本节中要讨论的主题。

滚动条的各个部分

滚动条由每个端带有箭头按钮的阴影轴和箭头按钮之间的滚动框(有时称为拇指)组成。 滚动条表示窗口工作区中数据对象的整体长度或宽度;滚动框表示在工作区中可见的对象部分。 每当用户滚动数据对象以显示其不同部分时,滚动框的位置就会发生变化。 系统还会调整滚动条的滚动框的大小,以便它指示整个数据对象当前在窗口中可见的部分。 如果大多数对象可见,滚动框占用了大部分滚动条轴。 同样,如果只有一小部分对象可见,滚动框占用滚动条轴的一小部分。

用户通过单击其中一个箭头按钮、单击阴影滚动条轴中的区域或拖动滚动框来滚动窗口的内容。 当用户单击箭头按钮时,应用程序将内容滚动一个单元(通常是单行或列)。 当用户单击阴影区域时,应用程序将内容滚动一个窗口。 当用户拖动滚动框时发生的滚动量取决于用户拖动滚动框和滚动条滚动范围的距离。 有关滚动范围的详细信息,请参阅滚动框位置和滚动范围

以下屏幕截图显示了具有垂直和水平滚动条的 Rich Edit 控件,因为它们可能在 Windows Vista 中显示。 垂直滚动条当前处于“热”状态,因为拍摄屏幕快照时鼠标指针悬停在其上方。

screen shot of a rich edit control with scroll bars

标准滚动条和滚动条控件

滚动条作为标准滚动条或滚动条控件包含在窗口中。 标准滚动条位于窗口的非工作区中。 它与窗口一起创建,并在显示窗口时显示。 标准滚动条的唯一目的是使用户能够生成用于查看客户端区域的整个内容的滚动请求。 通过在创建窗口时指定 WS_HSCROLLWS_VSCROLL 或同时指定这两种样式,可以在窗口中包含标准滚动条。 WS_HSCROLL 样式创建位于工作区底部的水平滚动条。 WS_VSCROLL 样式创建位于工作区右侧的垂直滚动条。 SM_CXHSCROLL 和 SM_CYHSCROLL 系统指标值定义标准水平滚动条的宽度和高度。 SM_CXVSCROLL 和 SM_CYVSCROLL 值定义标准垂直滚动条的宽度和高度。 标准滚动条是其关联窗口的一部分,因此没有自己的窗口句柄。

滚动条控件是属于 SCROLLBAR 窗口类的控件窗口。 此时会显示滚动条控件,其功能类似于标准滚动条,但它是一个单独的窗口。 作为一个单独的窗口,滚动条控件采用直接输入焦点。 与标准滚动条不同,滚动条控件还具有内置的键盘界面。

可以在单个窗口中根据需要使用任意数量的滚动条控件。 创建滚动条控件时,必须指定滚动条的大小和位置。 但是,如果可以调整滚动条控件的窗口大小,则必须在窗口的大小发生更改时调整滚动条的大小。

使用标准滚动条的优点是系统创建滚动条并自动设置其大小和位置。 但是,标准滚动条有时过于严格。 例如,假设要将客户端区域划分为四个象限,并使用一组单独的滚动条来控制每个象限的内容。 不能使用标准滚动条,因为只能为特定窗口创建一组滚动条。 请改用滚动条控件,因为可以根据需要将其中任意数量的控件添加到窗口中。

除了滚动窗口内容之外,应用程序还可以提供滚动条控件。 例如,屏幕保存程序应用程序可能提供滚动条,用于设置在屏幕上移动图形的速度。

滚动条控件可以具有许多样式,用于控制滚动条的方向和位置。 调用 CreateWindowEx 函数创建滚动条控件时,可以指定所需的样式。 某些样式创建了一个滚动条控件,该控件使用默认的宽度或高度。 但是,必须始终指定 x 坐标和 y 坐标以及滚动条的其他维度。

有关滚动条控件样式表,请参阅滚动条控件样式

注意

若要将视觉样式与滚动条一起使用,应用程序必须包含清单,并且必须在程序开头调用 InitCommonControls。 有关视觉样式的信息,请参阅视觉样式。 有关清单信息,请参阅启用视觉样式

 

滚动框位置和滚动范围

滚动框的位置表示为整数;它相对于滚动条的左端或上端,具体取决于滚动条是水平还是垂直。 该位置必须位于滚动范围的最小值和最大值内。 例如,在范围为 0 到 100 的滚动条中,位置 50 位于中间,其余位置沿滚动条相等分布。 初始范围取决于滚动条。 标准滚动条的初始范围为 0 到 100;滚动条控件具有空范围(最小值和最大值均为零),除非在创建控件时提供显式范围。 可以随时更改该范围。 可以使用 SetScrollInfo 函数设置范围值,使用 GetScrollInfo 函数检索当前范围值。

应用程序通常会将滚动范围调整为方便的整数,从而轻松地将滚动框位置转换为与要滚动的数据对象对应的值。 例如,如果应用程序必须在一个窗口中显示一个文本文件的 260 行,一次只能显示 16 行,垂直滚动条范围可以设置为 1 到 244。 如果滚动框位于位置 1,则第一行将位于窗口顶部。 如果滚动框位于位置 244,则最后一行(第 260 行)将位于窗口底部。 如果应用程序尝试指定小于最小值或大于最大值的位置值,则改用最小或最大滚动范围值。

可以为滚动条设置页面大小。 页面大小表示可以在所有者窗口的工作区中容纳的数据单位数(给定其当前大小)。 例如,如果工作区可以容纳 16 行文本,则应用程序会将页面大小设置为 16。 系统使用页面大小以及滚动条轴的滚动范围和长度来设置滚动框的大小。 每当调整包含滚动条的窗口大小时,应用程序调用 SetScrollInfo 函数来设置页面大小。 应用程序通过调用发送 GetScrollInfo 函数来检索当前页大小。

若要在滚动条范围和数据对象之间建立有用的关系,应用程序必须在数据对象的大小发生更改时调整范围。

当用户在滚动条中移动滚动框时,滚动条将滚动框的位置报告为滚动区域中的整数。 如果位置为最小值,则滚动框位于垂直滚动条的顶部或水平滚动条的左端。 如果位置是最大值,则滚动框位于垂直滚动条的底部或水平滚动条的右端。

滚动条可以报告(即最大滚动位置)的最大值取决于页面大小。 如果滚动条的页面大小大于一个,则最大滚动位置小于最大范围值。 可以使用以下公式计算最大滚动位置:

MaxScrollPos = MaxRangeValue - (PageSize - 1) 

应用程序必须在滚动条中移动滚动框。 尽管用户请求在滚动条中滚动,但滚动条不会自动更新滚动框位置。 而是将请求传递给父窗口,该窗口必须滚动数据并更新滚动框位置。 应用程序使用 SetScrollInfo 函数更新滚动框位置;否则,使用 SetScrollPos 函数。 因为它控制滚动框的移动,所以应用程序可以以最适合滚动数据的增量移动滚动框。

滚动条可见性

当指定相等的最小值和最大值时,系统会隐藏和禁用标准滚动条。 如果指定包含滚动条整个滚动范围的页面大小,则系统还会隐藏和禁用标准滚动条。 这是在不需要工作区内容时暂时隐藏滚动条的方式。 隐藏滚动条时,无需通过滚动条发出滚动请求。 当将最小值和最大值设置为不相等值以及页面大小不包括整个滚动范围时,系统将启用滚动条并再次显示它。 ShowScrollBar 函数还可用于隐藏或显示滚动条。 它不会影响滚动条的范围、页面大小或滚动框位置。

EnableScrollBar 函数可用于禁用滚动条的一个或两个箭头。 应用程序以灰色显示禁用的箭头,并且不响应用户输入。

滚动条请求

用户通过单击滚动条的各个部分发出滚动请求。 系统以 WM_HSCROLLWM_VSCROLL 消息的形式将请求发送到指定窗口。 水平滚动条发送 WM_HSCROLL 消息;垂直滚动条发送 WM_VSCROLL 消息。 每条消息都包含一个与用户操作对应的请求代码、滚动条(仅滚动条控件)的句柄,在某些情况下,请求代码对应于滚动框的位置。

下图显示了用户在单击滚动条的各个部分时生成的请求代码。

diagram showing the request codes associated with each region on two scroll bars

SB_ 值指定用户执行的操作。 应用程序检查 WM_HSCROLLWM_VSCROLL 消息随附的代码,然后执行相应的滚动操作。 在下表中,为每个值指定了用户的操作,然后是应用程序的响应。 在每种情况下,应用程序都会为数据定义适当的单元。 例如,垂直滚动文本的典型单位是一行文本。

请求 操作 响应
SB_LINEUP 用户单击顶部滚动箭头。 递减滚动框的位置;向数据顶部滚动一个单位。
SB_LINEDOWN 用户单击底部滚动箭头。 增加滚动框的位置;向数据底部滚动一个单位。
SB_LINELEFT 用户单击左侧滚动箭头。 递减滚动框的位置;向数据左侧滚动一个单位。
SB_LINERIGHT 用户单击右侧滚动箭头。 增加滚动框的位置;向数据右侧滚动一个单位。
SB_PAGEUP 用户单击滚动框上方的滚动条轴。 将滚动框的位置减少窗口中的数据单元数;以相同数量的单位向数据的顶部滚动。
SB_PAGEDOWN 用户单击滚动框下方的滚动条轴。 将滚动框的位置增加窗口中的数据单元数;以相同数量的单位向数据的底部滚动。
SB_PAGELEFT 用户单击滚动框左侧的滚动条轴。 将滚动框的位置减少窗口中的数据单元数;以相同数量的单位向数据的左侧滚动。
SB_PAGERIGHT 用户单击滚动框右侧的滚动条轴。 将滚动框的位置增加窗口中的数据单元数;以相同数量的单位向数据的右侧滚动。
SB_THUMBPOSITION 用户在拖动滚动框后释放滚动框。 将滚动框设置为消息中指定的位置;以与滚动框移动的单位数相同的单位滚动数据。
SB_THUMBTRACK 用户拖动滚动框。 将滚动框设置到消息中指定的位置,并按快速绘制数据的应用程序的滚动框移动的单位数滚动数据。 无法快速绘制数据的应用程序必须等待 SB_THUMBPOSITION 请求代码,然后才能移动滚动框并滚动数据。
SB_ENDSCROLL 用户在箭头或滚动条轴上按住鼠标后释放鼠标。 不需要响应。

 

当用户单击并拖动滚动框时,滚动条会生成 SB_THUMBPOSITION 和 SB_THUBTRACK 请求代码。 应该对应用程序进行编程,以处理 SB_THUMBTRACK 或 SB_THUMBPOSITION 请求代码。

当用户单击滚动框后释放鼠标按钮时,会出现 SB_THUMBPOSITION 请求代码。 处理此消息的应用程序在用户将滚动框拖动到所需位置并释放鼠标按钮后执行滚动操作。

当用户拖动滚动框时,会出现 SB_THUMBTRACK 请求代码。 如果应用程序处理 SB_THUMBTRACK 请求代码,则可以在用户拖动滚动框时滚动窗口的内容。 但是,滚动条可以在短时间内生成许多 SB_THUMBTRACK 请求代码,因此应用程序只有在能够快速重新绘制窗口内容的情况下才能处理这些请求代码。

滚动条的键盘界面

滚动条控件提供了内置的键盘界面,使用户能够通过使用键盘发出滚动请求;标准滚动条则不然。 当滚动条控件具有键盘焦点时,当用户按下箭头键时,它会向父窗口发送 WM_HSCROLLWM_VSCROLL 消息。 请求代码与用户按下的箭头键对应的每条消息一起发送。 以下是箭头键及其相应的请求代码。

箭头键 请求代码
DOWN SB_LINEDOWN 或 SB_LINERIGHT
End SB_BOTTOM
Home SB_TOP
LEFT SB_LINEUP 或 SB_LINELEFT
PGDN SB_PAGEDOWN 或 SB_PAGERIGHT
PGUP SB_PAGEUP 或 SB_PAGELEFT
RIGHT SB_LINEDOWN 或 SB_LINERIGHT
UP SB_LINEUP 或 SB_LINELEFT

 

 

注意

滚动条控件的键盘接口发送 SB_TOP 和 SB_BOTTOM 请求代码。 SB_TOP 请求代码表示用户已达到滚动范围的最高值。 应用程序向下滚动窗口内容,以便可以看到数据对象的顶部。 SB_BOTTOM 请求代码指示用户已达到滚动范围的底部值。 如果应用程序处理 SB_BOTTOM 请求代码,则会向上滚动窗口内容,以便可以看到数据对象的底部。

 

如果想要一个标准滚动条的键盘界面,可以自己创建一个,方法是在窗口过程中处理 WM_KEYDOWN 消息,然后根据消息附带的虚拟键代码执行适当的滚动操作。 有关如何为滚动条创建键盘界面的信息,请参阅为标准滚动条创建键盘接口

滚动工作区

滚动工作区内容的最简单方法是擦除,然后重新绘制。 这是应用程序可能对 SB_PAGEUP、SB_PAGEDOWN 和 SB_TOP 请求代码使用的方法,这些请求代码通常需要全新的内容。

对于某些请求代码(如 SB_LINEUP 和 SB_LINEDOWN),并非所有内容都需要擦除,因为某些代码在滚动后仍可见。 ScrollWindowEx 函数保留工作区内容的一部分,将保留的部分移动指定量,然后准备工作区的其余部分以绘制新信息。 ScrollWindowEx 使用 BitBlt 函数将数据对象的特定部分移动到工作区中的新位置。 当出现下一个 WM_PAINT 消息时,工作区的任何未覆盖部分(任何未保留的部分)都将无效、擦除和绘制。

ScrollWindowEx 函数可用于从滚动操作中排除工作区的一部分。 这样可使具有固定位置(如子窗口)的项目在工作区内移动。 它会自动使接收新信息的工作区部分失效,因此应用程序不必计算自己的剪辑区域。 有关剪裁的详细信息,请参阅剪裁

通常,应用程序在与滚动条指示的方向相反的方向上滚动窗口的内容。 例如,当用户单击滚动框下方区域中的滚动条轴时,应用程序会向上滚动窗口中的对象,以显示可见部分下方的对象部分。

还可以使用 ScrollDC 函数滚动矩形区域。

滚动条颜色和指标

系统定义的颜色值 COLOR_SCROLLBAR 控制滚动条轴内的颜色。 使用 GetSysColor 函数确定滚动条轴的颜色,使用 SetSysColors 函数设置滚动条轴的颜色。 但是,请注意:这种颜色变化会影响系统中的所有滚动条。

可以通过调用 GetSystemMetrics 函数来获取系统在标准滚动条中使用的位图的尺寸。 下面是与滚动条关联的系统指标值。

系统指标 说明
SM_CXHSCROLL 水平滚动条上箭头位图的宽度
SM_CXHTHUMB 水平滚动条上滚动框的宽度。 此值检索页面大小为零的滚动条的宽度。
SM_CXVSCROLL 垂直滚动条上箭头位图的宽度
SM_CYHSCROLL 水平滚动条上箭头位图的高度
SM_CYVSCROLL 垂直滚动条上箭头位图的高度
SM_CYVTHUMB 垂直滚动条上滚动框的高度。 此值检索页面大小为零的滚动条的高度。