Chinaunix首页 | 论坛 | 博客
  • 博客访问: 592417
  • 博文数量: 92
  • 博客积分: 5026
  • 博客等级: 大校
  • 技术积分: 1321
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-28 11:04
文章分类

全部博文(92)

文章存档

2011年(9)

2010年(17)

2009年(12)

2008年(54)

我的朋友

分类: C/C++

2008-05-13 11:11:37


 
接上

#if defined(TRACE) || defined(NCURSES_TEST)
extern NCURSES_EXPORT_VAR(int) _nc_optimize_enable; /* enable optimizations */
#ifdef _XOPEN_SOURCE_EXTENDED
extern NCURSES_EXPORT(const char *) _nc_viswbuf(const wchar_t *);
#endif
extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *);
#define OPTIMIZE_MVCUR 0x01 /* cursor movement optimization */
#define OPTIMIZE_HASHMAP 0x02 /* diff hashing to detect scrolls */
#define OPTIMIZE_SCROLL 0x04 /* scroll optimization */
#define OPTIMIZE_ALL 0xff /* enable all optimizations (dflt) */
#define TRACE_MOVE 0x0008 /* trace cursor moves and scrolls */
#define TRACE_CHARPUT 0x0010 /* trace all character outputs */
#define TRACE_ORDINARY 0x001F /* trace all update actions */
#define TRACE_CALLS 0x0020 /* trace all curses calls */
#define TRACE_VIRTPUT 0x0040 /* trace virtual character puts */
#define TRACE_IEVENT 0x0080 /* trace low-level input processing */
#define TRACE_BITS 0x0100 /* trace state of TTY control bits */
#define TRACE_ICALLS 0x0200 /* trace internal/nested calls */
#define TRACE_CCALLS 0x0400 /* trace per-character calls */
#define TRACE_DATABASE 0x0800 /* trace read/write of terminfo/termcap data */
#define TRACE_ATTRS 0x1000 /* trace attribute updates */

#define TRACE_SHIFT 13 /* number of bits in the trace masks */
#define TRACE_MAXIMUM ((1 << TRACE_SHIFT) - 1) /* maximum trace level */

#if defined(TRACE) || defined(NCURSES_TEST)
extern NCURSES_EXPORT_VAR(int) _nc_optimize_enable; /* enable optimizations */
#ifdef _XOPEN_SOURCE_EXTENDED
extern NCURSES_EXPORT(const char *) _nc_viswbuf(const wchar_t *);
#endif
extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *);
#define OPTIMIZE_MVCUR 0x01 /* cursor movement optimization */
#define OPTIMIZE_HASHMAP 0x02 /* diff hashing to detect scrolls */
#define OPTIMIZE_SCROLL 0x04 /* scroll optimization */
#define OPTIMIZE_ALL 0xff /* enable all optimizations (dflt) */
#endif

#ifdef __cplusplus

/* these names conflict with STL */
#undef box
#undef clear
#undef erase
#undef move
#undef refresh

}
#endif

#endif /* __NCURSES_H */



看完了ncurses.h头文件里面的函数应该知道这个文件里面的函数能满足大家很多要求了,比如写一个界面,画个图什么的,甚至于写一个编辑器!用curses库有个特点,就是要初始化一个窗口用函数initscr();后面要用函数endwin来说明窗口结束!
那么下面就看一看学习的笔记!

我们现在知道了:在程序中调用initscr()函数,会让屏幕初始化并进入CURSES模式。还有一些其它的函数可以根据我们自己的方案初始化 CURSES。不同的初始化函数可以让屏幕进入不同的显示模式。比如:终端模式(terminal mode)、彩色模式(color mode)、鼠标模式(mouse mode)等等……

通常情况下,用户输入的字符将被终端程序送入终端的缓冲区。但当用户输入换行符时,终端程序将会中断,同时输出当前的缓冲区内容并启用新行的输出缓冲。但是大多数程序需要当用户输入单个字符时,却希望这些字符能够立即显示在屏幕上。这两个函数就是用来禁用行缓冲(line buffering)。这两个函数所初始化的的模式同样可以用来给程序传送控制字符,比如:挂起(CTRL-Z)、中断或退出(CTRL-C)。区别在于,在raw()函数模式下,这些字符将传送给程序去处理而不作为终端程序处理的信号。在cbreak()模式下,这些控制字符将被认为是终端驱动程序中的控制字符,因而将这些字符传送给终端程序。我比较喜欢使用raw(),那样可以进行更多的控制操作。

这两个函数控制用户输入的键盘回显。就是在运行程序的时候是否将输入的字符出现在屏幕上。比如你的程序在运行时你需要使用控制字符,但是你不想让控制字符出现在屏幕上,就可以使用这两个函数。也就是说当用户调用getch()函数向程序输入数据时,你不想让他输入的字符出现在屏幕上。noecho()函数就可以不让控制字符(比如CTRL-C)出现在屏幕上。大多数的交互式程序要进入控制模式的时候,一般都使用echo()、noecho()函数初始化、关闭键盘回显。这样给了程序员更大的灵活性。


这个函数允许使用功能键:F1、F2、方向键等等……几乎所有的交互式程序都使用这个函数。令用户使用方向键控制整个用户界面。使用keypad (stdscr,TURE)就可以在“标准显示设备”(stdscr)上使用这些功能。在以后的章节中将详细讨论如何使用功能键。



这个函数虽然不经常使用。但有时却非常有用。halfdelay()函数会启用半延时模式(half-delay mode)。和cbreak()函数一样,当程序需要当用户输入这些字符时,它们能够立即显示在屏幕上。但是它要停滞一段限定时间(以0.1秒为单位)等待输入,如果没有有效的输入,返回ERR。给halfdelay()传递一个整型参数(以0.1秒为单位)。它就会按照参数中的时间等待用户输入。一般来说,这个函数在需要等待的输入的程序中可以被用到,如果用户没有及时做出响应,程序就可以去处理其它的事情了。最常见到的应用例子是在输入密码的出超时响应。


上面的提到的这些函数可以定制CURSES在初始化后的行为。这些函数不能被广泛使用在程序的各个部分。所以,这些函数的调用要处在整个CURSES会话的开始部分。

一个例子

让我们写一个程序用来说明这些函数的用法。

CODE:
例2. 初始化函数用法的示例:
#include ;
int main()
{ int ch;
initscr(); /* 开始curses模式 */
raw(); /* 禁止行缓冲 */
keypad(stdscr, TRUE); /* 开启功能键响应模式 */
noecho(); /* 当执行getch()函数的时候关闭键盘回显 */
printw("Type any character to see it in bold\n");
ch = getch(); /* 如果没有调用raw()函数,必须先按下enter键才可以执行下面的程序 */
if(ch == KEY_F(1)) /* 如果没有调用keypad()初始化,将不会执行这条语句 */
printw("F1 Key pressed"); /* 如果没有使用 noecho() 函数,一些难看的控制字符将会被打印到屏幕上 */
else { printw("The pressed key is ");
attron(A_BOLD);
printw("%c", ch);
attroff(A_BOLD);
}
refresh(); /* 将缓冲区的内容打印到的显示器上 */
getch(); /* 等待用户输入 */
endwin(); /* 结束curses模式 */
return 0;
}

这个程序很简单,不需要太多的说明。但还是有一些前面没有提到的函数。getch()函数用来取得用户输入的信息。它和通常的getchar()函数相似。但是getch()可以让我们在禁用行缓冲时避免在输入完成后还要按enter键麻烦。在后面的章节中我们也将讨论到这些输入函数。attron()和 attroff()函数作为切换开关用来开启和关闭给字符增加一些修饰效果。在这个例子中,它们使显示的字符字体加粗。在后面的部分中我们也将讨论到这些函数。


代码好像有点问题议

gcc编译
提示TURE那一行有错误,没定义什么的,
后来我把TURE改成了1
编译成功

CODE:
the code is


#include ;
int main(void)
{int c;
initscr();
keypad(stdscr,1);
noecho();
raw();
printw("jasdjsalfkjlsdjkflsdkjfljkasdkjlf\n");
getch();
if(getch()==KEY_F(1))
printw("f1 jaslkdjlasd");
else
{
printw("The pressed key is ");
attron(A_BOLD);
printw("%c", getch());
attroff(A_BOLD);
}
refresh();
getch();
endwin();
return 0;
}

(A Word about Windows)

在我们进入数以万计的CURSES函数以前,让我们先了解一下窗口(windows)的知识。关于窗口机制的详细信息我们会在以后的章节中详细介绍。这一章只是一些基础的知识,为了给讲解输入输出函数作铺垫。当然,在现在就树立一个窗口的概念是很有好处的。

窗口实质上是由CURSES系统定义的一个假想的屏幕。这种窗口并不像Windows平台上的窗口,这些窗口没有边框。当CURSES初始化的时候,它会默认创建一个叫做stdscr的窗口。这个窗口的大小一般是80列,25行的屏幕(根据显示器或者显卡的不同,可能会出现不同的大小)如果你运行简单的任务,比如打印几个字符串、输入一些数据等等……这样的单窗口完全可以满足你的需要。当然,你也可以通过窗口系统的函数创建你自己的窗口。

举个例子,如果你调用以下函数:

CODE:
printw(“Hi! There!”);
refresh();

它会在stdscr上的当前光标位置输出“Hi! There!”。同样,调用refresh()函数,它只更新stdscr上的缓冲区。

例如,你已经建立了一个叫做win的窗口。你要在这个窗口上输出以上的内容。只需要在普通的函数前添加w前缀就可以了。同时,函数中的参数也要相应的变化(要指明你所要显示信息的窗口):

CODE:
wprintw(win, "Hi There !!!");
wrefresh(win);

你将在这份文档的其余部分看到,这些函数有相同的命名规则。

CODE:
printw(string); /* 在stdscr的当前光标位置打印字符串string */
mvprintw(y, x, string); /* 将字符串string打印在坐标(y,x)处 */
wprintw(win, string); /* 在窗口win的当前光标位置打印字符串string */ mvwprintw(win, y, x, string); /* 移动到窗口win的(y,x)然后打印字符串string */

后来编译遇到如下错误,查看这里的学习资料,仔细看就明白了!

CODE:
[ljjk@localhost ljjk]$ gcc -l curses -o 12321 12321.c
12321.c: In function `main':
12321.c:6: `win' undeclared (first use in this function)
12321.c:6: (Each undeclared identifier is reported only once
12321.c:6: for each function it appears in.)

后来问题得到了解决

CODE:
#include ;
#include ;
int main(void)
{
initscr();
wprintw(win,"hello");
wrefresh(win);

endwin();
}




this is the code

我们已经通过一些例子看到了修饰(Attributes)输出文字的效果。给某些文字加上修饰会使文字更加醒目和美观。在某些程度上也会增加输出信息的可读性。下面这个程序将会把一个C语言的源程序文件的注释部分用使用粗体(BOLD)输出。

CODE:
例:一个简单的文字修饰的例子:



#include ;

int main(int argc, char *argv[])
{
int ch, prev;
FILE *fp;
int goto_prev = FALSE, y, x;
if(argc != 2)
{
printf("Usage: %s \n", argv[0]);
exit(1);
}
fp = fopen(argv[1], "r"); /* 在这里检测文件是否成功打开 */
if(fp == NULL)
{
perror("Cannot open input file");
exit(1);
}
initscr(); /* 初始化并进入CURSES模式 */
prev = EOF;
while((ch = fgetc(fp)) != EOF)
{
if(prev == '/' && ch == '*') /* 当读到字符“/”和“*”的时候调用开启修饰函数 */
{
attron(A_BOLD); /* 将“/”和“*”及以后输出的文字字体加粗 */
goto_prev = TRUE;
}
if(goto_prev == TRUE) /* 回到“/”和“*”之前开始输出 */
{
getyx(stdscr, y, x);
move(y, x - 1);
printw("%c%c", '/', ch); /* 实际打印内容的部分 */
ch = 'a'; /* 避免下次读取变量错误,这里赋一个任意值*/
goto_prev = FALSE; /* 让这段程序只运行一次 */
}
else
printw("%c", ch);
refresh(); /* 将缓冲区的内容刷新到屏幕上 */
if(prev == '*' && ch == '/')
attroff(A_BOLD); /* 当读到字符“*”和“/”的时候调用修饰关闭函数*/
prev = ch;
}
getch();
endwin(); /* 结束并退出Curses模式 */
return 0;
}

不用去理睬那些初始化部分和其它没用的部分。把注意集中在上面的这个while循环体中。这个循环读取文件中每个字符并寻找有“/*”(注释起始处标志)的地方。一旦找到,就会调用attron()函数开始为输出文字加粗加亮。当找到“*/”(注释结束处标志)的地方,就会使用attroff()函数关闭修饰效果。


这个程序介绍了两个十分有用的函数:getyx()和move()。getyx()函数其实是一个定义在ncurses.h中的宏,它会给出当前光标的位置。由于getyx()不是一个通常所指的函数,因此我们不能向它传递指针,只可以传递一对整型变量(前文提到过)。函数move()将光标移动到指定位置。(译者注:在这里再次强调:所有这些函数中使用行列坐标的时候是先行列后列。就是先写y坐标,再写x坐标。)很多初学者因为数学上的使用习惯而使用了先行后列的方式。(在这里一定要注意!)


这个程序执行的任务非常简单,无需作过多的说明。这个程序对于分析C程序十分有帮助。你也可以试着将输出文字的颜色改变为其它颜色。也可以将这个程序扩展为分析其它语言程序的工具。


让我们来更多的了解一下输出修饰。attron()函数、attroff()函数和attrset()函数以及他们的姊妹函数(sister functions)比如attr_get()等等……可以用这些函数创造出生动有趣的显示效果。


attron()函数和attroff()函数分别用来开启(on)或关闭(off)输出修饰。以下这些修饰属性已经定义在头文件CURSES.h中。可以在函数中使用:

A_NORMAL 普通字符输出 (不加亮显示)
A_STANDOUT 终端字符最亮
A_UNDERLINE 下划线
A_REVERSE 字符反白显示
A_BLINK 闪动显示
A_DIM 半亮显示
A_BOLD 加亮加粗
A_PROTECT 保护模式
A_INVIS 空白显示模式
A_ALTCHARSET 字符交?
A_CHARTEXT 字符掩盖
COLOR_PAIR(n) 前景、背景色设置


(注:经过译者试验(见试验程序lst01.c),上述修饰中只有A_NORMAL、A_BLINK、A_DIM、A_INVIS、A_BOLD、 A_STANDOUT和A_REVERSE有效。且A_STANDOUT和A_REVERSE具有相同的输出结果。也许是笔者的试验环境问题,也许是笔者的这个测试程序还不完备。还请读者能够在自己所使用的系统上测试,欢迎把测试结果给我。如果你有更好的测试程序,我更加希望你能通过E-mail寄给我。)


最后一个修饰是最吸引人的,它可以设置输出的字符及背景的颜色。颜色的设置将在后面章节详细介绍。


我们可以给一段输出同时设定多种修饰。这样可以得到多种结合的效果。如果你想反白显示字符并同时让字符闪烁。只需要在两种修饰属性间加一个“|”字符就可以了:



attron(A_REVERSE | A_BLINK);


现在我们该讨论讨论attron()函数和attrset()函数之间的区别了。attrset()为整个窗口设置一种修饰属性。而attron()函数只从被调用的地方开始设置。所以attrset()会覆盖掉你先前为整个窗口设置的任何修饰属性。就像在窗口的开始处开启修饰,在窗口结尾处关闭修饰属性一样。这两种方法为我们管理输出修饰属性提供了更简单、更富有弹性的方法。但是,如果你粗心的话,可能会让整个屏幕变得十分杂乱无章,函数之间的调用会难以管理。这种情况,尤其在某些利用到菜单的程序中出现的十分普遍。所以,事先做好设计,然后按照设计去实施会效果会好得多。你可以经常使用 standend()函数关闭所有设置的修饰。这个函数的作用和attrset(A_NORMAL)函数是相同的。


attr_get()函数用来取得当前窗口的修饰属性设置以及背景、文字颜色。虽然这个函数不像上面的那些函数常用。但它却对检测屏幕区域的修饰属性设置很有用。当我们在屏幕输出一些混合的复杂修饰效果时,这个函数可以告诉我们每一个字符关联的修饰。这个函数必须在设置了attrset()或者 attron()函数之后使用。


这些函数都有attr_的前缀,比如:attr_set()、attr_on()等等……它们的作用和上面的函数一样,只不过要在调用时添加一定的参数。


这些函数的作用范围是某一个指定的窗口。而上面的函数只作用在默认的stdscr上。


chgar()函数被列在curs_attr的man_page 的最末尾。事实上它是一个很有用的函数。它可以在不移动光标位置的情况下修改已输出的字符的修饰效果。它从光标当前位置处开始,以一个整型参数作为修改字符的个数。给这些字符设置某一种修饰属性。


当我们整型参数赋值为-1时,它代表一行修饰。如果你想从当前光标位置使整个一行的输出修饰变为反白显示时,可以这样使用:

chgat(-1, A_REVERSE, 0, NULL);
这个函数经常被用来修改已输出的字符的修饰。当然,你也可以根据自己的需要选择要修改的起始点和终止点。


这一类的函数还包括wchgat(), mvchgat()。它们的使用方法和差不多chgat(),只不过wchgat()要指定一个窗口。mvchgat()将光标先移动到指定位置,然后才执行剩下的修饰部分。同样的,chgat()是一个宏,只不过用stdscr替代了指定的窗口。大部分不带w前缀的函数都是以stdscr作为默认窗口的宏。

CODE:
例:mvchgat()用法示例:



#include ;

int main(int argc, char *argv[])
{
initscr(); /* 进入 curses 模式 */
start_color(); /* 开启颜色管理功能 */

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);
/*
*第一、二个参数表明了函数开始的位置
*第三个参数是被改变修饰的字符的数目,-1表示一整行
*第四个参数是被改变的修饰名
*第五个参数是颜色索引。颜色索引已经在init_pair()中被初试化了
*如果用0表示不使用颜色。
*最后一个总是NULL,没什么特别的意义。
*/
refresh();
getch();
endwin(); /* 结束curses模式 */
return 0;
}



CODE:
ncurses学习笔记
现在会用curses里的光标定位和键盘事件了,
代码实例如下


#include ;
int main(void)
{
int x,y;
initscr();
keypad(stdscr,1);
refresh();
x=9,y=6;
mvprintw(y,x,"hdkajsdkjaskdahskdjas");
while(getch() != KEY_LEFT)
{
if(getch()==KEY_DOWN)
{

mvprintw(1,1,"hafkjsdhkfhsdjfsd");

}
if(getch()==KEY_RIGHT)
{
mvprintw(9,9,"nilaopo ge jiba");

}
if(getch()==KEY_UP)
{
mvprintw(y-1,x,"nihao a ,wo jiao liuqi hen kaixin ");
}
}
endwin();
return 0;
}
~
~

学习笔记---光标定位的实现
学习linux下的编程真是比win下的还有意思,写了一小段码码!当给大家学习用的了

CODE:
#include ;
int main(void)
{
int x,y,a,b;
initscr();
keypad(stdscr,2);
refresh();
getmaxyx(stdscr,a,b);
x=0,y=0;
mvprintw(y,x,"%d",a);
while(getch() != KEY_LEFT)
{
/* y++;
if(x>;a)
{
x++;
} */
switch (getch())
{
case KEY_DOWN:
y++;
move(y,x);
break;
case KEY_RIGHT:
x++;
move(y,x);

break;
case KEY_UP:
y--;
move(y,x);
break;
}

}
endwin();
return 0;
}

关于curses库的介绍暂时就先介绍这么多,以上的内容!
头文件在usr/include目录下可以找到
有些资料是参考某些教程的!相关资料可以找我要!或者在下面留下email我会发给您的!
或者到我的站里面找到!
谢谢
阅读(5509) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~