ncurses高级应用
一,使用鼠标
在ncurses中使用鼠标需要几点注意,终端必须在非规范模式下接受鼠标事件,另外,应该有功能键,因为没有他,xterm不会正确的报告鼠标事件。
int raw(void);
int keypad(WINDOW *win, bool bf);
这两个函数用来完成上面要求的工作。
鼠标事件本身通过MEVENT结构来捕获,其定义如下:
typedef struct
{
short id;
int x, y, z;
mmask_t bstate;
}MEVENT;
id用来区分多个设备,xy用来给出鼠标事件发生的位置,z留给未来使用。bstate则指出事件发生时鼠标的状态。下表是鼠标事件的常量的定义
#define BUTTON1_RELEASED 000000000001L 按钮 1 松开
#define BUTTON1_PRESSED 000000000002L 按钮 1 按下
#define BUTTON1_CLICKED 000000000004L 按钮 1 单击
#define BUTTON1_DOUBLE_CLICKED 000000000010L 按钮 1 双击
#define BUTTON1_TRIPLE_CLICKED 000000000020L 按钮 1 三击
#define BUTTON1_RESERVED_EVENT 000000000040L 按钮 1 保留
#define BUTTON2_RELEASED 000000000100L 按钮 2 松开
#define BUTTON2_PRESSED 000000000200L 按钮 2 按下
#define BUTTON2_CLICKED 000000000400L 按钮 2 单击
#define BUTTON2_DOUBLE_CLICKED 000000001000L 按钮 2 双击
#define BUTTON2_TRIPLE_CLICKED 000000002000L 按钮 2 三击
#define BUTTON2_RESERVED_EVENT 000000004000L 按钮 2 保留
#define BUTTON3_RELEASED 000000010000L 按钮 3 松开
#define BUTTON3_PRESSED 000000020000L 按钮 3 按下
#define BUTTON3_CLICKED 000000040000L 按钮 3 单击
#define BUTTON3_DOUBLE_CLICKED 000000100000L 按钮 3 双击
#define BUTTON3_TRIPLE_CLICKED 000000200000L 按钮 3 三击
#define BUTTON3_RESERVED_EVENT 000000400000L 按钮 3 保留
#define BUTTON4_RELEASED 000001000000L 按钮 4 松开
#define BUTTON4_PRESSED 000002000000L 按钮 4 按下
#define BUTTON4_CLICKED 000004000000L 按钮 4 单击
#define BUTTON4_DOUBLE_CLICKED 000010000000L 按钮 4 双击
#define BUTTON4_TRIPLE_CLICKED 000020000000L 按钮 4 三击
#define BUTTON4_RESERVED_EVENT 000040000000L 按钮 4 保留
#define BUTTON_CTRL 000100000000L 同时 CTRL 键也被按下
#define BUTTON_SHIFT 000200000000L 同时 SHIFT 键也被按下
#define BUTTON_ALT 000400000000L 同时 ALT 键也被按下
#define ALL_MOUSE_EVENTS 000777777777L 接收所有的鼠标消息
#define REPORT_MOUSE_POSITION 001000000000L 报告鼠标位置
鼠标使用步骤:
mmask_t mousemask(mmask_t newmask, mmask_t *oldmask);
首先,调用mousemask来告诉ncurses你对那些鼠标事件感兴趣,他的值是上面列出的值的一个或者多个相或的结果,函数执行成功返回掩码的当前设置,出错则会返回0。
int getmouse(MEVENT *event);
int ungetmouse(MEVENT *event);
当有鼠标事件等待处理是,getch就会返回KEY_MOUSE,在再次调用getch之前,必须获得鼠标事件,否则他就会消失。getmouse用来获得下一个鼠标事件,如果出错将会返回ERR,否则返回OK,并填充传递给他的MEVENT结构,ungetmouse会将鼠标事件返回给鼠标事件队列,也会把KEY_MOUSE事件返回给getch函数正在工作的输入队列。
int mouseinterval(int erval);
另外,一次鼠标击键定义为在一定时间内一个按键被按下又被释放。默认的时间是1/5秒,但你可以使用上面的函数来更改这一时间的设置。erval的单位是千分之一秒,同样,函数成功返回OK,失败返回ERR。
bool wenclose(const WINDOW *win, int y, int x);
bool mouse_trafo(int* pY, int* pX, bool to_screen);
bool wmouse_trafo(const WINDOW* win, int* pY, int* pX, bool to_screen);
最后就是处理鼠标发生的位置。wenclose是用来确定给定的xy是不是在win中,getmouse返回的坐标值是相对于屏幕的,所以要用wenclose里来检测鼠标事件是否发生在你的窗口中。如果真的发生在这个窗口,便可以使用wmouse_trafo来产生相对于屏幕的坐标的值。其中最后一个参数应该为FALSE,如果是将相对子窗口的坐标转换成相对于屏幕的坐标值,则最后一个参数为TRUE。宏mouse_trafo是第一个参数为stdscr的wmouse_trafo函数。
/*show the position of mouse event*/
#include
#include
int main(void)
{
int key;
int quit = 0;
MEVENT event;
initscr();
raw();
keypad(stdscr, TRUE);
mousemask(BUTTON1_CLICKED | BUTTON2_CLICKED, 0);
while (!quit)
{
key = getch();
switch (key)
{
case KEY_MOUSE :
getmouse(&event);
printw("Y:%d X:%d\n", event.y, event.x);
refresh();
break;
case 'q' :
quit = 1;
break;
default :
printw("Key = %d\n", key);
}
}
endwin();
return 0;
}
/*mouse.c*/
#include
#include
void showstar(WINDOW * win, const int line);
int main(void)
{
int key;
int quit = 0;
MEVENT mouse;
WINDOW * win;
initscr();
raw();
win = newwin(10, 50, 5, 3);/*this must do before keypad*/
keypad(win, TRUE); /*then use win.*/
mousemask(BUTTON1_CLICKED | BUTTON2_CLICKED, 0); /*set actions*/
box(win, '|', '-');
mvwaddch(win, 1, 48, 'X');
mvwaddstr(win, 3, 3, "Test 1");
mvwaddstr(win, 4, 3, "Test 2");
mvwaddstr(win, 5, 3, "Test 3");
wrefresh(win);
while (!quit)
{
key = wgetch(win);
switch(key)
{
case KEY_MOUSE :
getmouse(&mouse); /*get mouse action*/
if (!wenclose(win, mouse.y, mouse.x))
break; /*do nothing if not in window*/
wmouse_trafo(win, &mouse.y, &mouse.x, FALSE);
if ((3 <= mouse.x && mouse.x <= 8)
&& (3 <= mouse.y && mouse.y <= 5))
showstar(win, mouse.y);
if (1 == mouse.y && 48 == mouse.x) /*Clicked 'X'*/
quit = 1;
break;
case 'q' :
quit = 1;
break;
default :
break;
}
}
delwin(win);
endwin();
return 0;
}
void showstar(WINDOW * win, const int line)
{
mvwaddch(win, line, 2, '*');
wrefresh(win);
}
二,使用菜单
一,建立
#include
ITEM *new_item(const char *name, const char *description);
int free_item(ITEM *item);
new_item函数用来建立项目,相对应有free_item来释放相应的空间,
MENU *new_menu(ITEM **items);
int free_menu(MENU *menu);
当项目建立好之后,由new_menu函数来建立菜单,相对应由free_menu释放。
二,显示
int post_menu(MENU *menu);
int unpost_menu(MENU *menu);
绘制菜单,但是不在屏幕上显示,需要使用refresh来完成显示的动作。unpost_menu的动作是将菜单从子窗口擦除,同样也需要refresh来刷新。
三,动作处理
int menu_driver(MENU *menu, int c);
函数menu_driver用来是指菜单将要进行的动作,参数c用来指明动作,他的取值可以是下面的常量:
REQ_LEFT_ITEM 向左移动到一个菜单项
REQ_RIGHT_ITEM 向右移动到一个菜单项
REQ_UP_ITEM 向上移动到一个菜单项
REQ_DOWN_ITEM 向下移动到一个菜单项
REQ_SCR_ULINE 向上滚动一行
REQ_SCR_DLINE 向下滚动一行
REQ_SCR_DPAGE 向下滚动一页
REQ_SCR_UPAGE 向上滚动一页
REQ_FIRST_ITEM 移动到第一个菜单项
REQ_LAST_ITEM 移动到最后一个菜单项
REQ_NEXT_ITEM 移动到下一个菜单项
REQ_PREV_ITEM 移动到上一个菜单项
REQ_TOGGLE_ITEM 选中/不选中一个菜单项
REQ_CLEAR_PATTERN 清除菜单模式缓冲
REQ_BACK_PATTERN 从模式缓冲中删除前一个字符
REQ_NEXT_MATCH 移动到匹配模式的下一个菜单项
REQ_PREV_MATCH 移动到匹配模式的下一个菜单项
四,其他
int set_current_item (MENU *menu, const ITEM *item); 把菜单里当前选中的菜单项设置为item
ITEM * current_item (const MENU *menu);
int set_top_row (MENU *menu, int row); 尝试把row设置为显示的最顶端一行
int top_row (const MENU *menu); 返回最顶端菜单的行数
int item_index (const ITEM *item);返回项目在菜单中的位置
int set_item_opts (ITEM *item, OPTIONS opts);把菜单的选项设置为传递给他的选项
int item_opts_on (ITEM *item, OPTIONS opts);打开传递给他的选项其他的选项保持不动。
int item_opts_off (ITEM *item, OPTIONS opts);关闭传递给他的选项其他的选项保持不动。
OPTIONS item_opts (const ITEM *item);返回当前设置的选项位
int set_item_userptr (ITEM *item, void *userptr);为菜单设置userptr
void * item_userptr (const ITEM *item);返回和userptr关联的选项
int set_item_value (ITEM *item, bool value);用于选中或不选中可多选的菜单中的菜单项
bool item_value (const ITEM *item);对于可以选中多项的菜单,如果菜单项被选中,则返回TRUE,否则返回FALSE
bool item_visible (const ITEM *item);判断菜单是否可见,用于菜单长度超过屏幕的时候
int set_menu_items (MENU *menu, ITEM **items);用传递给菜单的菜单项改变菜单
ITEM ** menu_items (const MENU *menu); 返回菜单中菜单项列表
int item_count (const MENU *menu); 返回菜单中菜单项的数目
int set_item_opts (ITEM *item, OPTIONS opts);
int item_opts_on (ITEM *item, OPTIONS opts);
int item_opts_off (ITEM *item, OPTIONS opts);
OPTIONS item_opts (const ITEM *item);把传递给菜单的选项opts都设置为关闭,保持其他选项不动。他的取值可以是:
O_ONEVALUE 菜单中只能选中一项
O_SHOWDESC 显示菜单项的描述
O_ROWMAJOR 以行的顺序显示菜单
O_IGNORECASE 当匹配模式时,忽略大小写
O_SHOWMATCH 移动光标指示模式匹配菜单名
O_NONCYCLIC 在菜单的末尾不折叠显示
int set_menu_opts (MENU *menu, OPTIONS opts);
int menu_opts_on (MENU *menu, OPTIONS opts);
int menu_opts_off (MENU *menu, OPTIONS opts);
OPTIONS menu_opts (const MENU *menu);
int set_menu_win (MENU *menu, WINDOW *win);设置和菜单相关联的窗口
WINDOW *menu_win (const MENU *menu);返回菜单关联的窗口
int set_menu_sub (MENU *menu, WINDOW *sub);设置和菜单相关联的子窗口
WINDOW *menu_sub (const MENU *menu);返回菜单使用的子窗口
int scale_menu (const MENU *menu, int *rows, int *columns); 返回用于菜单的最小子窗口的大小
int set_menu_fore (MENU *menu, chtype attr); set为设置相应的属性
chtype menu_fore (const MENU *menu);返回选中菜单项的属性
int set_menu_back (MENU *menu, chtype attr);
chtype menu_back (const MENU *menu);返回可选但未选中的菜单项的属性
int set_menu_grey (MENU *menu, chtype attr);
chtype menu_grey (const MENU *menu);返回未选中菜单项的属性
int set_menu_pad (MENU *menu, int pad);
int menu_pad (const MENU *menu);返回菜单名和菜单描述分隔的字符
int set_menu_format (MENU *menu, int rows, int cols); 设置当前菜单的显示大小,若菜单包含的菜单项比给出的空间大,则滚动显示
void menu_format (const MENU *menu, int *rows, int *cols);返回当前菜单的显示大小
int set_menu_mark (MENU *menu, const char *mark); 设置选中菜单项的前缀
const char *menu_mark (const MENU *menu);得到选中菜单项的前缀
const char *menu_request_name (int request); 返回request可打印的名字
int menu_request_by_name (const char *name);返回和name相关的请求代码
int set_menu_spacing (MENU *menu, int spc_description, int spc_rows, int spc_columns); 选择菜单使用的间隔空间
int menu_spacing (const MENU *menu, int* spc_description, int* spc_rows, int* spc_columns);返回菜单间隔空间设置
int set_menu_userptr (MENU *menu, void *userptr); 设置针对应用的特定数据
void * menu_userptr (const MENU *menu);返回和菜单相关的针对应用的特定数据
int pos_menu_cursor (const MENU *menu);把光标定位在当前选中的菜单项上
int set_menu_pattern (MENU *menu, const char *pattern); 把模式缓冲内容设置为pattern
char * menu_pattern (const MENU *menu); 返回模式缓冲的当前内容
#include
#include
#include
#include
#include
#include
#include
char * say_menu[] = {
"Hi", "Say Hi",
"World", "Hello World",
"Quit", "Exit the application",
NULL};
int main(void)
{
int quit = 0;
int key;
int i;
MENU * menu;
ITEM * item[4];
initscr();
raw();
noecho();
keypad(stdscr, TRUE);
for (i = 0; say_menu[i * 2]; i++)
item[i] = new_item(say_menu[i * 2], /*给ITEM *分配空间并初始化*/
say_menu[i * 2 + 1]);
item[i] = NULL;
menu = new_menu(item); /*创建一个新菜单,item必须以NULL结尾。*/
post_menu(menu); /*绘制菜单*/
while (!quit)
{
int code;
ITEM * selected;
key = getch();
switch (key)
{
case KEY_DOWN :
case KEY_RIGHT:
code = menu_driver(menu, REQ_NEXT_ITEM); /*执行动作*/
break;
case KEY_UP :
case KEY_LEFT :
code = menu_driver(menu, REQ_PREV_ITEM);
break;
case '\n' :
if ((selected = current_item(menu)) != NULL) /*返回当前选中项。*/
{
unpost_menu(menu); /*从子窗口中擦除菜单,需要refresh。*/
mvaddstr(10, 10, "You have selected:");
mvaddstr(11, 15, item_description(selected)); /*返回项目的描述*/
refresh();
sleep(3);
erase();
if (!strcmp("Quit", item_name(selected))) /*返回项目名字*/
quit = 1;
else
post_menu(menu); /*绘制菜单*/
}
break;
case 'q' :
quit = 1;
break;
default :
if (isprint(key))
if (menu_driver(menu, key) != E_OK)
menu_driver(menu, REQ_CLEAR_PATTERN);
break;
}
}
endwin();
return 0;
}
三,使用窗体
一,建立
FIELD * new_field (int height, int width, int toprow, int leftcol, int offscreen, int nbuffers);
FIELD * dup_field (FIELD *field, int toprow, int leftcol);
FIELD * link_field (FIELD *field, int toprow, int leftcol);
int free_field (FIELD *field);
函数new_field用来建立一个域,参数分别表示这个域的高,宽,左上角的yx的值,跨越屏幕的行数,以及额外的工作缓冲的数量。duo_field函数用来复制域,link_field 用来连接域,free_field用来释放域所占 的内存空间。
FORM *new_form(FIELD **fields);
int free_form(FORM *form);
当域建立完毕之后,就要用函数new_form将他们组成窗体,函数free_form用来释放窗体。
二,显示
int post_form(FORM *form);
int unpost_form(FORM *form);
当建立好窗体之后,就可以用函数post_form来显示,注意,这里需要用refreah函数,将其真正的显示到屏幕上面。unpost_form的动作与post_form函数相反,他清除所在子窗口的窗体。同样也需要用refresh函数。
三,操作
int form_driver(FORM *form, int c);
同menu_driver的性质一样,他也是用来控制的函数,不同的是他所控制的是窗体,而不是菜单。
REQ_NEXT_PAGE Move to the next page.
REQ_PREV_PAGE Move to the previous page.
REQ_FIRST_PAGE Move to the first page
REQ_LAST_PAGE Move to the last field.
REQ_NEXT_FIELD Move to the next field.
REQ_PREV_FIELD Move to the previous field.
REQ_FIRST_FIELD Move to the first field.
REQ_LAST_FIELD Move to the last field.
REQ_SNEXT_FIELD Move to the sorted next field.
REQ_SPREV_FIELD Move to the sorted previous field.
REQ_SFIRST_FIELD Move to the sorted first field.
REQ_SLAST_FIELD Move to the sorted last field.
REQ_LEFT_FIELD Move left to a field.
REQ_RIGHT_FIELD Move right to a field.
REQ_UP_FIELD Move up to a field.
REQ_DOWN_FIELD Move down to a field.
REQ_NEXT_CHAR Move to the next char.
REQ_PREV_CHAR Move to the previous char.
REQ_NEXT_LINE Move to the next line.
REQ_PREV_LINE Move to the previous line.
REQ_NEXT_WORD Move to the next word.
REQ_PREV_WORD Move to the previous word.
REQ_BEG_FIELD Move to the beginning of the field.
REQ_END_FIELD Move to the end of the field.
REQ_BEG_LINE Move to the beginning of the line.
REQ_END_LINE Move to the end of the line.
REQ_LEFT_CHAR Move left in the field.
REQ_RIGHT_CHAR Move right in the field.
REQ_UP_CHAR Move up in the field.
REQ_DOWN_CHAR Move down in the field.
REQ_NEW_LINE Insert or overlay a new line.
REQ_INS_CHAR Insert a blank at the cursor.
REQ_INS_LINE Insert a blank line at the cursor.
REQ_DEL_CHAR Delete character at the cursor.
REQ_DEL_PREV Delete character before the cursor.
REQ_DEL_LINE Delete line at the cursor.
REQ_DEL_WORD Delete blank-delimited word at the cursor.
REQ_CLR_EOL Clear to end of line from cursor.
REQ_CLR_EOF Clear to end of field from cursor.
REQ_CLR_FIELD Clear the entire field.
REQ_OVL_MODE Enter overlay mode.
REQ_INS_MODE Enter insert mode.
REQ_SCR_FLINE Scroll the field forward a line.
REQ_SCR_BLINE Scroll the field backward a line.
REQ_SCR_FPAGE Scroll the field forward a page.
REQ_SCR_BPAGE Scroll the field backward a page.
REQ_SCR_FHPAGE Scroll the field forward half a page.
REQ_SCR_BHPAGE Scroll the field backward half a page.
REQ_SCR_FCHAR Scroll the field forward a character.
REQ_SCR_BCHAR Scroll the field backward a character.
REQ_SCR_HFLINE Horizontal scroll the field forward a line.
REQ_SCR_HBLINE Horizontal scroll the field backward a line.
REQ_SCR_HFHALF Horizontal scroll the field forward half a line.
REQ_SCR_HBHALF Horizontal scroll the field backward half a line.
REQ_VALIDATION Validate field.
REQ_NEXT_CHOICE Display next field choice.
REQ_PREV_CHOICE Display previous field choice.
四,其他
int set_form_opts (FORM *form, OPTIONS opts); 用opts设置窗体的选项,O_NL_OVERLOAD:如果用户在域的结尾按了回车,
则强迫窗体驱动移动到下一个域,O_BS_OVERLOAD:如果在域的开头按了退格键
,则强迫移动到上一个域,默认他们是打开的。
int form_opts_on (FORM *form, OPTIONS opts);打开opts,其他不变
int form_opts_off (FORM *form, OPTIONS opts);关闭opts,其他不变
OPTIONS form_opts (const FORM *form);返回当前设置
int set_form_win (FORM *form, WINDOW *win);设置窗体的窗口
WINDOW * form_win (const FORM *form);返回窗体的窗口
int set_form_sub (FORM *form, WINDOW *sub);设置窗体的子窗口
WINDOW * form_sub (const FORM *form);返回窗体的子窗口
int scale_form (const FORM *form, int *rows, int *columns);返回要求一个窗体的最小尺寸
int set_form_userptr (FORM *form, void *userptr);为窗体设置针对应用的特定数据的指针
void * form_userptr (const FORM *form);返回给定窗体的针对应用的特定数据
const char * form_request_name (int request);返回请求的文字名称
int form_request_by_name (const char *name);返回请求的代码
int set_current_field (FORM *form, FIELD *field);设置当前域
FIELD * current_field (const FORM *);返回当前域
int set_form_page (FORM *form, int n);设置窗体的当前页
int form_page (const FORM *form);返回当前页号
int field_index (const FIELD *field);返回和窗体相关联的域数组中这个域的索引号
int set_field_buffer (FIELD *field, int buf, const char *value);
char * field_buffer (const FIELD *field, int buffer);
int set_field_status (FIELD *field, bool status);设置域的状态
bool field_status (const FIELD *field);检查域状态
int set_max_field (FIELD *field, int max);
int set_form_fields (FORM *form, FIELD **fields);把窗体的域设置为新传递给窗体的列表,列表以NULL,结尾
FIELD ** form_fields (const FORM *form); 返回当前和form相关的域数组
int field_count (const FORM *form);
int move_field (FIELD *field, int frow, int fcol);
int set_new_page (FIELD *field, bool new_page_flag);如果new_page_flag为TRUE,设置域从一个新页开始,FALSE取消设置
bool new_page (const FIELD *field);如果域标记了新页的开始则返回TRUE,否则返回FALSE
int set_form_fields (FORM *form, FIELD **fields);
FIELD ** form_fields (const FORM *form);
int field_count (const FORM *form);返回当前和form相关联的域的数量
int move_field (FIELD *field, int frow, int fcol);把field移动到指定位置上
int pos_form_cursor (FORM *form);当光标被窗体库以外的调用移动时,在当前选中域的光标的位置
bool data_ahead (const FORM *form);如果form前有数据但有不在屏幕上,返回TRUE
bool data_behind (const FORM *form);如果form后有数据但有不在屏幕上,返回TRUE
int set_field_buffer (FIELD *field, int buf, const char *value);
char * field_buffer (const FIELD *field, int buffer);
int set_field_status (FIELD *field, bool status);
bool field_status (const FIELD *field);
int set_max_field (FIELD *field, int max);设置动态域的最大尺寸
int field_info (const FIELD *field, int *rows, int *cols, int *frow, int *fcol, int *nrow, int *nbuf); 返回域在创建时设置的属性
int dynamic_field_info (const FIELD *field, int *rows, int *cols, int *max);返回当前能改变的一个域的属性
int set_field_fore (FIELD *field, chtype attr);设置域的前景属性
chtype field_fore (const FIELD *field);返回域前景属性
int set_field_back (FIELD *field, chtype attr);设置域的背景属性
chtype field_back (const FIELD *field);返回域的背景属性
int set_field_pad (FIELD *field, int pad);设置用来填充域的字符文本
int field_pad (const FIELD *field);返回用来填充域的字符文本
int set_field_just (FIELD *field, int justification); 设置域的调整值
int field_just (const FIELD *field);
int set_field_userptr (FIELD *field, void*userptr);
void * field_userptr (const FIELD *field);
int set_field_opts (FIELD *field, OPTIONS opts);
int field_opts_on (FIELD *field, OPTIONS opts);
int field_opts_off (FIELD *field, OPTIONS opts);
OPTIONS field_opts (const FIELD *field);
O_VISIBLE The field is displayed. If this option is off, display of the field is suppressed.
O_ACTIVE The field is visited during processing. If this option is off, the field will not be reachable by navigation keys. Please notice that an invisible field appears to be inactive also.
O_PUBLIC The field contents are displayed as data is entered.
O_EDIT The field can be edited.
O_WRAP Words that do not fit on a line are wrapped to the next line. Words are blank-separated.
O_BLANK The field is cleared whenever a character is entered at the first position.
O_AUTOSKIP Skip to the next field when this one fills.
O_NULLOK Allow a blank field.
O_STATIC Field buffers are fixed to field’s original size. Turn this option off to create a dynamic field.
O_PASSOK Validate field only if modified by user.
域类型
int set_field_type (FIELD *field, FIELDTYPE *type, ...);用来设置一个域的类型
FIELDTYPE * field_type (const FIELD *field);
void * field_arg (const FIELD *field); 返回给验证例程的参数
FIELDTYPE * TYPE_ALNUM;接受字母和数字:set_field_type(field, TYPE_ALNUM, width);
FIELDTYPE * TYPE_ALPHA;接受字母:set_field_type(field, TYPE_ALPHA, width); width设置了数据的最小宽度,如果是一个可选的域,可以设置为0
FIELDTYPE * TYPE_ENUM; 接收范围限制在枚举类型的数据集合中 field_type(field, TYPE_ENUM, valuelist, checkcase, checkunique);其中,valuelist是一个以NULL结尾的字符串数组,checkcase不为0则会区分大小写,
FIELDTYPE * TYPE_INTEGER;接受整数,set_filed_type(filed, TYPE_INITEGER, padding/*前补零的个数*/, vmin, vmax/*指出范围*/);
FIELDTYPE * TYPE_NUMERIC;接受一个十进制数set_filed_type(filed, TYPE_NUMERIC, padding/*前补零的个数*/, vmin, vmax/*指出范围 */);
FIELDTYPE * TYPE_REGEXP;正则表达式匹配 set_field_type(field, TYPE_REGEXP, regexp);
FIELDTYPE * TYPE_IPV4;
FIELDTYPE * new_fieldtype(
bool (* const field_check)(FIELD *, const void *),
bool (* const char_check)(int, const void *)); 控制域的类型
int free_fieldtype (FIELDTYPE *fieldtype); 释放fieldtype分配的内存
int set_fieldtype_arg(
FIELDTYPE *fieldtype,
void *(* const make_arg)(va_list *),
void *(* const copy_arg)(const void *),
void (* const free_arg)(void *));设置fieldtype参数。
int set_fieldtype_choice(
FIELDTYPE *fieldtype,
bool (* const next_choice)(FIELD *, const void *),
bool (* const prev_choice)(FIELD *, const void *));设置fieldtype_choice参数
FIELDTYPE * link_fieldtype (FIELDTYPE *type1,FIELDTYPE *type2);连接filetype
int set_field_init (FORM *form, void (*func)(FORM *)); 在修改域之后,重画窗体时调用的函数指针
void (*)(FORM *) field_init (const FORM *form);返回field_init钩子函数的函数指针,如果没有则返回NULL
int set_field_term (FORM *form, void (*func)(FORM *));在修改域之前,重画窗体时调用的函数指针
void (*)(FORM *) field_term (const FORM *form);返回field_term钩子函数的函数指针,如果没有则返回NULL
int set_form_init (FORM *form, void (*func)(FORM *));在修改页之后,重画窗体时调用的函数指针
void (*)(FORM *) form_init (const FORM *form);返回form_init钩子函数的函数指针,如果没有则返回NULL
int set_form_term (FORM *form, void (*func)(FORM *));在修改页之后,重画窗体时调用的函数指针
void (*)(FORM *) form_term (const FORM *form);返回form_term钩子函数的函数指针,如果没有则返回NULL
#include
#include
#include
#include
#include
#include
#include
int main(void)
{
int quit = 0;
int key;
FORM * form;
FIELD * fields[5];
initscr();
fields[0] = new_field(1, 20, 2, 2, 0, 0); /*分配一个新域*/
field_opts_off(fields[0], O_ACTIVE); /*关闭指定选项,其他不变*/
set_field_buffer(fields[0], 0, "Name:");
fields[1] = new_field(1, 50, 3, 5, 0, 0);
fields[2] = new_field(1, 20, 4, 2, 0, 0);
field_opts_off(fields[2], O_ACTIVE);
set_field_buffer(fields[2], 0, "Passwd:");
fields[3] = new_field(1, 50, 5, 5, 0, 0);
fields[4] = new_field(1, 10, 6, 5, 0, 0);
set_field_buffer(fields[4], 0, "--QUIT--");
field_opts_off(fields[4], O_EDIT);
fields[5] = NULL;
form = new_form(fields);
post_form(form);
raw();
noecho();
keypad(stdscr, TRUE);
while (!quit)
{
int code;
key = getch();
switch (key)
{
case KEY_DOWN :
case KEY_RIGHT :
case '\t' :
code = form_driver(form, REQ_NEXT_FIELD);
break;
case '\n' :
if (field_index(current_field(form)) == 4)
quit = 1;
else
code = form_driver(form, REQ_NEXT_FIELD);
break;
case KEY_UP :
case KEY_LEFT:
code = form_driver(form, REQ_PREV_FIELD);
break;
default :
if (isprint(key))
form_driver(form, key);
break;
}
}
endwin();
return 0;
}