📄 ch18.htm
字号:
/* 设置表单域选项 */
set_field_fore(field[0], COLOR_PAIR(1)); /* 设置表单域背景色为蓝色 */
set_field_back(field[0], COLOR_PAIR(2)); /* 白色为前景色(字符为白色)*/
field_opts_off(field[0], O_AUTOSKIP);
/* 当这个域填满时不自动跳到下一个表单域*/
set_field_back(field[1], A_UNDERLINE);
field_opts_off(field[1], O_AUTOSKIP);
/* 创建表单并递送 */
my_form = new_form(field);
post_form(my_form);
refresh();
set_current_field(my_form, field[0]); /* 把此表单域设为当前的活动域 */
mvprintw(4, 10, "Value 1:");
mvprintw(6, 10, "Value 2:");
mvprintw(LINES - 2, 0, "Use UP, DOWN arrow keys to switch between fields");
refresh();
/* 用循环获取用户请求 */
while((ch = getch()) != KEY_F(1))
{ switch(ch)
{ case KEY_DOWN:
/* 跳到下一个表单域 */
form_driver(my_form, REQ_NEXT_FIELD);
/* 跳到当前缓冲区的末尾 */
/* 在输入最后一个字符后跳出 */
form_driver(my_form, REQ_END_LINE);
break;
case KEY_UP:
/* 跳到前一个表单域 */
form_driver(my_form, REQ_PREV_FIELD);
form_driver(my_form, REQ_END_LINE);
break;
default:
/* 如果是正常的字符,则读入并打印 */
form_driver(my_form, ch);
break;
}
}
/* 取消表单递送并释放内存 */
unpost_form(my_form);
free_form(my_form);
free_field(field[0]);
free_field(field[1]);
endwin();
return 0;
}
</pre>
</font>
<p>
<dd>
仔细研究这些颜色变量对并深刻的理解前景和背景修饰。在我的程序里面,若要设置颜色属性,我一般只用set_field_back()来设置背景修饰。cureses不允许自定义颜色。
</dd>
</p>
<br>
<h4 align="left">
<strong>
18.3.5.表单域属性
</strong>
</h4>
<p>
<dd>
表单的处理是通过对表单域设定属性实现的,有大量的表单域属性对应表单处理的各个方面。你可以用下面的函数为表单域设定属性:
</dd>
</p>
<font color="maroon">
<pre>
int set_field_opts(FIELD *field, /* 要变更的表单域 */
int attr); /* 要设定的属性 */
int field_opts_on(FIELD *field, /* 要改变选项的表单域 */
int attr); /* 要启用的属性 */
int field_opts_off(FIELD *field, /* 要改变选项的表单域 */
int attr); /* 要关闭的属性 */
int field_opts(FIELD *field); /* 要查询的表单域 */
</pre>
</font>
<p>
<dd>
函数set_field_opts()可以直接用来设置表单域属性。要启用或关闭某些属性的话,你可以用函数field_opts_on()或field_opts_off()来完成。你可以随时用函数field_opts()来查询某个表单域的属性。下面列出了所有可用的属性,默认情况下,它们都是已启用的。
</dd>
</p>
<p>
O_VISIBLE
</p>
<P>
<dd>
控制表单域是否在屏幕上可见。可以用来显示或隐藏某些表单域以及附加表单域。
</dd>
</P>
<p>
O_ACTIVE
</p>
<p>
<dd>
控制表单域在表单处理时是否是激活状态(如:类似Tab键在域之间跳转访问)。这样可以使应用程序创建带有可变缓冲区的标签或起始表单域。
</dd>
</p>
<p>
O_PUBLIC
</p>
<p>
<dd>
控制输入时是否在表单域中显示输入数据。如果关闭了某个表单域的这个属性,表单系统仍然允许编辑这个表单域的数据。但不会在这个可视表单域中显示出来,同时光标也不会移动。你可以通过关闭O_PUBLIC选项来定义一个密码域。
</dd>
</p>
<p>
O_EDIT
</p>
<p>
<dd>
控制表单域的数据能否被修改。当这个选项关闭时,除了REQ_PREV_CHOICE 和REQ_NEXT_CHOICE以外,其它所有的编辑请求都将失效。可以设置类似这样的只读表单域用来显示帮助信息。
</dd>
</p>
<p>
O_WRAP
</p>
<p>
<dd>
控制多行表单域的自动换行。通常,当一个单词(用空格作为单词之间的间隔)的任意一个字符到了当前行的末尾时,整个单词会自动换行显示(如果有下一行的话)。当这个选项关闭时,这个单词会在行尾处断开。
</dd>
</p>
<p>
O_BLANK
</p>
<p>
<dd>
清空表单域。当此选项打开后,在表单域的起始位置输入字符时,程序会自动清空整个域(除了刚输入的这个字符)。
</dd>
</p>
<P>
O_AUTOSKIP
</P>
<p>
<dd>
控制当前表单域填满时是否自动跳转到下一个表单域。通常,当用户的输入的数据超出了的一个表单域所能容纳的数据时,光标会自动跳转到下一个表单域。如果这个选项已关闭,则光标停在表单域的末尾。对于没有大小限制的动态表单域,这个选项会被忽略。
</dd>
</p>
<p>
O_NULLOK
</p>
<p>
<dd>
是否检查空白表单域的有效性,默认为不检查。用户可以在退出时让一个表单域为空,而不用像通常那样检查这个表单域是否有效。如果某个表单域的这个选项是关闭的,退出程序时就要检查表单域的有效性了。
</dd>
</p>
<p>
O_PASSOK
</p>
<p>
<dd>
控制表单有效性检查发生的时间。默认是在表单域的数据被修改后检查。设置以后,用户在退出表单域后检查表单域的有效性。当你需要在处理表单时同时更改表单域的有效性检查函数,设置O_PASSOK选项就对了。
</dd>
</p>
<p>
O_STATIC
</p>
<p>
控制表单域的长度是否固定为初始长度。如果关闭这个选项,则表单域就变成动态的。系统会根据输入数据的长度自动调整表单域大小。
</p>
<p>
<dd>
如果当前的表单域为选定状态时,表单域的属性不能修改。但是,可以在表单域递送后修改属性。
</dd>
</p>
<p>
<dd>
这些属性都是位掩码,可以用“或”逻辑运算符组合属性。你已经看见了关闭O_AUTOSKIP属性后的效果。下面的这个例子说明了更多属性的用法。其他的属性会在后面适当的地方说明。
</dd>
</p>
<P>
例27. 表单域属性用法示例
</P>
<font color="Maroon">
<pre>
#include <form.h>
#define STARTX 15
#define STARTY 4
#define WIDTH 25
#define N_FIELDS 3
int main()
{ FIELD *field[N_FIELDS];
FORM *my_form;
int ch, i;
/* 初始化curses */
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
/* 初始化表单域 */
for(i = 0; i < N_FIELDS - 1; ++i)
field[i] = new_field(1, WIDTH, STARTY + i * 2, STARTX, 0, 0);
field[N_FIELDS - 1] = NULL;
/* 设置表单域选项 */
set_field_back(field[1], A_UNDERLINE); /* 为选项打印下划线 */
field_opts_off(field[0], O_ACTIVE); /* 这个表单域是静态标签 */
field_opts_off(field[1], O_PUBLIC); /* 这个表单域类似密码域 */
field_opts_off(field[1], O_AUTOSKIP);
/* 防止在输入完最后一个字符后还是在同一个域输入*/
/* 创建表单并递送 */
my_form = new_form(field);
post_form(my_form);
refresh();
set_field_just(field[0], JUSTIFY_CENTER); /* 表单域输入时居中对齐 */
set_field_buffer(field[0], 0, "This is a static Field "); /* 初始化表单域 */
mvprintw(STARTY, STARTX - 10, "Field 1:");
mvprintw(STARTY + 2, STARTX - 10, "Field 2:");
refresh();
/* 循环读取用户请求 */
while((ch = getch()) != KEY_F(1))
{ switch(ch)
{ case KEY_DOWN:
/* 跳到下一个表单域 */
form_driver(my_form, REQ_NEXT_FIELD);
/* 跳到当前缓冲的末尾 */
/* 在最后一个字符处跳出 */
form_driver(my_form, REQ_END_LINE);
break;
case KEY_UP:
/* 跳到前一个表单域 */
form_driver(my_form, REQ_PREV_FIELD);
form_driver(my_form, REQ_END_LINE);
break;
default:
/* 若是普通的字符,则打印出来 */
form_driver(my_form, ch);
break;
}
}
/* 取消表单传递并释放内存 */
unpost_form(my_form);
free_form(my_form);
free_field(field[0]);
free_field(field[1]);
endwin();
return 0;
}
</pre>
</font>
<p>
<dd>
这个例子虽然用处不大,但它演示了这些属性的用法和效果。如果恰到好处地使用这些属性,可以在有效地在表单中显示信息。第二个表单域关闭了O_PUBLIC选项,所以你看不到输入的字符。
</dd>
</p>
<br>
<h4 align="left">
<strong>
18.3.6.获取表单域的状态
</strong>
</h4>
<P>
<dd>
表单域的状态用来标记表单域的是否被修改。初始值为FALSE,当用户在表单域中输入数据,同时也修改了数据缓冲区后,该值就变为TRUE。因此,可以通过查询一个表单域的状态来看检测它是否被修改了。下面的函数支持以上的功能。
</dd>
</P>
<font color="maroon">
<pre>
int set_field_status(FIELD *field, /* 要改变状态的表单域 */
int status); /* 要设置的表单域状态 */
int field_status(FIELD *field); /* 要取得状态的表单域*/
</pre>
</font>
<p>
<dd>
你的程序最好能够在离开一个表单域的时候检查一下表单域的状态。因为表单域的有效性还没有确定,所以数据缓冲区可能还没有更新。为确保返回正确的表单域状态,最好在下面三种情况调用field_status()函数:(1)、退出表单域并检查有效性时;(2)、在表单域或表单初始化或退出时;(3)、Form Driver处理REQ_VALIDATION请求后。
</dd>
</p>
<br>
<h4 align="left">
<strong>
18.3.7. 用户指针
</strong>
</h4>
<p>
<dd>
每个表单域的结构都包含一个用户指针,这个指针可以使用户做很多事情。它不能被表单库直接访问,但可以被用户任意使用。下面的函数可以设置和读取用户指针。
</dd>
</p>
<font color="maroon">
<pre>
int set_field_userptr(FIELD *field,
char *userptr); /* 与这个表单域关联的用户指针 */
char *field_userptr(FIELD *field); /* 要获取指针的表单域 */
</pre>
</font>
<br>
<h4 align="left">
<strong>
18.3.8. 动态表单域
</strong>
</h4>
<p>
<dd>
假如你需要一个可以动态改变大小的表单域的话,那么这正是你需要用到的功能。当用户输入的数据大小超过该表单域的原大小时,文本框的尺寸就会动态的改变。根据文本框的位置,文本框可以自动的水平或垂直滚动,以适应新增添的数据。
</dd>
</p>
<p>
<dd>
为使一个表单域的宽度可以动态地改变,应该先关闭O_STATIC选项。这可以通过调用下面函数完成:
</dd>
</p>
<font color="maroon">
<pre>
field_opts_off(field_pointer, O_STATIC);
</pre>
</font>
<p>
<dd>
但是通常不允许一个表单域无限制地增长。可以设置表单域动态增长的最大宽度:
</dd>
</p>
<font color="maroon">
<pre>
int set_max_field(FIELD *field, /* 要进行设置的表单域 */
int max_growth); /* 表单域动态增长的最大宽度 */
</pre>
</font>
<p>
<dd>
可以通过下面的函数访问动态增长的表单域:
</dd>
</p>
<font color="maroon">
<pre>
int dynamic_field_info( FIELD *field, /* 要进行查询的表单域 */
int *prows, /* 表单域的行数 */
int *pcols, /* 表单域的列数 */
int *pmax) /* 表单域动态增长的最大宽度 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -