使用 curses 来操作窗口数据

初始化 cursess 时,会自动提供 stdscr。 可使用 curses 子例程库操作 stdscr,或可以创建用户定义的窗口。

创建窗口

您可以使用 newwin 子例程创建自己的窗口。

每次调用 newwin 子例程时,curses 均会在内存中分配新的窗口结构。 此结构包含与新窗口相关的所有信息。 curses 不限制可创建窗口的数目。 嵌套子窗口的数目受限于可用内存的容量,最多可达到在 /usr/include/limits.h 文件中定义的 SHRT_MAX 值。

可以更改窗口而无需考虑它们的创建顺序。 在调用 wrefresh 子例程的过程中对终端显示器进行更新。

子窗口

必须为与终端显示器相关的子窗口提供坐标。 使用 subwin 子例程创建的子窗口必须符合父窗口的界限。 否则,将返回空值。

pad

使用以下子例程创建 pad:
子例程 描述
新闻板 创建 pad 数据结构。
子板 在 pad 内创建子 pad,并返回指向子 pad 的指针。

除去窗口、pad 和子窗口

相对于其父 pad 定位新的子 pad。

要除去窗口、pad 或子窗口,请使用 delwin 子例程。 在删除窗口或 pad 之前,必须已将其子对象删除;否则,delwin 子例程将返回错误。

更改屏幕图像或窗口图像

curses 子例程更改窗口外观时,窗口的内部表示将更新,但在下一次调用 wrefresh 子例程之前显示保留不变。 wrefresh 子例程使用窗口结构中的信息更新显示。

刷新窗口

不论何时将输出写到窗口或 pad 结构,必须刷新终端显示器以与内部表示相匹配。 刷新执行以下操作:

  • 将 curscr 的内容与用户定义的或 stdscr 的内容进行比较
  • 更新 curscr 结构以与用户定义或 stdscr 相匹配
  • 重新绘制已经更改的物理显示器的一部分

使用以下子例程刷新窗口:

子例程 描述
刷新wrefresh 更新终端和 curscr 以反映对窗口所作的更改。
wnoutrefreshdoupdate 更新指定窗口,并立即将它们输出到终端。 当进行多次更新时,这些子例程对于快速响应将有所帮助。

refreshwrefresh 子例程首先调用 wnoutrefresh 子例程以将正在刷新的窗口复制到当前屏幕。 然后,它们调用 doupdate 子例程来更新显示。

如果需要同时刷新多个窗口,那么请使用以下两种可行方法之一。 可对导致交替调用 wnoutrefreshdoupdate 子例程的 wrefresh 子例程进行一系列调用。 还可对每个窗口调用一次 wnoutrefresh 子例程,然后再调用一次 doupdate 子例程。 在使用第二种方法时,仅向显示器发送一个脉冲串的输出。

用于刷新 pad 的子例程

prefreshpnoutrefresh 子例程类似于 wrefreshwnoutrefresh 子例程。

prefresh 子例程更新当前屏幕和物理显示器,而 pnoutrefresh 子例程更新 curscr 以反映对用户定义的 pad 所作的更改。 因为涉及到的是 pad 而不是窗口,这些子例程需要附加参数来指示哪部分 pad 和屏幕牵涉其中。

刷新尚未更改的区域

在刷新期间,仅在显示器上重新绘制那些已改变的区域。 可使用 touchwintouchline 子例程刷新未变的显示区域:
子例程 描述
接触线 强制在下一次调用 wrefresh 子例程时刷新一系列行。
touchwin 在下次调用 wrefresh 子例程时,强制刷新窗口字符数组中的每一个字符。 touchwin 子例程不保存优化信息。 对于重叠窗口,此子例程很有用处。

处理子窗口或重叠窗口时,将 touchwinwrefresh 子例程合并将会有所帮助。 要将一窗口从另一窗口后调至前面,请调用后跟 wrefresh 子例程的 touchwin 子例程。

显示乱码

如果使用非 curses 子例程(比如 echoprintf 子例程)将文本发送到终端显示器,那么外部窗口可能显示错乱。 在这种情况下,显示被更改了,但当前屏幕没有被更新,所以不能反映这些更改。 在错乱的屏幕上进行刷新可能引发问题,因为在屏幕显示错乱后,正在刷新的窗口和当前屏幕结构之间没有什么不同。 因此,由错乱的文本导致的显示器上的空格不更改。

移动窗口时,也会出现类似问题。 使用非 curses 子例程向显示器发送的字符不随窗口内部移动。

如果屏幕显示错乱,请调用 curscr 上的 wrefresh 子例程以更新显示,从而反映当前的物理显示。

操作窗口内容

创建窗口或子窗口后,程序经常是通过使用以下子例程来以某种方式操作它们:
子例程 描述
在窗口中或围绕窗口绘制框
文案 提供更多对 overlayoverwrite 子例程的精确控制
垃圾线 指示 curses 在写入任何东西之前必须废弃屏幕行并将其抛出
mvwin 将窗口或子窗口移动到一个新位置
覆盖 覆盖 将一个窗口复制到另一个窗口之上
防骗热线 从缺省屏幕除去一行

要使用 overlayoverwrite 子例程,必须将这两个窗口重叠。 overwrite 子例程具有破坏性,而 overlay 不具有破坏性。 使用 overwrite 子例程将文本从一个窗口复制到另一个窗口时,被复制窗口的空白部分将覆盖复制到的窗口的任何部分。 overlay 子例程不具破坏性,因为它不复制被复制窗口的空白部分。

类似于 overlayoverwrite 子例程,copywin 子例程允许将某一窗口的一部分复制到另一个窗口。 不同于 overlayoverwrite 子例程,使用 copywin 子例程时,窗口不需要重叠。

要从 stdscr 除去行,可使用 ripoffline 子例程。 如果将一个正的 line 参数传递给此子例程,那么指定数目的行将会从 stdscr 的顶部除去。 如果将一个负的 line 参数传递给子例程,那么这些行将会从 stdscr 的底部除去。

要在写入任何新行之前废弃指定范围的行,可使用 garbagedlines 子例程。

支持过滤器

为作为过滤器的 curses 应用程序提供了 filter 子例程。 此子例程致使 curses 将 stdscr 仅作为单个行运作。 运行 filter 子例程时,curses 不使用需要了解 curses 所在行的任何终端功能。