我们已经看到了如何使用属性来打印具有特殊效果的字符的示例。谨慎地设置属性可以以简单易懂的方式呈现信息。以下程序接受 C 文件作为输入,并以粗体打印文件中的注释。浏览代码。
示例 5. 一个简单的属性示例
/* pager functionality by Joseph Spainhour" <spainhou@bellsouth.net> */
#include <ncurses.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int ch, prev, row, col;
prev = EOF;
FILE *fp;
int y, x;
if(argc != 2)
{
printf("Usage: %s <a c file name>\n", argv[0]);
exit(1);
}
fp = fopen(argv[1], "r");
if(fp == NULL)
{
perror("Cannot open input file");
exit(1);
}
initscr(); /* Start curses mode */
getmaxyx(stdscr, row, col); /* find the boundaries of the screeen */
while((ch = fgetc(fp)) != EOF) /* read the file till we reach the end */
{
getyx(stdscr, y, x); /* get the current curser position */
if(y == (row - 1)) /* are we are at the end of the screen */
{
printw("<-Press Any Key->"); /* tell the user to press a key */
getch();
clear(); /* clear the screen */
move(0, 0); /* start at the beginning of the screen */
}
if(prev == '/' && ch == '*') /* If it is / and * then only
* switch bold on */
{
attron(A_BOLD); /* cut bold on */
getyx(stdscr, y, x); /* get the current curser position */
move(y, x - 1); /* back up one space */
printw("%c%c", '/', ch); /* The actual printing is done here */
}
else
printw("%c", ch);
refresh();
if(prev == '*' && ch == '/')
attroff(A_BOLD); /* Switch it off once we got *
* and then / */
prev = ch;
}
endwin(); /* End curses mode */
fclose(fp);
return 0;
} |
不要担心所有那些初始化和其他废话。专注于 while 循环。它读取文件中的每个字符并搜索模式 /*。一旦发现该模式,它就会使用以下代码打开 BOLD 属性:attron()。当我们得到模式 */ 时,它会被以下代码关闭:attroff() .
上面的程序还向我们介绍了两个有用的函数:getyx()和move()。第一个函数将当前光标的坐标获取到变量 y, x 中。由于 getyx() 是一个宏,我们不必传递变量的指针。函数move()将光标移动到给定的坐标。
上面的程序实际上是一个简单的程序,功能不多。沿着这些思路,可以编写一个更有用的程序,该程序读取 C 文件,解析它并以不同的颜色打印它。甚至可以将其扩展到其他语言。
让我们深入了解属性的更多细节。函数attron(), attroff(), attrset(),及其姊妹函数attr_get()等等,可用于打开/关闭属性、获取属性并产生彩色显示。
函数 attron 和 attroff 接受属性的位掩码,并分别打开或关闭它们。以下视频属性(在 <curses.h> 中定义)可以传递给这些函数。
A_NORMAL Normal display (no highlight) A_STANDOUT Best highlighting mode of the terminal. A_UNDERLINE Underlining A_REVERSE Reverse video A_BLINK Blinking A_DIM Half bright A_BOLD Extra bright or bold A_PROTECT Protected mode A_INVIS Invisible or blank mode A_ALTCHARSET Alternate character set A_CHARTEXT Bit-mask to extract a character COLOR_PAIR(n) Color-pair number n |
最后一个是最丰富多彩的 :-) 颜色将在下一节中解释。
我们可以对任意数量的上述属性进行 OR(|) 运算,以获得组合效果。如果您想要具有闪烁字符的反相视频,可以使用
attron(A_REVERSE | A_BLINK); |
那么 attron() 和 attrset() 之间有什么区别呢?attrset 设置窗口的属性,而 attron 只是打开赋予它的属性。因此,attrset() 完全覆盖窗口先前拥有的任何属性,并将其设置为新属性。同样,attroff() 只是关闭作为参数赋予它的属性。这使我们能够灵活地轻松管理属性。但是,如果您不小心使用它们,您可能会丢失对窗口具有哪些属性的跟踪,并使显示混乱。在管理带有颜色和突出显示的菜单时,尤其如此。因此,请确定一致的策略并坚持下去。您始终可以使用standend(),它等效于attrset(A_NORMAL),它关闭所有属性并将您带回正常模式。
函数 attr_get() 获取窗口的当前属性和颜色对。尽管我们可能不会像上面这些函数那样频繁地使用它,但在扫描屏幕区域时,它很有用。假设我们想要在屏幕上进行一些复杂的更新,并且不确定每个字符与什么属性关联。那么这个函数可以与 attrset 或 attron 一起使用,以产生所需的效果。
函数 chgat() 列在手册页 curs_attr 的末尾。它实际上是一个有用的函数。此函数可用于为一组字符设置属性而无需移动。我的意思是它!!!无需移动光标 :-) 它更改从当前光标位置开始的给定数量的字符的属性。
我们可以将 -1 作为字符计数,以更新到行尾。如果您想更改从当前位置到行尾的字符的属性,只需使用它。
chgat(-1, A_REVERSE, 0, NULL); |
当更改屏幕上已有的字符的属性时,此函数非常有用。移动到要更改的字符,然后更改属性。
其他函数 wchgat()、mvchgat()、wchgat() 的行为类似,只是 w 函数在特定窗口上运行。mv 函数首先移动光标,然后执行赋予它们的工作。实际上,chgat 是一个宏,它被替换为以 stdscr 作为窗口的 wchgat()。大多数“无 w”函数都是宏。
示例 6. Chgat() 用法示例
#include <ncurses.h>
int main(int argc, char *argv[])
{ initscr(); /* Start curses mode */
start_color(); /* Start color functionality */
init_pair(1, COLOR_CYAN, COLOR_BLACK);
printw("A Big string which i didn't care to type fully ");
mvchgat(0, 0, -1, A_BLINK, 1, NULL);
/*
* First two parameters specify the position at which to start
* Third parameter number of characters to update. -1 means till
* end of line
* Forth parameter is the normal attribute you wanted to give
* to the charcter
* Fifth is the color index. It is the index given during init_pair()
* use 0 if you didn't want color
* Sixth one is always NULL
*/
refresh();
getch();
endwin(); /* End curses mode */
return 0;
} |
此示例还向我们介绍了 curses 的颜色世界。颜色将在稍后详细解释。使用 0 表示无颜色。