回 目 录
上 一 章 下 一 章

# 第十一章：键盘管理

### 11.1 一些基础知识

  一个图形用户界面（GUI）如果没有一个功能强大的用户对话接口的话，那它就是不完整的。一个CURSES程序应该对用户的键盘和鼠标操作很敏感。让我们先来了解一下你的键盘。

  像你在以上看到的几乎所有的例子那样，得到用户的输入的键值非常简单。简单的取得用户按键信息的方法是使用getch()函数。当你读取某些特殊的按键，例如换行键时，你应该激活cbreak模式。以便于读取功能键、方向键等等。

  getch()返回一个整数对应键盘上相应的按键。如果你输入的是一个普通字符。这个整数就等价于这个字符。否则这个整数将和curses.h中定义的常量相匹配。例如如果用户按下了F1，这个数字的返回值将是265。这个值可以通过curses.h中内定义的宏KEY_F()检测。这样可以更方便的管理键盘的输入。

例如，如果你这样调用getch()函数：

    	int ch;
    	ch = getch();

  getch()函数将等待用户输入。（除非你规定了延时时间）当你按下一个键，就会返回一个相应的整数。然后你可以检测这个值是否是你想要的。当然，这些相对应的值可以在curses.h中找到。

  以下这段代码就可以用来监测键盘左方向键：

        if(ch == KEY_LEFT)
            printw("Left arrow is pressed\n");

  让我们写一个可以通过上下键操纵的窗口菜单。

### 11.2.一个简单的使用键盘的例子

例 10： 一个读取键盘的例子

    #include <stdio.h>
    #include <ncurses.h>

    #define WIDTH 30
    #define HEIGHT 10
    int startx = 0;
    int starty = 0;
    char *choices[] = {
    			"Choice 1",
    			"Choice 2",
    			"Choice 3",
    			"Choice 4",
    			"Exit",
    		  };
    int n_choices = sizeof(choices) / sizeof(char *);
    void print_menu(WINDOW *menu_win, int highlight);

    int main()
    {
    	WINDOW *menu_win;
    	int highlight = 1;
    	int choice = 0;
    	int c;

    	initscr();
    	clear();
    	noecho();
    	cbreak();						/* 禁用行缓冲，直接传递所有输入 */
    	startx = (80 - WIDTH) / 2;
    	starty = (24 - HEIGHT) / 2;

    	menu_win = newwin(HEIGHT, WIDTH, starty, startx);
    	keypad(menu_win, TRUE);
    	mvprintw(0, 0,"Use arrow keys to go up and down, Press enter to select a choice");
    	refresh();
    	print_menu(menu_win, highlight);
    	while(1)
    	{
    		c = wgetch(menu_win);
    		switch(c)
    		{
    			case KEY_UP:
    			if(highlight == 1)
    					highlight = n_choices;
    				else
    					--highlight;
    				break;
    			case KEY_DOWN:
    				if(highlight == n_choices)
    					highlight = 1;
    				else
    					++highlight;
    				break;
    			case 10:
    				choice = highlight;
    				break;
    			default:
    				mvprintw(24, 0, "Charcter pressed is = %3d Hopefully it can be printed as '%c'", c, c);
    				refresh();
    				break;
    		}
    		print_menu(menu_win, highlight);
    		if(choice != 0)					/* 用户必须要做一个选择 */
    			break;
    	}
    	mvprintw(23, 0, "You chose choice %d with choice string %s\n", choice, choices[choice - 1]);
    	clrtoeol();
    	refresh();
    	endwin();
    	return 0;
    }
    void print_menu(WINDOW *menu_win, int highlight)
    {
    	int x, y, i;
    	x = 2;
    	y = 2;
    	box(menu_win, 0, 0);
    	for(i = 0; i < n_choices; ++i)
    	{	if(highlight == i + 1)    			/* 使选择的字符串高亮显示 */
    		{	wattron(menu_win, A_REVERSE);
    			mvwprintw(menu_win, y, x, "%s", choices[i]);
    			wattroff(menu_win, A_REVERSE);
    		}
    		else
    			mvwprintw(menu_win, y, x, "%s", choices[i]);
    		++y;
    	}
    	wrefresh(menu_win);
    }

回 目 录
上 一 章 下 一 章