Жанр: Учеба

Техника программирования на турбо-С

сторінка №9

Alt-D = Delete Line
"end"

Функции подсказки
-----------------------------------------------------------------

Для введения контекстно-управляемых окон подсказки в ваши
программы необходимо к ним добавить два вызова функций, которые
находятся в исходном файле thelp.c, представленном ниже в
листинге 7.2.

void load_help(char *filename)

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

void set_help(char *helpname, int x, int y)

Эта функция задает текущее окно подсказки с восьмисимвольным
массивом, соответствующим наименованию окна в файле подсказки.
Наименование окружается в файле подсказки угловыми скобками,
причем не включает в себя эти скобки. Целые числа х и y задают
координаты верхнего левого угла (в символьных позициях) окна
подсказки, что позволяет пользователям использовать одно и то же
окно в различных контекстах, но в различных листах экрана.

Изменение функциональной клавиши подсказки
-----------------------------------------------------------------

Если вам нужно задать значение функциональной клавиши,
отличной от "F1" (по умолчанию), вы должны изменить значение
глобальной целочисленной переменной helpkey. Эта переменная
объявлена в ibmpc.c в Главе 4. Вы можете включить исходный файл
keys.h (см. Главу 4) в вашу программу и использовать одно из
определенных в этом файле значений клавиш. Следующий фрагмент
изменяет функциональную клавишу подсказки на "F2".

#include "keys.h"
extern int helpkey;
helpkey = F2;

Изменение функции подсказки
-----------------------------------------------------------------

Файл с именем ibmpc.c в Главе 4 включает указатель на
функцию с именем helpfunc. Обычно этот указатель содержит
значение NULL. Когда используются функции подсказки, указатель
инициализируется адресом функции с именем help. Если вам нужно
использовать другую функцию, скажем, вместо стандартной функции
help, вы можете изменить значение указателя helpfunc. Для
применения функциональной клавиши подсказки для вызова вашей
функции используйте следующие операторы:

extern void (*helpfunc)();
void yourfunc();
helpfunc = yourfunc;

Вы можете вернуться к указанию helpfunc на стандартную
функцию подсказки с помощью следующих операторов:

extern void (*helpfunc)();
extern void help();
helpfunc = help;

Выключение подсказки
-----------------------------------------------------------------

Имеются три пути для выключения подсказки: вы можете
установить значение функциональной клавиши подсказки равным 0;
можно установить указатель функции подсказки равным NULL; можно
вызвать set_help, передавая указатель на строку нулевой длины.
Для включения подсказки необходимо отменить выбранное действие.


Исходный листинг: thelp.c
-----------------------------------------------------------------

Теперь перейдем к листингу 7.2 thelp.c. Этот файл является
исходным текстом функций, поддерживающих контекстно-управляемые
окна подсказки.

Листинг 7.2: thelp.c

/*---------------------thelp.c------------------*/

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "twindow.h"
#include "keys.h"

#define MAXHELPS 25
#define HBG WHITE
#define HFG BLACK
#define HINT DIM

#define TRUE 1
#define FALSE 0

static struct helps {
char hname [9];
int h, w;
long hptr;
} hps [MAXHELPS+1];

static int hp = 0;
static int ch = 0;
static int hx, hy;
FILE *helpfp = NULL;
long ftell();
char *fgets();
void help();
char helpname[64];
void getline(char *lineh);

/*--------------загружает файл определения HELP!-------------*/
void load_help(char *hn)
{
extern void (*helpfunc)();
extern int helpkey;
char lineh [80];

if (strcmp(helpname, hn) == 0)
return;
helpfunc = help;
helpkey = F1;
hp = 0;
strcpy(helpname, hn);
if ((helpfp = fopen(helpname, "r")) == NULL)
return;
getline(lineh);
while (1) {
if (hp == MAXHELPS)
break;
if (strncmp(lineh, ""end"", 5) == 0)
break;
if (*lineh != '"')
continue;
hps[hp].h = 3;
hps[hp].w =18;
strncpy(hps[hp].hname, lineh+1, 8);
hps[hp].hptr = ftell(helpfp);
getline(lineh);
while (*lineh != '"') {
hps[hp].h++;
hps[hp].w = max(hps[hp].w, strlen(lineh)+2);
getline(lineh);
}
hp++;
}
}

/*--------получает строку текста из файла подсказки---------*/
static void getline(char *lineh)
{
if (fgets(lineh, 80, helpfp) == NULL)
strcpy(lineh, ""end"");
}
/*-----устанавливает текущий активный экран подсказки--------*/
void set_help(char *s, int x, int y)
{
for (ch = 0; ch " hp; ch++)
if (strncmp(s, hps[ch].hname, 8) == 0)
break;
hx = x;
hy = y;
}

/*-------------выдает текущее окно подсказки-----------------*/
void help()
{
char ln [80];
int i, xx, yy;
WINDOW *wnd;
extern int helpkey;
if (hp && ch != hp) {
curr_cursor(&xx, &yy);
cursor(0, 25);
wnd = establish_window(hx, hy, hps[ch].h, hps[ch].w);
set_colors(wnd, ALL, HBG, HFG, HINT);
display_window(wnd);
fseek(helpfp, hps[ch].hptr, 0);
for (i = 0; i " hps[ch].h-3; i++) {
getline(ln);
wprintf(wnd, ln);
}
wprintf(wnd, "[Help] to return");
while (get_char() != helpkey)
putchar(BELL);
delete_window(wnd);
cursor(xx, yy);
}
}

Описание программы: thelp.c
-----------------------------------------------------------------

Программа thelp.c содержит четыре имени #define,
устанавливающих глобальные параметры системы подсказки. MAXHELPS
получает значение максимального количества окон подсказки,
которое программа может поддерживать одновременно. HBG, HFG и
HINT являются цветами фона, переднего плана и яркостью окон
подсказки.

Структура helps описывает окно подсказки. Она содержит
мнемоническое имя окна, его высоту и ширину, а также символьное
смещение описания окна в текстовом файле, включающем окна
подсказки. Массив hps структур helps содержит один элемент для
каждого окна в текстовом файле и строится функцией load_help.
Функция load_help читает текстовый файл подсказки, заданный при
вызове, и строит массив hps. Она распознает угловую скобку,
идентифицирующую каждое имя окна, копируя имя и символьное
смещение в файле в структуру. Затем она читает текст окна для
определения длины и ширины окна. Длина яляется функцией
количества строк текста, а ширина является функцией размера самой
длинной строки текста окна.

Функция set_help просматривает массив для поиска окна с
именем, заданным при вызове. Целочисленная переменная ch, которая
используется для индексации в массиве при поиске, будет содержать
индекс текущего окна при нажатии функциональной клавиши
подсказки. Переменные hx и hy получают значения при вызове. Эта
процедура устанавливает позицию окна.

Функция help вызывается функцией get_char из ibmpc.c при
нажатии заданной функциональной клавиши подсказки. Функция help
сохраняет текущую позицию курсора и убирает курсор с экрана.

Создается окно подсказки с координатами и размерами, записанными
в элементе массива с индексом ch. Текущая символьная позиция в
текстовом файле перемещается к месту, указанному в элементе
массива. Каждая строка текста читается из файла и записывается в
окно. Дописывается последняя строка, сообщающая пользователю о
необходимости повторного нажатия клавиши подсказки для очистки
окна подсказки и возврата. Программа ожидает нажатия клавиши
подсказки, уничтожает окно и восстанавливает курсор на экране в
прежнем положении.

Пример контекстно-управляемой подсказки
-----------------------------------------------------------------

Программы на листингах 7.3, 7.4 и 7.5 представляют пример
использования программного обеспечения подсказки. Листинг 7.3,
sayings.c, содержит главную функцию, вызывающую функцию примера,
maxims.c, показанную в листинге 7.4. Листинг 7.5 является
проектным make-файлом, используемым Турбо Си для построения этого
примера.

Для запуска программы вводите следующую команду:

c"sayings

Программа sayings.c загружает файл teprogs.hlp с помощью
вызова load_help и вызывает функцию с именем maxims. Такая
последовательность была выбрана для того, чтобы maxims.c могла
быть встроена в последующие программы, предусматривающие примеры
обработки меню и резидентных в памяти утилит. Maxims.c
показывает, как использовать set_help и get_char в ваших
программах. Используется только одно окно подсказки. Maxims.c
открывает окно и ожидает нажатия клавиши. Если вы нажимаете 1, 2
или 3, в окне показывается одна из трех старых пословиц. На
рисунке 7.3 изображено окно с одной из таких выданных пословиц.
Если вы нажмете "Ключ", программа завершится. Если будет нажата
"F1", выдается окно подсказки, как показано на рисунке 7.4.

----------------------------------------------------------------¬
¦ ¦
¦ C" ¦
¦ ¦
¦ ¦
¦ ¦
¦ ¦
¦ -----------------Press F1 for help----------------¬ ¦
¦ ¦ A rolling stone gathers no moss ¦ ¦
¦ L-------------------------------------------------- ¦
¦ ¦
¦ ¦
¦ ¦
¦ ¦
¦ ¦
¦ ¦
¦ ¦
¦ ¦
L----------------------------------------------------------------

Рис. 7.3. Выданная пословица

----------------------------------------------------------------¬
¦ C" ¦
¦ ¦
¦ -----------------Press F1 for help--------T------------------¬¦
¦ ¦ A rolling stone gathers no moss ¦Press 1, 2 or 3 ¦¦
¦ L-----------------------------------------+for a pithy maxim.¦¦
¦ ¦[Help] to return ¦¦
¦ L-------------------¦
¦ ¦
¦ ¦
L----------------------------------------------------------------
Рис. 7.4. Подсказка для пословиц

Листинг 7.3: sayings.c

/*--------------sayings.c--------------*/
#include "twindow.h"
void maxims(void);

main()
{
load_help("tcprogs.hlp");
maxims();
}

Листинг 7.4: maxims.c

/*--------------------maxims.c-----------------*/
#include "twindow.h"
#include "keys.h"

void maxims()
{
int c;
WINDOW *wnd;

set_help("maxims ", 50, 10);
wnd = establish_window(5, 10, 3, 50);
set_title(wnd, "Press F1 for help");
set_colors(wnd, ALL, RED, WHITE, DIM);
display_window(wnd);
while ((c = get_char()) != ESC) {
switch © {
case '1':
wprintf(wnd, "\nA stitch in time \
saves nine ");
break;
case '2':
wprintf(wnd, "\nA rolling stone \
gathers no moss");
break;
case '3':
wprintf(wnd, "\nA penny saved \
is a penny earned");
break;
default:
break;
}
}
delete_window(wnd);
}

Листинг 7.5: sayings.prj

saying
maxims (twindow.h, keys.h)
thelp (twindow.h, keys.h)
twindow (twindow.h, keys.h)
ibmpc.obj

Резюме
-----------------------------------------------------------------

Ваши оконные средства теперь включают возможность контекстно
-управляемой подсказки. Следующие главы содержат дополнительные
возможности обработки окон и примеры их использования. Каждый
пример использует окна контекстно-управляемой подсказки, поэтому
ваше понимание средств подсказки возрастает с каждой добавленной
возможностью. Это обучение имеет существенное значение,
поскольку, как правило, диалоговые программы должны
предусматривать оперативную подсказку пользователю. Следующее
дополнение к использованию окон в диалоговой программе
представлено в Главе 8, которая описывает использование окон в
качестве форм для ввода данных. Глава 8 включает функции,
позволяющие вам описывать содержимое и формат шаблона ввода
данных, и описывает программное обеспечение для сбора элементов
данных, вводимых пользователем в форму.

ГЛАВА 8


-------

Использование данных в окнах
-----------------------------------------------------------------

Интерактивные программы интерпретируют значения данных
внутри компьютера в соответствии с типами данных, определенными
пользователем. Эти значения данных могут интерпретироваться
по-разному, поэтому программы могут использовать разнообразные
технические приемы для интерпретации значений вводимых данных.
Например, текстовый процессор интерпретирует данные, поступающие
на его вход, как текст произвольной формы. Электронный бланк
интерпретирует данные в соответствии с совокупностью форматов
строки и столбца, в которой в данный момент находится курсор.
Однако одни и те же данные каждая программа "видит и чувствует"
по-разному. Поэтому даже правильное копирование входного потока
одной программы на вход другой может привести к массе спорных
результатов, которые в этом случае выдает вторая программа.

Многие интерактивные программы воспринимают значения данных
непосредственно в той форме, в которой пользователь осуществляет
их физический ввод (например, данные в печатной форме (бланк)).
Каждая, сходная с печатной, форма представления данных
определялась Государственной налоговой службой. Формоориентированные
интерактивные программы интерпретируют программы
как лист бумаги, содержащий поля со значениями данных и текст,
описывающий значение каждого поля. После того, как пользователь
введет значение данного в соответствующие позиции поля,
программное обеспечение проверяет допустимость введенного
значения и дальнейшее управление курсором. В этой главе
формо-ориентированный ввод данных, указание доступа к ним и
контроль операций над ними реализован путем использования окна
как шаблона для ввода данных. Шаблон ввода данных включает в себя
окно вместе с описанием вводимых в каждое поле данных и именами
полей ввода данных.

Шаблон ввода данных
-----------------------------------------------------------------

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

Поле ввода данных
-----------------------------------------------------------------

Поле ввода данных, по сути дела, представляет собой элемент
данных. Оно может быть датой, результатом вычисления суммы
чего-либо, именем или вычисленной средней заработной платой. Поле
ввода данных имеет следующие характеристики: оно имеет
определенную длину и формат и должно занимать одну строку окна.
Поле ввода данных - традиционный элемент систем управления базами
данных (СУБД).

После того, как вы описали поля шаблона, вы должны
специфицировать позицию размещения поля в шаблоне, атрибуты,
выходной буфер, функцию проверки допустимости данных,
help-информацию и маску вводимых данных для каждого поля. Эти
компоненты описания полей рассматриваются ниже.

Позиция
------------------------------------------------------------------

Позиция поля задается выражением, состоящим из номера строки
и столбца символьных координат, соответствующих местоположению
текста в шаблоне окна. Предпочтительнее задавать координаты
позиции поля относительно координат окна, а не экрана; если вы
вдруг решите изменить координаты расположения самого окна, то в
случае описания позиции поля в координатах окна описание позиции
поля вам изменять не придется.

Атрибуты
------------------------------------------------------------------

Атрибут поля позволяет описать вводимые в него данные как
имеющие один из существующих типов данных. Тип данных задается
отдельной буквой (которые рассмотрены в данной главе). Однако уже
сейчас вам необходимо знать, что вы можете специфицировать поле
как поле даты, спецификации, денежной единицы или как числовое.
Задание атрибута поля позволяет контролировать, каким способом
будут интерпретированы значения данных в поле.

Буфер
-----------------------------------------------------------------

Для каждого поля назначается выходной буфер данных, который
является адресом символьного массива, в котором будет происходить
накопление данных. Ваша программа резервирует память под этот
буфер и передает его адрес данным внутри прикладной программы.

Проверка допустимости значений
-----------------------------------------------------------------

Ваша программа генерирует адрес функции проверки
допустимости вводимых значений так, как будто сама эта функция
используется. Программное обеспечение ввода данных будет вызывать
эту функцию всегда после того, как вы ввели данное в поле.
Следует заметить, что при вводе данных программное обеспечение
само осуществляет автоматическую проверку некоторых основных
ограничений в соответствии с атрибутами поля, однако, используя
дополнительные подпрограммы проверки значений, вы можете
существенно расширить и усложнить проверку данных по различным
критериям.
Help-информация
-----------------------------------------------------------------

Вы можете специфицировать вспомогательное help-окно (которое
описано в Главе 7) для каждого поля, а также help-функцию для
каждого поля, которая будет вам выдавать справочную информацию о
предназначении каждого поля в случае, если постоянный текст,
описывающий поле и отображаемый в окне, не удовлетворяет вашему
любопытству. Help-окно получает информацию из специального
help-файла, в связи с чем включение help-функций в программу
обязательно. При желании вы можете не специфицировать свои
help-функции, а использовать стандартные help-функции пакета,
которые могут быть вызваны пользователем путем нажатия на
соответствующую help-клавишу. Следует помнить, что использование
соответствующей help-спецификации эффективно лишь в процессе
ввода пользователем данных в поле, для которого эта
help-информация предназначена.

Маска вводимых данных
-----------------------------------------------------------------

Когда вы определяете поле для ввода данных, вы можете задать
маску для всех вводимых в это поле значений. Эта маска
специфицируется в массиве символов, включающем в себя символы
нижнего подчеркивания и пунктуации. Символ нижнего подчеркивания
соответствует позиции маски, в которой возможен ввод данных, а
пунктуация служит для обозначения других (различных) отображаемых
символов кода ASCII. Длина элементов данных описывается
количеством символов нижнего подчеркивания, а длина буфера,
выделяемого под вводимые данные, описываемые маской, должна быть
не меньше, чем длина элемента данных плюс 1. Символы пунктуации в
буфер не перекачиваются. Например, маска вводимых данных,
касающихся номера телефона (включая код местности и расширение)
может иметь следующий вид:

char phone_mask [] = "(____)____-____ ext:_____";

Приглашения к вводу в поле (Prompts)
-----------------------------------------------------------------

Каждое поле может иметь свое специфичное приглашение к вводу
в него данных, которое обычно содержит информацию, поясняющую
пользователю, для чего предназначено данное поле (семантика поля)
и какая именно информация должна быть в него введена. Такое
приглашение представляет собой символьную строку, которую
пользователь изменить не может. Вы должны сами специфицировать Ввод данных
-----------------------------------------------------------------

В процессе своей работы функция ввода данных обрабатывает
поля шаблона в той последовательности, в которой вы осуществляли
их описание (не принимая во внимание позиции их размещения в
шаблоне), осуществляя при этом простейшую проверку допустимости
находящихся в полях шаблона данных (правильность даты, поле
должно содержать только цифры и т.д.). Вы можете также определить
обычную (в смысле Си) функцию, которая будет осуществлять
дальнейшую, возможно, сложную и разнообразную, проверку вводимых
данных или определить функцию, которая будет выдавать в случае
ввода недопустимых данных специальную help-информацию
пользователю. В процессе ввода данных в шаблон используется
выделение в соответствии с указанными атрибутами (ACCENT) цвета
окна более ярким тоном полей, в которые предполагается ввод
данных. При этом курсор на экране компьютера переходит в
соответствующую позицию поля. В случае, если пользователь
инициирует другой порядок ввода данных, переходя от поля к полю,
то выделение следующего, выбранного пользователем поля ввода, и
перемещение курсора также осуществляется программно.

Функции сбора данных
-----------------------------------------------------------------

Эти функции, являющиеся библиотечными функциями, ваша
программа так или иначе вызывает при использовании окна с
шаблоном ввода данных. Запомните, что вы должны вначале
установить окно, а лишь затем использовать эти функции.

void init_template(WINDOW *wnd)

Эта функция инициализирует окно для использования в нем
шаблона ввода данных. Она устанавливает связной список структур
FIELD и производит очистку всех существующих дескрипторов.
Структура FIELD, описывающая характеристики полей ввода данных,
определена в twindow.h (см. Главу 6). Функция inint_template
предназначена для выполнения двух задач. Во-первых, она
инициализирует окно; во-вторых, если окно инициализировано, она
осуществляет поиск и уничтожение всех установленных на данный
момент полей окна; следовательно, использование этой функции
возможно в ситуации, когда шаблон окна не является достаточно
большим, так как использование функции приводит к освобождению
структур FIELD.

FIELD *establish_field
(WINDOW *wnd,int x,int y,char *msk,char *bf,int t)

Эта функция устанавливает поля ввода данных в окне, которое
было инициализировано функцией init_template как окно с шаблоном
ввода данных. Символы x и y суть координаты, специфицирующие
размещение маски поля ввода, причем предпочтительнее указывать
координаты относительно окна, а не экрана. Указатель bf суть
указатель на определяемый при обращении буфер сбора данных.
Параметр t (значение типа integer) указывает тип поля ввода
данных. Различают следующие типы полей:

А = алфавитно-цифровое
N = цифровое, незначащие разряды заполнены пробелами
Z = цифровое, незначащие разряды заполнены нулями
С = поле денежной единицы
D = поле даты

Указатель msk является указателем на символ маски, который
определяет длину поля и управляет отображением символа пунктуации
на экране (причем последние не контролируются в буфер сбора
данных поля). Маска включает в себя обычно несколько символов.
Символ подчеркивания указывает позицию символа, который должен
быть введен в данном месте. Массив bf должен содержать столько
символов, сколько символов подчеркивания содержит маска, плюс
один символ (для символа конца строки \0).

Поле денежной единицы может иметь произвольное число цифр
слева от десятичной точки и две цифры справа от нее.

Дата должна соответствовать формату "ММДДГГ". Если
пользователь неправильно ввел дату, программа выдает сообщение об
ошибке и требует от пользователя повторного ввода даты.


Функция establish_field возвращает указатель на структуру
FIELD, определенную в twindow.h. Вы можете использовать этот
указатель при обращении к field_window, field_help, field_protect
и field_validate, которые описаны ниже.

void wprompt(WINDOW *wnd, int x, int y, char *s)

Эта функция осуществляет выдачу приглашения на ввод данных в
окно. Приглашение на ввод данных является строкой s, котор

Список сторінок

Поділитися у соцмережах

☏ Замовлення реклами: +3805044-68-872

© Асоціація електронних бібліотек України

☝ Усі матеріали сайту (зокрема статті, зображення, рекламні оголошення тощо) призначені лише для попереднього ознайомлення. Усі права на публікації, представлені на сайті, належать їхнім законним власникам. Просимо Вас не зберігати копії інформації.