Files
minigui-docs/programming-guide-zh/MiniGUIProgGuidePart1Chapter07-zh.md
2022-11-17 16:06:23 +00:00

123 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 滚动条
## 1 滚动条概念
>【注意】本章讲述的滚动条是作为 MiniGUI 主窗口和控件的一部分而存在的。MiniGUI 3.0 中也增加了独立的滚动条控件。有关该滚动条控件的使用方法,请参阅本指南“[独立滚动条控件](MiniGUIProgGuidePart6Chapter21-zh.md)”。
滚动条是图形用户界面中最好的功能之一,它很容易使用,而且提供了很好的视觉反馈效果。你可以使用滚动条显示任何东西——无论是文字、图形、表格、数据库记录、图像或是网页,只要它所需的空间超出了窗口的显示区域所能提供的空间,就可以使用滚动条。
滚动条既有垂直方向的供上下移动也有水平方向的供左右移动。使用者可以使用鼠标在滚动条两端的箭头上或者在箭头之间的区域中点一下这时滚动滑块在滚动条内的移动位置与所显示的信息在整个文件中的位置成比例。使用者也可以用鼠标拖动滚动滑块到特定的位置。图8.1显示了垂直滚动条的建议用法。
![垂直滚动条的建议用法](figures/Part1Chapter07-01.jpeg)
__图 1__ 垂直滚动条的建议用法
有时程序编写者对滚动概念很难理解因为他们的观点与使用者的观点不同使用者向下滚动是想看到文件较下面的部分但是程序实际上是将文件相对于显示窗口向上移动。MiniGUI 是依据使用者的观点:向上滚动意味着朝文件的开头移动;向下滚动意味着朝文件尾部移动。
在应用程序中包含水平或者垂直的滚动条很容易,程序编写者只需要在`CreateWindow` 的第三个参数中包括窗口风格标识号 `WS_VSCROLL`(垂直滚动)和(或) `WS_HSCROLL` (水平滚动)即可。这些滚动条通常放在窗口的右部和底部,伸展为显示区域的整个长度或宽度。显示区域不包含滚动条所占据的空间。另外,默认情况下,垂直滚动条显示在窗口的右侧,如果希望将垂直滚动条显示在窗口的左侧,则应该使用 `WS_EX_LEFTSCROLLBAR` 扩展风格。
在 MiniGUI 中,会自动将鼠标点击转换为相应的消息,但是程序编写者必须自己处理键盘的消息。
## 2 使能、禁止滚动条
```c
EnableScrollBar (hWnd, SB_HORZ, TRUE);
EnableScrollBar (hWnd, SB_VERT, FALSE);
```
`EnableScrollBar` 函数可以用来使能或者禁止滚动条,它的第二个参数指定要操作的是哪个(垂直或者水平)滚动条。
## 3 滚动条的范围和位置
每个滚动条均有一个相关的“范围”(这是一对整数,分别代表最小值和最大值)和“位置”(它是滚动滑块在此范围内的位置)。当滚动滑块在滚动条的顶部(或左部)时,滚动滑块的位置是范围的最小值;在滚动条的底部(或右部)时,滚动滑块的位置是范围的最大值。
在默认情况下,滚动条的范围是从 0顶部或左部至 100底部或右部但我们也可以将范围改变为更便于程序处理的数值
```c
SCROLLINFO si;
si.nMax = 100;
si.nMin = 0;
si.nPage = 10; // 该变量决定了滚动滑块的长度该长度是由nPage/(nMax-nMin)的大小决定的
si.nPos = 0; // 滑块的当前位置它必须在nMin和nMax的范围内
SetScrollInfo (hWnd, Bar, &si, bRedraw);
```
参数 `Bar``SB_VERT` 或者 `SB_HORZ``nMin``nMax` 分别是范围的最小值和最大值。如果想要窗口根据新范围重画滚动条,则设置 `bRedraw``TRUE`(如果在调用`SetScrollRange` 后,调用了影响滚动条位置的其他函数,则应该将 `bRedraw` 设定为 `FALSE` 以避免过多地重画)。滚动滑块的位置总是离散的整数值。例如,范围为 0 至 4 的滚动条具有 5 个滚动滑块位置。如图 2。
![范围为 0 至 4 的滚动条具有 5 个滚动滑块位置](figures/Part1Chapter07-02.jpeg)
__图 2__ 范围为 0 至 4 的滚动条具有 5 个滚动滑块位置
在程序内使用滚动条时,程序编写者与窗口系统共同负责维护滚动条以及更新滚动滑块的位置。下面是窗口系统对滚动条的处理:
处理所有滚动条鼠标事件:
- 当使用者在滚动条内拖动滚动滑块时,移动滚动滑块。
- 为包含滚动条窗口的窗口消息处理程序发送滚动条消息。
以下是程序编写者应该完成的工作:
- 初始化滚动条的范围和位置。
- 处理窗口消息处理程序的滚动条消息。
- 更新滚动条内滚动滑块的位置。
- 更改显示区域的内容以回应对滚动条的更改。
## 4 滚动条消息
在用鼠标单击滚动条或者拖动滚动滑块时,窗口系统给窗口消息处理程序发送 `MSG_VSCROLL`(供上下移动)和 `MSG_HSCROLL`(供左右移动)消息。
和所有的消息一样, `MSG_VSCROLL``MSG_HSCROLL` 也带有 `wParam``lParam` 消息参数,大部分情况下我们可以忽略 `lParam` 参数。
`wParam` 消息参数被分为一个低字节和一个高字节。`wParam` 是一个数值,它指出了鼠标对滚动条进行的操作。这个数值被看作一个“通知码”。通知码的值由以 `SB`(代表 “scroll bar滚动条开头进行定义。表 1 是 MiniGUI 中定义的通知码。
__表 1__ MiniGUI 定义的滚动条通知码
| 通知码标识符 | 含义 |
|:-------------|:----|
| `SB_LINEUP` | 鼠标点击竖直按钮的上箭头 1 次 |
| `SB_LINEDOWN` | 鼠标点击竖直滚动条的下箭头 1 次 |
| `SB_LINELEFT` | 鼠标点击水平滚动条的左箭头 1 次 |
| `SB_LINERIGHT` | 鼠标点击水平滚动条的右箭头 1 次 |
| `SB_`PageUp` | 鼠标点击竖直按钮的上箭头与滑块之间的区域 1 次 |
| `SB_`PageDown` | 鼠标点击竖直按钮的下箭头与滑块之间的区域 1 次 |
| `SB_PAGELEFT` | 鼠标点击水平按钮的左箭头与滑块之间的区域 1 次 |
| `SB_PAGERIGHT` | 鼠标点击水平按钮的右箭头与滑块之间的区域 1 次 |
| `SB_THUMBTRACK` | 鼠标拖动滑块移动时窗口不断地收到的消息,注意,该值表示对鼠标位置经换算后对应的数值(通过 `lParam` 传递的),该值有可能大于设置的最大值,也有可能<小于设置的最小值在程序中需要作相应的判断 |
| `SB_THUMBPOSITION` | 用户拖动滑块结束 |
包含 `LEFT` `RIGHT` 的标识号用于水平滚动条包含 `UP``DOWN``TOP` `BOTTOM` 的标识号用于垂直滚动条鼠标在滚动条的不同区域单击所产生的通知码如图 3 所示
![鼠标在滚动条的不同区域单击所产生的通知码](figures/Part1Chapter07-03.jpeg)
__图 3__ 鼠标在滚动条的不同区域单击所产生的通知码
如果在滚动条的各个部位按住鼠标键程序就能收到多个滚动条消息
当把鼠标的游标放在滚动滑块上并按住鼠标键时你就可以移动滚动滑块这样就产生了带有 `SB_THUMBTRACK` 通知码的滚动条消息 `wParam` `SB_THUMBTRACK` `lParam` 是使用者在拖动滚动滑块时的目前位置该位置位于滚动条范围的最小值和最大值之间对于其他的滚动条操作`lParam` 应该被忽略
为了给使用者提供反馈窗口系统在你用鼠标拖动滚动滑块时移动它同时你的程序会收到` SB_THUMBTRACK` 消息然而如果不通过调用 `SetScrollPos` 来处理 `SB_THUMBTRACK` `SB_THUMBPOSITION` 消息在使用者释放鼠标键后滚动滑块会迅速跳回原来的位置
程序能够处理 `SB_THUMBTRACK` 消息如果处理`SB_THUMBTRACK` 消息在使用者拖动滚动滑块时你需要移动显示区域的内容处理 `SB_THUMBTRACK` 消息时窗口内容的更新要求比较及时因此对于某些应用程序可能因为数据量大重绘效率低而很难跟上产生的消息这时就可以忽略这个消息而只处理 `SB_THUMBPOSITION` 消息
## 5 编程实例
清单 1 给出了一个简单的滚动条处理程序该程序的完整源代码可见本指南示例程序包 `mg-samples` 中的 `scrollbar.c` 程序
__清单 1__ 滚动条及其处理
```c
SCROLLINFO si;
si.nMax = 100;
si.nMin = 0;
si.nPage = 10; // 该变量决定了滚动滑块的长度该长度是由nPage/(nMax-nMin)的大小决定的
si.nPos = 0; // 滑块的当前位置它必须在nMin和nMax的范围内
SetScrollInfo (hWnd, Bar, &si, bRedraw);
```
4 是清单 1 中的程序运行起来的效果
![滚动条的处理](figures/Part1Chapter07-04.jpeg)
__图 4__ 滚动条的处理