免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1100 | 回复: 0
打印 上一主题 下一主题

《Linux程序设计》学习笔记06——curses函数库 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-28 20:07 |只看该作者 |倒序浏览


  Normal
  0
  
  7.8 磅
  0
  2
  
  false
  false
  false
  
   
   
   
   
   
   
   
   
   
   
   
   
  
  MicrosoftInternetExplorer4



/* Style Definitions */
table.MsoNormalTable
        {mso-style-name:普通表格;
        mso-tstyle-rowband-size:0;
        mso-tstyle-colband-size:0;
        mso-style-noshow:yes;
        mso-style-parent:"";
        mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
        mso-para-margin:0cm;
        mso-para-margin-bottom:.0001pt;
        mso-pagination:widow-orphan;
        font-size:10.0pt;
        font-family:"Times New Roman";
        mso-fareast-font-family:"Times New Roman";
        mso-ansi-language:#0400;
        mso-fareast-language:#0400;
        mso-bidi-language:#0400;}
欢迎转载,请保留作者信息
bill@华中科技大学
http://billstone.cublog.cn
  
Curses标准作为过渡,位于简单的文本行程序和完全图形化界面(一般也更难于编程)的X视窗系统程序(如GTK/GNOME和Qt/KDE)之间。
Curses函数库的名称来自它所提供的功能,它能够优化光标的移动并减少需要对屏幕进行的刷新,因此它也减少了必须向字符终端发送的字符数目。

基本使用方法
Curses例程工作在屏幕、窗口和子窗口上。所谓“屏幕”就是正在写的设备(通常是终端屏幕,也有可能是xterm屏幕)。Curses函数库使用两个数据结构来映射终端屏幕,它们是stdscr和curscr。其中stdscr数据结构对应的是“标准屏幕”,它的工作原理和stdio函数库中的标准输出stdout非常相似,它是curses程序中的默认输出插口;而curscr数据结构和stdscr相似,但它对应的是当前屏幕的样子。
一个使用curses函数库的典型例程如下:

  
  #include
  
  #include
  
  #include
  
   
  int
  main()
  {
          initscr();
   
          move(5,15);
          printw("%s", "Hello
  World!");
          refresh();
   
          endwin();
   
          exit(0);
  }
  

当对使用curses函数库的程序进行编译时,必须在程序中包含头文件curses.h,它是需要在编译命令行中用-lcurses选项对curses函数库进行链接。
从上面的程序可以看到,所有curses程序必须以初始化函数initscr开始,以函数endwin结束。函数initscr在一个程序中只能调用一次。
提示:我们可以先调用endwin函数退出curses,然后通过调研clrearok(strscr,1)和refresh函数继续curses操作。这样,实际上是首先让curses忘记物理屏幕的样子,然后强迫它执行一次完整的屏幕原文重现。
函数move和printw的功能是移动光标和在当前位置上输出文本。在调用refresh函数之前,输出到stdscr上的内容是不会显示在屏幕上的。refresh函数的作用就是刷新物理屏幕。
当需要在屏幕上显示比较松散的多行文本时,典型方式就是通过move函数与printw函数的配合来完成。
简单来说,Curses函数库有几种函数:屏幕输出函数、输入函数、清除函数和光标移动函数。通过这几种函数的配合,我们就可以实现一个简单的全屏界面。
字符属性:每个curses字符都可以有特定的属性,该属性控制着该字符在屏幕上的显示方式,前提是用于显示的硬件设备能够支持要求的属性。预定义的属性有A_BLINK、A_BOLD、A_DIM、A_REVERSE、A_STANDOUT和A_UNDERLINE。相关函数有attron、attroff和attrset等。一个典型的使用片段如下:

  
          move(5,15);
          attron(A_BOLD);
          printw("%s", "Hello
  World!");
          attroff(A_BOLD);
          refresh();
  

键盘:curses函数库还提供了控制键盘的简单方法。通过调用两个echo函数,我们可以简单地关闭或开启输入字符的回显功能。通过调用break函数,可以将输入模式设置为字符中止模式,在这种模式下,字符一经键入立刻传递给程序,而不是像在行模式中那样首先缓存字符,知道用户按下回车键才将用户输入的字符传递给程序。通过调用两个raw函数则可以关闭或开启特殊字符的处理。
提示:curses环境下,输入模式分行模式和字符中止模式。默认输入模式是行模式,当用户键入回车符时才会将输入的数据传递给程序;而字符中止模式则当字符一经键入就传递给程序。

窗口与子窗口
Curses函数库在物理屏幕上能够同时显示多个不同尺寸的窗口。
在curses环境下,窗口由WINDOW数据结构来表示。实际上,标准屏幕stdscr只是WINDOW结构的一个特例。下面是一个使用了窗口的例程

  
  #include
  
  #include
  
  #include
  
   
  int
  main()
  {
          WINDOW *new_window;
          int x,y;
          char letter = 'a';
   
          initscr();
          for(y=0;y
                  for(x=0;x
                          mvwaddch(stdscr, y,
  x, letter);
                          if(++letter > 'z')
                                  letter = 'a';
                  }
          refresh();
          sleep(2);
   
          new_window = newwin(10,20,5,5);
          box(new_window, '|', '-');
          mvwprintw(new_window, 2, 2,
  "%s", "Hello World");
          wrefresh(new_window);
          sleep(2);
   
          mvwin(new_window, 10, 10);
          wrefresh(new_window);
          sleep(2);
          delwin(new_window);
          endwin();
   
          return 0;
  }
  

上面的例程中,先在全屏幕上填满字符,然后创建一个10*20的新窗口,继而在新窗口上输出“Hello,World”。
新窗口的建立是由newwin函数来实现的,它指定了新窗口的大小和位置。删除一个窗口时则使用delwin函数。函数box的作用在于使用特殊的字符来界定新窗口。
用于窗口的通用函数有几类:前缀w用于窗口、前缀mv用于光标移动、前缀mvw用于在制定窗口中移动光标。wrefresh函数用于刷新窗口。而mvwin函数的作用是移动指定的窗口到指定的位置;如果移动后窗口超出屏幕范围,mvwin函数调用将会失败。
子窗口是多窗口的一种特例,我们使用subwin函数和delwin函数创建和删除子窗口。与前面提到的新窗口相比,子窗口没有自己独立的屏幕字符存储空间,它们与它们的父窗口(在调用subwin时指定)共享同一字符存储空间。这意味着,对子窗口中内容的任何修改都会反映到它的父窗口中,所以删除子窗口时,屏幕不会发生任何变化。
子窗口主要的用途是提供了一种简洁的方式来卷动另一窗口里的部分内容。在编写curses程序时,经常需要卷动屏幕的某个小区域,将这个小区域定义为一个子窗口,然后对其卷动,就能达到我们想要的效果。
注意:使用子窗口有个强加的限制:在应用程序刷新屏幕之前必须先对其父窗口调用touchwin函数。

keypad模式
curses函数库提供了一个精巧的用于管理功能键的功能。对每个终端来说,它的每个功能键所对应的转义序列都被保存,通常是保存在一个terminfo结构中,而头文件curses.h通过一组以KEY_为前缀的定义来管理逻辑键。
curses在启动时会关闭转义序列与逻辑键之间的转换功能,这功能需要通过调用keypad函数来启用。
实际上,使用keypad模式还是有一定的限制的:
1)识别escape转义序列的过程是与时间相关的。在处理许多网络协议时这个问题会变得很突出,唯一解决办法是设法对终端进行编程,让它针对用户希望使用的每个功能键只发送一个单独的、唯一的字符,但这将限制可使用的控制字符的数目。
2)为了让curses能够区分“单独按下Escapce键”和“一个以Escape字符开头的键盘转义字符”,它必须等待一小段时间。
3)curses不能处理二义性的Escape转义序列。如果你的终端上两个不同的按键会产生完全相同的转义序列,就回导致curses不知该返回哪个逻辑按键。Curses对这一问题的处理方式是简单地放弃对这个转义序列的处理。

彩色显示
鉴于历史性原因,curses只能以一种非常受限的方式来使用彩色。
Curses函数库对颜色的支持有些不同:字符颜色的定义及其背景色的定义并不完全独立。必须同时定义一个字符的前景色和背景色,称为颜色组合。
把颜色作为字符属性使用之前,必须首先调用init_pair函数对装备使用的颜色组合进行初始化,而对颜色属性的访问则通过COLOR_PAIR函数来完成。而颜色属性的激活则由wattron函数来完成,它的第二个参数指定了需要设置的颜色属性。

Pad
在编写高级curses程序时,有时需要先建立一个逻辑屏幕,然后再把它的全部或者部分内容输出到物理屏幕上。Curses提供了一个特殊的数据结构pad来解决这个问题。
Pad结构非常类似于WINDOW结构,所有执行写窗口操作的curses函数同样可以应用于pad。但是pad有自己的创建函数newpad和刷新函数prefresh。

本章最后展示了一个CD唱片应用程序的完整代码。它详细地描述了如何使用curses来编写应用程序,为我们自己设计使用curses函数库带来了很大的帮助。
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/47687/showart_1979880.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP