1、安装Ncurses Ncurses是一个能提供功能键定义(快捷键),屏幕绘制以及基于文本终端的图形互动功能的动态库。 Ncurses是一个能提供基于文本终端窗口功能的动态库. Ncurses可以: · 只要您喜
          1、安装Ncurses
Ncurses是一个能提供功能键定义(快捷键),屏幕绘制以及基于文本终端的图形互动功能的动态库。
Ncurses是一个能提供基于文本终端窗口功能的动态库. Ncurses可以:
· 只要您喜欢,您可以使用整个屏幕
· 创建和管理一个窗口
· 使用8种不同的彩色
· 为您的程序提供鼠标支持
· 使用键盘上的功能键
Ubuntu下
mysea@mysea-desktop:~$ sudo apt-get install libncurses5-dbg libncurses5-dev mysea@mysea-desktop:~/test$ gcc -lncurses -o cursestest cursestest.c
Freebsd下
cd /usr/ports/devel/ncurses-devel make install clean
2、hello,world
#include <curses.h>
int main(void){
  initscr();//初始化
  box(stdscr,ACS_VLINE,ACS_HLINE);//画边框
  mvaddstr(15,2,"hello,world");//在15,2显示字符串
  refresh();//刷新屏幕
  getch();//等待按键
  endwin();//结束
  return 0;  
}
编译及运行
dp@dp:~/cursestest % gcc -lncurses 1.c -o mytest dp@dp:~/cursestest % ./mytest
3、色彩
然后编写下面代码:
#include <ncurses.h>
#include <locale.h>
#include <stdio.h>
int main(void){
//init_pair(short index,short foreground,short background)初始化颜色索引
//attron(COLOR_PAIR(索引号)|属性)
  setlocale(LC_ALL,"");
  initscr();//初始化
  box(stdscr,ACS_VLINE,ACS_HLINE);//画边框
  if (!has_colors()||start_color()==ERR){
    endwin();
    printf("终端不支持颜色\n");
    return 0;
  }
  init_pair(1,COLOR_GREEN,COLOR_BLACK);
  init_pair(2,COLOR_RED,COLOR_BLACK);
  init_pair(3,COLOR_WHITE,COLOR_BLUE);
  int i=0;
  for (i=1;i<=3;i++){
     attron(COLOR_PAIR(i));
     move(i,10);
     printw("hello,world:%d",i);
  }
  for (i=1;i<=3;i++){
     attron(COLOR_PAIR(i)|A_UNDERLINE);
     move(i+5,10);
     printw("hello,world:%d",i);
  }
  refresh();//刷新屏幕
  getch();//等待按键
  endwin();//结束
  
执行
4、对中文的支持
dp@dp:~/cursestest % cat 1.c
#include <ncurses.h>
#include <locale.h>
#include <stdio.h>
int main(void){
//init_pair(short index,short foreground,short background)初始化颜色索引
//attron(COLOR_PAIR(索引号)|属性)
  setlocale(LC_ALL,"");
  initscr();//初始化
  box(stdscr,ACS_VLINE,ACS_HLINE);//画边框
  if (!has_colors()||start_color()==ERR){
    endwin();
    printf("终端不支持颜色\n");
    return 0;
  }
  init_pair(1,COLOR_GREEN,COLOR_BLACK);
  init_pair(2,COLOR_RED,COLOR_BLACK);
  init_pair(3,COLOR_WHITE,COLOR_BLUE);
  int i=0;
  for (i=1;i<=3;i++){
     attron(COLOR_PAIR(i));
     move(i,10);
     printw("hello,世界%d",i);
  }
  for (i=1;i<=3;i++){
     attron(COLOR_PAIR(i)|A_UNDERLINE);
     move(i+5,10);
     printw("hello,世界:%d",i);
  }
  refresh();//刷新屏幕
  getch();//等待按键
  endwin();//结束
  return 0;  
}
编译时注意要使用ncursesw库,不使用ncurses库
dp@dp:~/cursestest % gcc -lncursesw 1.c -o mytest dp@dp:~/cursestest % ./mytest
5、窗口与子窗口
dp@dp:~/cursestest % cat 1.c
#include <ncurses.h>
#include <locale.h>
int main(){
//init_pair(short index,short foreground,short background)初始化颜色索引
//attron(COLOR_PAIR(索引号)|属性)
//newwin建立窗口,derwin建立窗口的子窗口(相对于父窗口相对位置),subwin建立窗口的子窗口(相对于根窗口绝对位置)
  setlocale(LC_ALL,"");
  WINDOW *win1,*win2,*subwin;
  initscr();//初始化
  win1=newwin(15,50,1,1);//新窗口(行,列,begin_y,begin_x)
  box(win1,ACS_VLINE,ACS_HLINE);
  mvwprintw(win1,1,1,"WIN1");
  mvwprintw(win1,2,1,"您好,很高兴认识您");
  win2=newwin(10,40,10,30);//新窗口(行,列,begin_y,begin_x)
  box(win2,ACS_VLINE,ACS_HLINE);
  mvwprintw(win2,1,1,"WIN2");
  mvwprintw(win2,2,1,"您好,很高兴认识您");
  subwin=derwin(win2,3,20,3,5); //子窗口
  box(subwin,ACS_VLINE,ACS_HLINE);
  mvwprintw(subwin,1,5,"按任意键退出");//(窗口,y,x,字符串)
  refresh();//刷新整个大窗口stdscr
  wrefresh(win1);
  wrefresh(win2);
  touchwin(win1);//转换当前窗口为win1
  wrefresh(win1);
  getch();//win1显示完,等待按键显示win2
  touchwin(win2);//转换当前窗口为win2 
  //使用doupdate,可以事先定义要刷新的部分,然后刷新
  wnoutrefresh(win2); 
  wnoutrefresh(subwin);
  doupdate();
  getch();//等待按键
  delwin(win1);
  delwin(subwin);
  delwin(win2);
  endwin();//结束
  return 0;  
}
dp@dp:~/cursestest % gcc -lncursesw 1.c -o mytest
dp@dp:~/cursestest % ./mytest
6、自动滚屏
dp@dp:~/cursestest % cat 2.c
#include <ncurses.h> 
#include <locale.h> 
int main(void){ 
  int y,x,i,j,h,w;
  setlocale(LC_ALL,""); 
  WINDOW *pad; 
  initscr();//初始化 
  
  getmaxyx(stdscr,h,w);//获得屏幕尺寸 
  //画背景
  for(i=0;i<h;i++){
     for(j=0;j<w;j++){
       mvaddch(i,j,ACS_CKBOARD);
     }
  }
  refresh();
  
  //建立窗口
  pad=newpad(80,90);
  for (i=0;i<80;i++){
    char line[90];
    sprintf(line,"line %d\n",i);
    mvwprintw(pad,i,1,line);
  }
  refresh();
  prefresh(pad,0,1,5,10,20,25);//刷新pad。0,1 为基垫需要显示区域的左上角置(行列对,以下同此)。5,10,20,45为屏幕显示区域的左上角和右下角位置
 
  for(i=0;i<65;i++){
    prefresh(pad,i+1,1,5,10,20,25);//刷新pad,实现流屏;
    usleep(30000); 
  }
  getch();//等待按键
  delwin(pad); 
  endwin();//结束 
  return 0;  
}
dp@dp:~/cursestest % gcc -lncursesw 2.c -o mytest
dp@dp:~/cursestest % ./mytest
7、在窗口中移动光标
dp@dp:~/cursestest % cat 2.c
#include <ncurses.h> 
#include <locale.h> 
int main(void){ 
//init_pair(short index,short foreground,short background)初始化颜色索引 
//attron(COLOR_PAIR(索引号)|属性) 
//newwin建立窗口,derwin建立窗口的子窗口(相对于父窗口相对位置),subwin建立窗的子窗口(相对于根窗口绝对位置) 
  int x,y;
  setlocale(LC_ALL,""); 
  WINDOW *win1,*win2,*subwin; 
  initscr();//初始化 
  win1=newwin(15,50,1,1);//新窗口(行,列,begin_y,begin_x) 
  box(win1,ACS_VLINE,ACS_HLINE); 
  mvwprintw(win1,1,1,"WIN1"); 
  mvwprintw(win1,2,1,"myhaspl@myhaspl.com"); 
  win2=newwin(10,40,10,30);//新窗口(行,列,begin_y,begin_x) 
  box(win2,ACS_VLINE,ACS_HLINE); 
  wmove(win2,1,1);//移动某窗口的光标
  printw("WIN2");
  wmove(win2,2,1);//移动某窗口的光标。(窗口,y,x)
  printw("myhaspl@myhaspl.com"); 
  subwin=derwin(win2,3,20,4,5); //子窗口 
  box(subwin,ACS_VLINE,ACS_HLINE); 
  mvwprintw(subwin,1,5,"按任意键退出");//(窗口,y,x,字符串) 
    
  refresh();//刷新整个大窗口stdscr 
  wrefresh(win1); 
  wrefresh(win2); 
  
  move(5,60);//在stdscr移动光标
  printw("hello.........");
  touchwin(win1);//转换当前窗口为win1 
  wrefresh(win1); 
  getch();//win1显示完,等待按键显示win2 
  touchwin(win2);//转换当前窗口为win2 
  //使用doupdate,可以事先定义要刷新的部分,然后刷新 
  wnoutrefresh(win2);  
  wnoutrefresh(subwin); 
  doupdate(); 
  getyx(subwin,y,x);//获得当前逻辑光标位置
  mvwprintw(subwin,y+1,x,"................");//在“按任意键退出"下一行输出"..............."
  getch();//等待按键 
  delwin(win1); 
  delwin(subwin); 
  delwin(win2); 
  endwin();//结束 
  return 0;  
} 
编译后运行
dp@dp:~/cursestest % gcc -lncursesw 2.c -o mytest
dp@dp:~/cursestest % ./mytest
8、菜单
dp@dp:~/cursestest % cat 2.c
#include <locale.h>
#include <menu.h> 
#include <stdio.h>
#include <ctype.h>
//定义菜单项
static const char *menus[]={
  "1-1","1-2","1-3","2-1","2-2","2-3"
};
#define CITEM sizeof(menus)/sizeof(menus[0])//菜单项数
ITEM *items[CITEM];
int main(int argc,char *argv[]){
  int i;
  int ch;
  int mrows,mcols;
  WINDOW *win,*subwin;
  MENU *mymenu;
  
  //初始化屏幕
  initscr();
  //不用等待回车键
  cbreak();
  //不回显
  noecho();
  //可以处理功能键 
  keypad(stdscr,TRUE); 
  
  //建立菜单项
  for(i=0;i<CITEM;i++){
    items[i]=new_item(menus[i],menus[i]);//第二个参数为菜单项的描述
  } 
  //建立菜单
  mymenu=new_menu(items);
  set_menu_format(mymenu,CITEM,1);  //设置CITEM行1列的菜单
  set_menu_mark(mymenu,">");//菜单选中的MARK
  //获得菜单的行列数
  scale_menu(mymenu,&mrows,&mcols);
  //建立窗口和子窗口
  win=newwin(mrows+2,mcols+2,3,30);
  keypad(win,TRUE);
  box(win,0,0);
  subwin=derwin(win,0,0,1,1);
  //设置菜单的窗口
  set_menu_sub(mymenu,subwin);  
  //在子窗口上放置菜单
  post_menu(mymenu);
  
  refresh();
  wrefresh(win);
  //获得输入,并移动选择到相应的菜单项 
  while(toupper(ch=wgetch(win))!='\n'){
     if(ch==KEY_DOWN)
       menu_driver(mymenu,REQ_DOWN_ITEM);//移动菜单选择
     else if(ch==KEY_RIGHT)
       menu_driver(mymenu,REQ_RIGHT_ITEM);
     else if (ch==KEY_UP)
       menu_driver(mymenu,REQ_UP_ITEM); 
     else if (ch==KEY_LEFT)
       menu_driver(mymenu,REQ_LEFT_ITEM);
  }
  //输出当前项
  mvprintw(LINES-2,0,"you select the item :%s\n",item_name(current_item(mymenu)));
  refresh();
  unpost_menu(mymenu);
  getch();
  //释放内存
  free_menu(mymenu);
  for(i=0;i<CITEM;i++) free_item(items[i]);
  endwin();
  return 1;
}
编译并运行
dp@dp:~/cursestest % gcc -lncursesw -lmenu 2.c -o mytest
dp@dp:~/cursestest % ./mytest
