ваша help-функция может выдавать список номеров служащих и их
фамилии, выбирая эту информацию непосредственно из самого файла
"Служащий".
int data_entry(WINDOW *wnd)
Эта функция обрабатывает вводимые в шаблон данные.
Пользователь может просмотреть весь шаблон со значениями всех
полей, выдавая на дисплей текущие значения данных из
соответствующих буферов накопления данных. Пользователь
осуществляет ввод данных в поля в той последовательности, в
которой поля были установлены в шаблоне с помощью функции
establish_field, при этом позиция размещения поля в шаблоне во
внимание не принимается.
Поле, которое предназначено в данный момент для ввода в него
данных, отображается пользователю с учетом суммарного
пространства под вводимые данные, включая пунктуацию, и
выделяется повышенной яркостью в соответствии со значением
параметра ACCENT, определяющим цвет окна. Курсор устанавливается
в первой позиции поля, и функция переходит в режим ожидания ввода
данных. Пользователь может начать ввод данных или в текущее поле,
или установить текущим другое поле, используя клавишу <ВВОД>,
клавишу табуляции <Таб> или клавиши управления курсором. Клавиши
<КЛЮЧ>, <Страница вверх> (), (),
<КОН> (), перемещения курсора в первую позицию первой строки
() и функциональные клавиши (с <ПФ1> до <ПФ10>, исключая
клавишу, за которой закреплен вызов help-функции) предназначены
для завершения процесса ввода данных и возврата из функции
data_entry, к которой перед этим было осуществлено обращение, в
точку вызова.
После ввода пользователем последнего символа поля происходит
выделение повышенной яркостью следующего поля и перемещение к
нему курсора. Перед этим функция data_entry обращается к своим
собственным функциям контроля данных и (если вы установили еще и
свои специальные функции контроля данных) к специальным функциям
контроля. Все эти функции должны в результате работы выдать
значение ОК, в противном случае функция data_entry не переместит
курсор к следующему полю.
Если пользователь нажал клавишу, за которой закреплен вызов
help-функции, то будет осуществлен вызов специальной help-функции
(если она вами определена), предназначенной для текущего поля,
путем передачи ей адреса буфера накопления данных поля. Если
help-функция вами не создана и help-окно "привязано" к полю, то
help-функции, описанные в Главе 7, обеспечат выдачу на экран
дисплея help-окна. Если ни help-окно, ни help-функция не
определены, то нажатие пользователем help-клавиши не приведет ни
к какому результату, если, конечно, программа использует
help-функции независимо от контекста вводимых в окно данных.
После того, как происходит возврат из функции data_entry в точку
ее вызова, все буферы полей содержат значения данных, которые
ввел пользователь. Эта функция возвращает управление в точку
вызова при нажатии клавиш, означающих конец ввода данных в
шаблон. Таковыми являются клавиша <КЛЮЧ>, клавиши листания
страниц (, ) или функциональные клавиши, приводящие к
завершению процесса ввода данных. Прикладное программное
обеспечение анализирует значение последней нажатой пользователем
клавиши для определения его намерений. Нажатие клавиши <КЛЮЧ>,
например, может означать "Игнорируй все внесенные мной изменения
и верни меня к предыдущему содержанию шаблона". Клавиши <Страница
вверх> () и <Страница вниз> () означают (как
определено в keys.h), что пользователь хочет перейти к следующей
или предыдущей записи базы данных. Когда пользователь завершает
ввод данных, то код завершения процесса ввода передается в
программу, вызвавшую функцию data_entry, для дальнейшего
использования.
Исходный текст: entry.c
-----------------------------------------------------------------
Листинг 8.1 представляет собой исходный текст файла entry.c,
который содержит библиотечные функции поддержки оконного шаблона
ввода данных.
Листинг 8.1: entry.c
/*----------------entry.c----------------*/
#include
#include
#include
#include
#include
#include
#include "twindow.h"
#include "keys.h"
#define FIELDCHAR '_'
int insert_mode = FALSE; /* режим вставки, ВКЛ/ВЫКЛ */
extern int helpkey;
/*----------------локальные прототипы----------------*/
void addfield(WINDOW *wnd, FIELD *fld);
void disp_field(WINDOW *wnd, char *bf, char *msk);
void data_value(WINDOW *wnd, FIELD *fld);
void insert_status(void);
int read_field(WINDOW *wnd, FIELD *fld);
void right_justify(char *s);
void right_justify_zero_fill(char *s);
int validate_date(char *s);
int endstroke(int c);
int spaces(char *c);
/*----------------инициализация шаблона---------------*/
void init_template(WINDOW *wnd)
{
FIELD *fld, *fl;
fld = FHEAD;
while (fld) {
fl = fld->fnxt;
free(fld);
fld = fl;
}
FHEAD = NULL;
}
/*---------------установка полей шаблона--------------*/
FIELD *establish_field(wnd, cl, rw, msk, bf, ty)
WINDOW *wnd;
int rw;
int cl;
char *msk;
char *bf;
int ty;
{
FIELD *fld;
if ( (fld = malloc(sizeof(FIELD))) == NULL)
return NULL;
fld->fmask = msk;
fld->frow = rw;
fld->fcol = cl;
fld->fbuff = bf;
fld->ftype = ty;
fld->fprot = 0;
fld->fnxt = fld->fprv = NULL;
fld->fvalid =NULL;
fld->fhelp = NULL;
fld->fhwin = NULL;
fld->flx = fld->fly = 0;
addfield(wnd, fld);
return fld;
}
/*--------добавление поля в конец списка-----------*/
static void addfield(WINDOW *wnd, FIELD *fld)
{
if (FTAIL) {
fld->fprv = FTAIL;
FTAIL->fnxt = fld;
}
FTAIL = fld;
if (!FHEAD)
FHEAD = fld;
}
/*---------отображение данных в полях----------*/
static void disp_field(WINDOW *wnd, char *bf, char *msk)
{
while (*msk) {
wputchar(wnd, *msk != FIELDCHAR ? *msk : *bf++);
msk++;
}
}
/*--------отображение значений данных в полях-----------*/
static void data_value(WINDOW *wnd, FIELD *fld)
{
wcursor(wnd, fld->fcol, fld->frow);
disp_field(wnd, fld->fbuff, fld->fmask);
}
/*----------отображение всех полей в окне---------------*/
void field_tally(WINDOW *wnd)
{
FIELD *fld;
fld = FHEAD;
while (fld != NULL) {
data_value(wnd, fld);
fld = fld->fnxt;
}
}
/*-----------установка help-окон для полей--------------*/
void field_window(FIELD *fld, char *hwin, int x, int y)
{
fld->fhwin=hwin;
fld->flx = x;
fld->fly = y;
}
/*-----------очистка всех полей шаблона--------------*/
void clear_template(WINDOW *wnd)
{
FIELD *fld;
char *bf, *msk;
fld = FHEAD;
while (fld != NULL) {
bf = fld->fbuff;
msk = fld->fmask;
while (*msk) {
if (*msk == FIELDCHAR)
*bf++ = ' ';
msk++;
}
fld = fld->fnxt;
}
field_tally(wnd);
}
/*---------установка режима вставки/замены курсора------------*/
static void insert_status()
{
set_cursor_type(insert_mode ? 0x0106 : 0x0607);
}
/*------------чтение поля с клавиатуры--------------*/
static int read_field(WINDOW *wnd, FIELD *fld)
{
char *mask = fld->fmask, *buff = fld->fbuff;
int done = FALSE, c, column;
column = fld->fcol;
while (*mask != FIELDCHAR) {
column++;
mask++;
}
while (TRUE) {
wcursor(wnd, column, fld->frow);
c = get_char();
if (fld->ftype == 'A')
c = toupper(c);
clear_message();
switch (c) {
case '\b':
case BS:
if (buff == fld->fbuff) {
done = c == BS;
break;
}
--buff;
do {
--mask;
--column;
} while (*mask != FIELDCHAR);
if (c == BS)
break;
case DEL:
movmem(buff+1, buff, strlen(buff));
*(buff+strlen(buff)) = ' ';
wcursor(wnd, column, fld->frow);
disp_field(wnd, buff, mask);
break;
case FWD:
do {
column++;
mask++;
} while (*mask && *mask != FIELDCHAR);
buff++;
break;
case INS:
insert_mode ^= TRUE;
insert_status();
break;
case '.':
if (fld->ftype == 'C') {
if (*mask++ && *buff == ' ') {
*buff++ = '0';
if (*mask++ && *buff == ' ')
*buff++ = '0';
}
right_justify(fld->fbuff);
wcursor(wnd, fld->fcol, fld->frow);
disp_field(wnd, fld->fbuff, fld->fmask);
column = fld->fcol+strlen(fld->fmask)-2;
mask = fld->fmask+strlen(fld->fmask)-2;
buff = fld->fbuff+strlen(fld->fbuff)-2;
break;
}
default:
if (endstroke(c)) {
done = TRUE;
break;
}
if (toupper(fld->ftype)!='A'&&!isdigit(c)) {
error_message("Numbers only");
break;
}
if (insert_mode) {
movmem(buff, buff+1, strlen(buff)-1);
disp_field(wnd, buff, mask);
wcursor(wnd, column, fld->frow);
}
*buff++ = c;
wputchar(wnd, c);
do {
column++;
mask++;
} while (*mask && *mask != FIELDCHAR);
if (! *mask)
c = FWD;
break;
}
if (!*mask)
done = TRUE;
if (done) {
if (fld->ftype == 'D' &&
c != ESC &&
validate_date(fld->fbuff) !=OK)
return ERROR;
break;
}
}
if (c != ESC && toupper(fld->ftype) != 'A') {
if (fld->ftype == 'C') {
if (*mask++ && *buff == ' ') {
*buff++ = '0';
if (*mask++ && *buff == ' ')
*buff++ = '0';
}
}
if (fld->ftype == 'Z' || fld->ftype == 'D')
right_justify_zero_fill(fld->fbuff);
else
right_justify(fld->fbuff);
wcursor(wnd, fld->fcol, fld->frow);
disp_field(wnd, fld->fbuff, fld->fmask);
}
return c;
}
/*-------проверка значения с на код клавиши завершения------*/
static int endstroke(int c)
{
switch (c) {
case '\r':
case '\n':
case '\t':
case ESC:
case F1:
case F2:
case F3:
case F4:
case F5:
case F6:
case F7:
case F8:
case F9:
case F10:
case PGUP:
case PGDN:
case HOME:
case END:
case UP:
case DN:
return TRUE;
default:
return FALSE;
}
}
/*------------выравнивание вправо, заполнение пробелами------*/