使用 curses 来操作窗口数据
初始化 cursess 时,会自动提供 stdscr。 可使用 curses 子例程库操作 stdscr,或可以创建用户定义的窗口。
创建窗口
您可以使用 newwin 子例程创建自己的窗口。
每次调用 newwin 子例程时,curses 均会在内存中分配新的窗口结构。 此结构包含与新窗口相关的所有信息。 curses 不限制可创建窗口的数目。 嵌套子窗口的数目受限于可用内存的容量,最多可达到在 /usr/include/limits.h 文件中定义的 SHRT_MAX 值。
可以更改窗口而无需考虑它们的创建顺序。 在调用 wrefresh 子例程的过程中对终端显示器进行更新。
子窗口
必须为与终端显示器相关的子窗口提供坐标。 使用 subwin 子例程创建的子窗口必须符合父窗口的界限。 否则,将返回空值。
pad
除去窗口、pad 和子窗口
相对于其父 pad 定位新的子 pad。
要除去窗口、pad 或子窗口,请使用 delwin 子例程。 在删除窗口或 pad 之前,必须已将其子对象删除;否则,delwin 子例程将返回错误。
更改屏幕图像或窗口图像
curses 子例程更改窗口外观时,窗口的内部表示将更新,但在下一次调用 wrefresh 子例程之前显示保留不变。 wrefresh 子例程使用窗口结构中的信息更新显示。
刷新窗口
不论何时将输出写到窗口或 pad 结构,必须刷新终端显示器以与内部表示相匹配。 刷新执行以下操作:
- 将 curscr 的内容与用户定义的或 stdscr 的内容进行比较
- 更新 curscr 结构以与用户定义或 stdscr 相匹配
- 重新绘制已经更改的物理显示器的一部分
使用以下子例程刷新窗口:
| 子例程 | 描述 |
|---|---|
| 刷新或 wrefresh | 更新终端和 curscr 以反映对窗口所作的更改。 |
| wnoutrefresh 或 doupdate | 更新指定窗口,并立即将它们输出到终端。 当进行多次更新时,这些子例程对于快速响应将有所帮助。 |
refresh 和 wrefresh 子例程首先调用 wnoutrefresh 子例程以将正在刷新的窗口复制到当前屏幕。 然后,它们调用 doupdate 子例程来更新显示。
如果需要同时刷新多个窗口,那么请使用以下两种可行方法之一。 可对导致交替调用 wnoutrefresh 和 doupdate 子例程的 wrefresh 子例程进行一系列调用。 还可对每个窗口调用一次 wnoutrefresh 子例程,然后再调用一次 doupdate 子例程。 在使用第二种方法时,仅向显示器发送一个脉冲串的输出。
用于刷新 pad 的子例程
prefresh 和 pnoutrefresh 子例程类似于 wrefresh 和 wnoutrefresh 子例程。
prefresh 子例程更新当前屏幕和物理显示器,而 pnoutrefresh 子例程更新 curscr 以反映对用户定义的 pad 所作的更改。 因为涉及到的是 pad 而不是窗口,这些子例程需要附加参数来指示哪部分 pad 和屏幕牵涉其中。
刷新尚未更改的区域
处理子窗口或重叠窗口时,将 touchwin 和 wrefresh 子例程合并将会有所帮助。 要将一窗口从另一窗口后调至前面,请调用后跟 wrefresh 子例程的 touchwin 子例程。
显示乱码
如果使用非 curses 子例程(比如 echo 或 printf 子例程)将文本发送到终端显示器,那么外部窗口可能显示错乱。 在这种情况下,显示被更改了,但当前屏幕没有被更新,所以不能反映这些更改。 在错乱的屏幕上进行刷新可能引发问题,因为在屏幕显示错乱后,正在刷新的窗口和当前屏幕结构之间没有什么不同。 因此,由错乱的文本导致的显示器上的空格不更改。
移动窗口时,也会出现类似问题。 使用非 curses 子例程向显示器发送的字符不随窗口内部移动。
如果屏幕显示错乱,请调用 curscr 上的 wrefresh 子例程以更新显示,从而反映当前的物理显示。
操作窗口内容
要使用 overlay 和 overwrite 子例程,必须将这两个窗口重叠。 overwrite 子例程具有破坏性,而 overlay 不具有破坏性。 使用 overwrite 子例程将文本从一个窗口复制到另一个窗口时,被复制窗口的空白部分将覆盖复制到的窗口的任何部分。 overlay 子例程不具破坏性,因为它不复制被复制窗口的空白部分。
类似于 overlay 和 overwrite 子例程,copywin 子例程允许将某一窗口的一部分复制到另一个窗口。 不同于 overlay 和 overwrite 子例程,使用 copywin 子例程时,窗口不需要重叠。
要从 stdscr 除去行,可使用 ripoffline 子例程。 如果将一个正的 line 参数传递给此子例程,那么指定数目的行将会从 stdscr 的顶部除去。 如果将一个负的 line 参数传递给子例程,那么这些行将会从 stdscr 的底部除去。
要在写入任何新行之前废弃指定范围的行,可使用 garbagedlines 子例程。
支持过滤器
为作为过滤器的 curses 应用程序提供了 filter 子例程。 此子例程致使 curses 将 stdscr 仅作为单个行运作。 运行 filter 子例程时,curses 不使用需要了解 curses 所在行的任何终端功能。