Жанр: Учеба
Техника программирования на турбо-С
...insert_status изменяет
тип курсора в соответствии со значением переменной insert_mode.
Режим вставки обуславливает наличие квадратного курсора, а режим
замены символов - наличие курсора в виде нижнего подчеркивания.
Для изменения формы курсора используется функция set_cursor_type
из библиотеки ibmpc.c (см. Главу 4).
Функция read_field используется для чтения введенных
пользователем в поля данных. Она устанавливает курсор в начало
поля и считывает последовательность символов в нем. Два локальных
указателя используются для трассировки вводимых данных. Указатель
mask позволяет получить текущую позицию в маске, а указатель buff
- текущую позицию в буфере. При перемещении пользователем
курсора, уничтожении или вводе символов значение этих указателей
корректируется.
При выполнении операции по уничтожению символов используется
функция Турбо Си movmem, которая используется для сдвига символов
в буфере, а также функция disp_field для отображения результатов
операции на экране.
Клавиша "ВСТ" ("Ins") переключает режимы Вставки/Замены.
Если текущее поле включает в себя точку (.), то оно содержит
нули в двух крайних правых позициях (если другие значения в них
не указаны), выравнено вправо, а соответствующие указатели и
курсор устанавливаются на значащие позиции, предназначенные для
указания пенни (денежной единицы).
Если пользователь нажал клавишу, символизирующую завершение
ввода данных, то данная ситуация обрабатывается функцией
endstroke, и ввод данных завершается. В противном случае символ
будет записан в буфер. Если в данный момент обрабатывалось не
алфавитно-цифровое поле, то анализируется ситуация на предмет
ввода пользователем числа. Если было введено не число, то
выдается сообщение об ошибке, и программа не воспринимает
введенные данные, требуя их повторного ввода. Если включен режим
вставки, то данные в буфере смещаются на одну позицию вправо, а
значение поля после вставки символа отображается с помощью
функции disp_field. При этом символ записывается в буфер и
отображается на экране. Совместное использование указателей маски
и буфера позволяет "перескакивать" через символы пунктуации.
После ввода последнего символа в поле дальнейший ввод данных в
него прекращается.
После завершения ввода данные проверяются на допустимость,
даты и числа выравниваются, курсор устанавливается в
соответствующую позицию поля и содержимое полей отображается на
экране.
Функция endstroke анализирует значение клавиш и
устанавливает клавиши, которые могут привести к завершению
процесса ввода данных.
Есть две функции, занимающиеся выравниванием данных. Первая
- right_justify, выравнивающая справа и заполняющая поле
пробелами. Вторая - right_justify_zero_fill, выравнивающая справа
и заполняющая поле нулями.
Функция spaces анализирует поле на наличие всех пробелов.
Функция validate_date осуществляет проверку даты.
Функция data_entry вызывается для обработки всех полей
шаблона. Функция вызывает field_fally для выдачи на экран всех
значений данных из соответствующих буферов полей. Затем функция
обрабатывает "сверху-вниз" связный список структур FIELD и
управляет вводом данных в каждом поле.
Функция set_help вызывается для осуществления привязки
оконной help-информации к конкретному полю. Поскольку значение
глобальной переменной helpkey определено заранее, то попытка
получить для этого поля специальную help-информацию закончится
безуспешно, поскольку программа data_entry будет перехватывать
прерывание от клавиши help-функции.
Если поле не является защищенным, то функция reverse_video
вызывается каждый раз, когда необходимо получить выделенное
отображение поля в соответствии с конфигурацией цветов,
определенной параметром ACCENT. Для выдачи на экран значения
текущего поля в акцентированном режиме, определяемом параметром
ACCENT, используется функция data_value, а для ввода в программу
введенных в поле пользователем данных применяется функция
read_field. Значением, возвращаемым функцией read_field, является
итоговая последовательность символов, суть которой - введенные в
поле данные. Если поле имеет свою специальную функцию контроля
данных, то вызывается эта функция.
При условии, что контроль данных по всем параметрам прошел
нормально, функция normal_video переводит окно в так называемый
контрольный режим отображения данных, цвет которого определяется
значением NORMAL, и функция data_value повторно выводит на экран
значение поля, но уже в NORMAL-цвете. Затем анализируется
завершающая последовательность нажатия клавиш. Если ввод данных
прерван клавишей, закрепленной за вызовом специальной
help-функции, то осуществляется обращение к этой функции. В связи
с тем, что в процессе обработки полей реализована возможность
заменять буферизованные данные полей полностью, функция
data_value снова вызывается для повторного отображения поля после
его обработки.
Завершающей клавишей в процессе ввода данных могут быть либо
клавиши движения вперед (стрелка вниз, ВВОД, Таб), либо клавиши
движения назад (стрелка вверх, стрелка влево). Следующее поле для
обработки выбирается из связного списка FIELD, специфицированного
параметром WINDOW, в зависимости от значений этих клавиш (вперед
или назад). При этом выбирается следующее или предыдущее поле, и
ввод данных продолжается.
Если последней была нажата одна из тех клавиш, которые
анализируются функцией endstroke и не являются аналогом ранее
встречающихся и анализируемых функцией последовательностей, то
ввод данных в оконный шаблон завершается, и функция data_entry
возвращает управление в точку вызова.
Пример: Ввод данных в определенном порядке
-----------------------------------------------------------------
Исходные файлы, представленные на листингах 8.2, 8.3 и 8.4,
суть примеры использования шаблона ввода данных в окне. Листинг
8.2, order.c, представляет собой текст главной функции (main),
которая осуществляет обращение к функции ordent.c,
непосредственно реализующей пример. Функция ordent.c будет в
дальнейшем присутствовать при рассмотрении примера меню в Главе
10 и резидентной утилиты в Главе 12. Листинг 8.4 представляет
собой make-файл order.prj, используемый утилитой make Турбо Си
для построения программы примера.
Для выполнения программы примера введите команду
C"order
Окно, представленное на рисунке 8.2, является по сути дела
"всплывающим", то есть появляющимся в позиции курсора. Однако
обратитесь к листингу 8.3, ordent.c, предварительно ознакомившись
с описанием программы, приведенным ниже. После того, как вы
ознакомились с листингом, выполните программу.
----------------------------------------------------------------¬
¦ ¦
¦ C" ¦
¦ ¦
¦ -------------Order Entry-------------¬ ¦
¦ ¦ ¦ ¦
¦ ¦ Name: ¦ ¦
¦ ¦ Address: ¦ ¦
¦ ¦ City: ¦ ¦
¦ ¦ State: Zip: ¦ ¦
¦ ¦ ¦ ¦
¦ ¦ Amount: . ¦ ¦
¦ ¦ Date: / / ¦ ¦
¦ ¦ ¦ ¦
¦ ¦ Phone: ( ) - ¦ ¦
¦ ¦ ¦ ¦
¦ L------------------------------------- ¦
¦ ¦
L----------------------------------------------------------------
Рис.8.2. Образец ввода шаблона ввода данных
Пример программы начинается с установки окна и передачи ему
значения заголовка и цвета. Окно отображается на экране дисплея,
и в шаблоне появляется приглашение к вводу данных. После
обращения к функции init_template осуществляется идентификация
help-информации для каждого поля (help-информация размещается в
пределах окна), которая поясняет назначение вводимых в каждое
поле данных. Установка оконной help-информации осуществляется
путем обращения к функции field_window. Каждое поле
непосредственно устанавливается в шаблоне путем обращения к
функции establish_field. Последнее поле устанавливается в этом
примере как не использующее оконную help-информацию. Поэтому для
данного поля с помощью функции field_help идентифицируется
специальная help-функция. Обратите внимание, что одно поле
шаблона - "state" - описано как имеющее специальную функцию
контроля данных, вводимых в него, на достоверность. Эта
специальная функция контроля данных специфицирована в обращении к
функции field_validate.
Программа обращается к функции clear_template для получения
пустого шаблона ввода данных, а затем - к функции data_entry,
позволяющей обрабатывать данные, вводимые в шаблон. По завершению
работы функции data_entry программа уничтожает окно. В реальной
задаче в этой точке программы вы должны предусмотреть обработку
введенных данных. В нашем примере после уничтожения окна
программа завершает свою работу.
Во время выполнения программы обратите внимание, каким
образом вводимые символы помещаются в позиции определенных полей,
а также на управление курсором. Режим Вставки/Замены символов
управляется с помощью клавиши "Ins" и индуцируется
соответствующей формой курсора. Если курсор отображается как
мерцающий символ подчеркивания в обычном своем виде, то это
означает, что данные вводятся в режиме замены символов. После
того, как вы нажмете клавишу "Ins", курсор примет форму
мерцающего прямоугольника, и вы будете продолжать работу в режиме
вставки символов.
Нажмите клавишу "F1" для получения справочной информации по
каждому из полей шаблона. На рисунке 8.3 изображен шаблон с
некоторыми значениями полей в момент выдачи по запросу
пользователя оконной help-информации. Нажмите клавишу "F1" для
поля "State" и получите оконную help-информацию для него.
Обратите внимание, что в качестве help-информации выступает
перечень допустимых значений поля "State". Выберите одно из них и
введите в качестве значения поля. На примере этого поля
внимательно изучите, как работает специальная функция контроля
данных, как она использует функцию error_message для выдачи
сообщений о вводе недопустимых данных. Рисунок 8.4 наглядно
демонстрирует именно случай неправильного ввода данных в поле
"State". Специальная help-функция для поля даты ("Date")
демонстрирует, как можно получить значение даты извне функции
data_entry. В данном примере для чтения текущей даты используется
функция Турбо Си getdate, после чего текущая дата записывается в
соответствующий буфер поля "Date".
----------------------------------------------------------------¬
¦ C" -----------------------------¬ ¦
¦ ¦ Enter the address of the ¦ ¦
¦ ¦ person who is placing the ¦ ¦
¦ ------------- Order entry¦ order. ¦ ¦
¦ ¦ ¦ [Help] to return ¦ ¦
¦ ¦ L---------------------T------- ¦
¦ ¦ Name: Clifford Brown ¦ ¦
¦ ¦ Address: 123 Main Street ¦ ¦
¦ ¦ City: Springfield ¦ ¦
¦ ¦ State: VA Zip: 21333 ¦ ¦
¦ ¦ ¦ ¦
¦ ¦ Amount: 23.40 ¦ ¦
¦ ¦ Date: 26/07/87 ¦ ¦
¦ ¦ ¦ ¦
¦ ¦ Phone: (202) 321-3211 ¦ ¦
¦ ¦ ¦ ¦
¦ L----------------------------------------------- ¦
L----------------------------------------------------------------
Рис. 8.3. Образец ввода шаблона ввода данных с данными
и help-информацией
----------------------------------------------------------------¬
¦ C" ¦
¦ --------------Order Entry-----------------¬ ¦
¦ ¦ ¦ ¦
¦ ¦ Name: Clifford Brown ¦ ¦
¦ ¦ Address: 123 Main Street ¦ ¦
¦ ¦ City: Springfield ¦ ¦
¦ ¦ State: TX Zip: 21333 ¦ ¦
¦ ¦ ¦ ¦
¦ ¦ Amount: 23.40 ¦ ¦
¦ ¦ Date: 26/07/87 ¦ ¦
¦ ¦ ¦ ¦
¦ ¦ Phone: (202) 321-3211 ¦ ¦
¦ ¦ ¦ ¦
¦ L------------------------------------------ ¦
¦ ¦
¦ ------ERROR!-----¬ ¦
¦ ¦ ¦ ¦
¦ ¦ Invalid State ¦ ¦
¦ L----------------- ¦
¦ ¦
L----------------------------------------------------------------
Рис. 8.4. Проверка корректности ввода данных
Листинг 8.2: order.c
/*-----------order.c---------*/
#include "twindow.h"
void ordent(void);
main()
{
load_help("tcprogs.hlp");
ordent();
}
Листинг 8.3: ordent.c
/*-----------------ordent.c----------------*/
#include "dos.h"
#include "stdio.h"
#include "string.h"
#include "twindow.h"
struct {
char name [26];
char addr [26];
char city [26];
char state [3];
char zip [6];
char amt [6];
char dt [7];
char phone [11];
} rcd;
char msk25 [] = "__________________________";
char mskamt [] = "____.____";
char mskdate [] = "___/___/___/";
char mskphone [] = "(___) ____-____";
#define mskst msk25+23
#define mskzip msk25+20
int validate_state(char *, int);
void help_date(char *);
void ordent()
{
WINDOW *wnd;
FIELD *fld;
wnd = establish_window(10, 5, 15, 50);
set_title(wnd, " Order Entry ");
set_colors(wnd, ALL, BLUE, AQUA, BRIGHT);
set_colors(wnd, ACCENT, WHITE, BLACK, DIM);
display_window(wnd);
wprompt(wnd, 5, 2, "Name:");
wprompt(wnd, 5, 3, "Address:");
wprompt(wnd, 5, 4, "City:");
wprompt(wnd, 5, 5, "State:");
wprompt(wnd, 18, 5, "Zip:");
wprompt(wnd, 5, 10, "Phone:");
wprompt(wnd, 5, 7, "Amount:");
wprompt(wnd, 5, 8, "Date:");
init_template(wnd);
fld = establish_field(wnd, 15, 2, msk25, rcd.name, 'a');
field_window(fld,"name ", 40, 1);
fld = establish_field(wnd, 15, 3, msk25, rcd.addr, 'a');
field_window(fld,"address ", 40, 2);
fld = establish_field(wnd, 15, 4, msk25, rcd.city, 'a');
field_window(fld, "address ", 40, 3);
fld = establish_field(wnd, 15, 5, mskst, rcd.state, 'A');
field_validate(fld, validate_state);
field_window(fld,"state ", 40, 4);
fld = establish_field(wnd, 23, 5, mskzip, rcd.zip, 'Z');
field_window(fld,"address ", 40, 4);
fld = establish_field(wnd,15,10,mskphone,rcd.phone, 'N');
field_window(fld,"phone ", 40, 9);
fld = establish_field(wnd, 15, 7, mskamt, rcd.amt, 'C');
field_window(fld,"amount ", 40, 8);
fld = establish_field(wnd, 15, 8, mskdate, rcd.dt, 'D');
field_help(fld, help_date);
clear_template(wnd);
data_entry(wnd);
delete_window(wnd);
}
/*--------проверка состояния нажатой клавиши----------*/
int validate_state(bf, key)
char *bf;
{
static char *states [] =
{" ","VA","NC","SC","GA","FL",0};
char **st = states;
while (*st)
if (strcmp(*st++, bf) == 0)
return OK;
error_message("Недопустимое состояние ");
return ERROR;
}
/*-------выдает сегодняшнюю дату------*/
void help_date(bf)
char *bf;
{
struct date dat;
getdate(&dat);
sprintf(bf, "%02d%02d%02d",
dat.da_day, dat.da_mon, dat.da_year % 100);
}
Листинг 8.4: order.prj
order
ordent (twindow.h)
entry (twindow.h, keys.h)
thelp (twindow.h, keys.h)
twindow (twindow.h, keys.h)
ibmpc.obj
Резюме
-----------------------------------------------------------------
Оконная библиотека содержит сейчас средства создания
контекстно-зависимой help-информации и форматного ввода данных.
Эти средства вы можете с успехом использовать при создании систем
интерактивного ввода данных. Шаблон ввода данных поддерживает
фиксированные форматы вводимых данных. В Главе 9 в функции
текстового редактора добавлены новые, одна из них - возможность
использования окна для ввода и модификации произвольного текста.
ГЛАВА 9
-------
Оконный текстовый редактор
-----------------------------------------------------------------
В Главе 8 обсуждалось применение видеоокон для
использования ввода данных в поля формо-ориентированного шаблона
ввода данных. Естественно, что не все поля данных имеют заранее
определенный, фиксированный формат. Многие поля и файлы состоят
из текстов свободной, неопределенной формы и последовательности,
например, слова в книге или комментарии к программе. Текстовые
процессоры и редакторы текстов позволяют вам строить текстовые
файлы, игнорируя формат исходных данных (текста), однако, если
вы создаете действительно интегрированную систему , то доступ
к функциям ввода текста в вашу программу и его редактирование
может вам понадобиться непосредственно из вашей прикладной
программы.
Эта глава является предварительным описанием оконного
текстового редактора, который использует видеоокна для ввода и
модификации текста точно так же, как большинство программ
редактирования текста и текстовых процессоров. Эта отличительная
черта оконного редактора используется при создании программных
систем, в которых требуется ввод текста произвольной формы. Пакет
Sidekick является примером системы, в которой имеется сходный с
рассматриваемым в этой главе редактор текстов. Пример программы,
представленный в этой главе, вполне может использоваться в
качестве редактора текстов в системах типа Sidekick. Оконный
текстовый редактор может также применяться в системах ввода
данных, когда требуется ввести в качестве данных текст
произвольной формы, занимающий более одной строки. Прикладная
программа типа программы ввода данных в заданном порядке с
помощью шаблона ввода данных из Главы 8 может потребовать ввода
поля, содержащего описательный текст. Это требование можно легко
реализовать, применяя оконный текстовый редактор. Многие базы
данных оперируют с данными, характеризующимися наличием
поясняющего их текста, различных описаний или определенной
терминологии предметной области. При использовании шаблонов ввода
данных поля данных такого типа могут с успехом обрабатываться
оконным редактором. вы также можете использовать текстовый
редактор для подготовки текстов help-окон в вашей программе путем
обработки файла описаний help-окон, описанного в Главе 7.
Для использования текстового редактора программа вначале
устанавливает окно, а затем резервирует буфер, в котором будут
храниться и редактироваться данные, вводимые пользователем.
Текстовый буфер редактора представляет собой массив,
резервирующий память, достаточную для хранения фиксированного
числа строк, каждая из которых равна ширине области окна,
отводимой для ввода и редактирования текста. Например, если вы
установили ширину окна в 42 символа, то область текста будет
иметь ширину 40 символов (рамка окна занимает 2 позиции). Если вы
в этом случае отвели под буфер 4000 символов (длина массива), то
редактор сможет обрабатывать одновременно только 100 строк
текста, так как буфер может содержать не более 100 строк текста
по 40 символов в строке. При вводе пользователем текста он
накапливается в буфере без специальных символов новой строки (\n)
и табуляции (\t).
Если текстовый буфер уже содержит текст, который был занесен
в него при первом обращении к редактору, то этот старый текст
отображается на экране дисплея в виде строк фиксированной длины в
соответствии с описанием окна.
Команды тестового редактора
-----------------------------------------------------------------
Текстовый редактор содержит полный набор команд
редактирования. Команды сведены в один перечень и могут быть
отображены на экране дисплея в виде, представленном на рисунке
9.1. В прошлой главе была рассмотрена программа, которая
использовала help-окно для выдачи различной информации. Help-окно
отображается при нажатии клавиши "F1". Точно такой же прием
используется для отображения набора команд редактора. Большинство
из команд редактирования закреплено за функциональными клавишами,
остальные используют комбинации клавиш "Ctrl" или "ALT" с другими
клавишами. Ниже будут рассмотрены все команды оконного текстового
редактора.
----------------------------------------------------------------¬
¦----------------------------------------------------------¬ ¦
¦¦------Cursor Movement--------------Page Movement-------- ¦ ¦
¦¦arrows = move text cursor Ctrl-Home = Beginning of File ¦ ¦
¦¦Ctrl-T = Top of Window Ctrl-End = End of File ¦ ¦
¦¦Ctrl-B = Bottom of Window PgUp = Previous Page ¦ ¦
¦¦Ctrl -"= Next Word PgDn = Next Page ¦ ¦
¦¦Ctrl "-= Previons Word +¬ ¦
¦¦Home = Beginning of Line --------Editor control------- ¦¦ ¦
¦¦End = End of Line Scroll Lock = No Auto Reform ¦¦ ¦
¦¦ ¦¦ ¦
¦¦ ¦¦ ¦
¦¦-------Block controls---------------Edit commands------- ¦¦ ¦
¦¦F4 = Form Paragraph F2 or Esc = Done ¦¦ ¦
¦¦F5 = Mark Block Beginning F3 = Erase File ¦¦ ¦
¦¦F6 = Mark Block End Ins = Togle Insert Mode ¦¦ ¦
¦¦F7 = Move Block Del = Delete Char ¦¦ ¦
¦¦F8 = Copy Block "-- = Rubout ¦¦ ¦
¦¦F9 = Delete Block Ctrl-D = Delete Word ¦¦ ¦
¦¦F10 = Unmark Block Alt-D = Delete Line +- ¦
¦¦ [Help] to return ¦ ¦
¦L---------------------------------------------------------- ¦
¦ ¦
¦ ¦
¦ ¦
L----------------------------------------------------------------
Рис. 9.1. Команды текстового редактора
Управление курсором
-----------------------------------------------------------------
Используя клавиши управления курсором, его можно перемещать
по всему экрану. Если вы переместили курсор в начало или в конец
экрана и продолжаете нажимать клавишу перемещения курсора вверх
(или вниз), то тем самым вы инициируете скроллинг текста, который
будет продолжаться до достижения начала (конца) буфера данных.
- "Ctrl/Т" и "Ctrl/В" перемещают буфер в начало и конец экрана;
- "Ctrl/(курсор вправо)" перемещает курсор в начало следующего
слова в буфере хранения текста;
- "Ctrl/(курсор влево)" перемещает курсор в начало предыдущего
слова в буфере хранения текста;
- "курсор в начало экрана" позиционирует курсор в начало
текущей строки;
- "КОН" позиционирует курсор в конец текущей строки;
- "ТАБ" перемещает курсор к следующей позиции табуляции;
- "РЕГИСТР/ТАБ" перемещает курсор к предыдущей позиции
табуляции.
Постраничная работа
-----------------------------------------------------------------
- "Страница вверх" и "Страница вниз" перемещает текст на
страницу вперед или назад;
- "Ctrl/(курсор в начало экрана)" устанавливает текст на
первую страницу, позиционируя курсор в первой позиции
первой строки текста;
- "Ctrl/КОН" устанавливает текст на последнюю страницу в
буфере и позиционирует курсор в первой позиции строки,
которая следует за последней строкой текста в буфере.
Команды работы с блоками текста
-----------------------------------------------------------------
Текстовый редактор имеет в своем составе команды работы с
блоками текста. Эти команды позволяют оперировать с блоками
текстов, которые определены ограничительными линиями.
- "F4" формирует параграф из текста, помеченного как блок;
- "F5" помечает первую строку блока. Строка текста, в
которой находится курсор, становится первой строкой
блока. Текст, образующий блок, отображает
...Поділитися у соцмережах