Редакторы |
Предыдущая Содержание Следующая |
Те же структуры меню могут быть расширены, чтобы сделать простые редакторы.
В дополнение к функции действия, вариант меню редактора будет иметь обработчик кнопок, принимающий консольный ввод и сохраняющий его в память, и, при необходимости, функцию подсказки, чтобы получить текущие настройки в память и построить строку для показа пользователю:
typedef struct _selection { char prompt[MAX_PROMPT_LEN]; int (*function)(int); /* функция действия */ int fn_arg; char * (*pro_function)(int); /* функция подсказки */ int pro_fn_arg; int (*key_function)(int); /* обработка кнопок */ int key_fn_arg; }SELECTION;
Предположим, что наш банкомат теперь позволяет клиенту обновить водительские права, введя соответствующую информацию (имя, номер лицензии, адрес). Этот код показан в Листинге 2.
Аргументы функций обработки кнопок и подсказки, как правило, будут одинаковы, и, вероятно, их можно объединить, чтобы сэкономить в меню место. Функции display() и keyedit() сами по себе будут в основном большими операторами switch(), обрабатывающими аргумент функции подсказки и обработки кнопок.
typedef struct _selection { char prompt[MAX_PROMPT_LEN]; int (*function)(int); /* функция действия */ int fn_arg; char * (*pro_function)(int); /* функция подсказки */ int (*key_function)(int); /* обработка кнопок */ int pro_key_fn_arg; }SELECTION;
/* глобальные переменные */ char global_curr_name[80]; int global_curr_lnum; char global_curr_address[80]; char workbuf[80];
// временный буфер ввода/вывода char * prompt(int state) { switch(state) { case NAME: strcpy(workbuf, global_curr_name); break;
case LNUM: sprintf(workbuf, "%d", global_curr_lnum); break;
case ADDRESS: strcpy(workbuf, global_curr_address); break; } return(workbuf); }
Функция draw_menu() теперь обходит все варианты выбора, выводит строку подсказки (как и раньше), а также проверяет наличие функции подсказки. Если она существует, система вызовет функцию подсказки, возвращающую строку в рабочем буфере порта (workbuf). Эта строка затем будет показана в правильном месте экрана:
void draw_menu(MENU * menu) { int selection_num; SELECTION * selptr;
/* очистить экран */ cls();
/* обойти все варианты выбора в ДАННОМ меню */
for(selection_num=0; selection_nummenu->num_selections; selection_num++) { /* для удобства создаём указатель */ selptr = &menu->selection[selection_num];
/* Если это "активный" элемент меню (определяем это с помощью ссылки на глобальную переменную 'active_selection'), отрисовать его инвертированным текстом. */
if (selection_num == active_selection) inverse(ON);
/* напечатать строку подсказки */ setcur(selection_num + MENU_INDENT_Y, MENU_INDENT_X);
printf(selptr->prompt);
/* если этот вариант имеет функцию подсказки, используем её! */ if(selptr->pro_function) { /* напечатать строку подсказки */ setcur(selection_num + MENU_INDENT_Y, PROMPT_INDENT_X); printf((*selptr->pro_function)(selptr->pro_key_fn_arg)); }
/* если необходимо, выключаем печать инвертированным текстом */
if (selection_num == active_selection) inverse(OFF); } }
Функция mdi() переходит к вызову функции обработки ввода с кнопок только после завершения верного ввода, как это показано в Листинге 3.
Теперь, когда имеется основная система меню, каким образом программист справляется с дополнительными потребностями? Этот очень универсальный подход к меню хорошо подходит для дополнительных возможностей. |
Предыдущая Содержание Следующая |