Редакторы

Предыдущая  Содержание  Следующая V*D*V

Те же структуры меню могут быть расширены, чтобы сделать простые редакторы.

 

В дополнение к функции действия, вариант меню редактора будет иметь обработчик кнопок, принимающий консольный ввод и сохраняющий его в память, и, при необходимости, функцию подсказки, чтобы получить текущие настройки в память и построить строку для показа пользователю:

 

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.

 

Теперь, когда имеется основная система меню, каким образом программист справляется с дополнительными потребностями? Этот очень универсальный подход к меню хорошо подходит для дополнительных возможностей.

Предыдущая  Содержание  Следующая