13. Организация меню
Ранее рассматривалось формирование меню. Однако, этого мало. Необходимо обеспечить реакцию системы на выбор пунктов меню или нажатие каких-либо клавиш. В ряде случаев это может означать выбор какого-либо объекта: человека, группу и др. Тогда необходимо связывать пункты меню с объектами БЗ. Для этого используются специальные фрагменты, называемые метками. Например, MT_ST(1,СТ_5) – метка, связывающая п.1 меню и объект СТ_5.
Рассмотрим различные варианты организации меню.
В общем случае:
... THEN B:DELFR(@@) {= Удаляются все фрагменты с именем @@ =}
B:REW(MEMORY) <формирование картинки=""> B:REW() B:MENU(X1,X2,1)формирование>
Т1:AN_POINT(); {= анализ выбранного пункта меню =}
Напомним, что первая строчка формируемой картинки будет заглавием меню, а последующие строчки – ее пунктами. Строчки-пункты не могут начинаться с пробелов.
Реакция оператора B:MENU(...) на нажатие клавиш:
1) Выбран N-й пункт меню и нажата ENTER. В БЗ будет введен фрагмент @@(N) и установлен параметр PAR(7,N). Параметр PAR(7,...) указывает на выбранный пункт.
2) Нажата служебная клавиша ESC (или F1, ..., F10) при выделенном пункте N. В БЗ будет введен фрагмент @@(ESC) и установлены параметры PAR(7,N) и PAR(6,27).
Например, если выбран п.2 меню, то в БЗ будет @@(2) и PAR(7,2). А если выбран п.3 и нажата клавиша F1, то в БЗ будет @@(F1) и PAR(7,3).
Продукция AN_POINT() анализирует выбранный пункт. В простейшем случае она имеет вид:
AN_POINT():IF D:@@(ESC) THEN <выход из="" меню="">;выход>
AN_POINT():IF D:@@(F1) THEN <выдача help="">;выдача>
AN_POINT():IF D:@@(1) THEN <вызов продукций,="" связанных="" с="" п.1="">;вызов>
...
Рассмотрим более сложный случай, когда меню составляется из объектов базы знаний и при нажатии нужно выдать все, что известно об этом объекте.
Пример 13.1. Выдать всех студентов группы ПМ96 в виде меню, а при выборе пункта - все, что известно о соответствующем студенте с возвратом в меню по ESC (при нажатии этой клавиши). Выход из меню также - по ESC.
Пусть БЗ имеет вид (как в примере 7.1):
ГР(ПМ96,ПМ)
СТУД(СТ_20,ПМ96) ФАМ(Михайлов,СТ_20) ИМЯ(Владимир,СТ_20)
СТУД(СТ_21,ПМ95) ФАМ(Пирагова,СТ_21) ИМЯ(Елена,СТ_21)
...
ГР(ПМ95,ПМ)
...
В данном случае при построении картинки меню (из ФИО студентов) требуется:
1) Формирование специальных фрагментов - "меток", связывающих код студента с номером пункта, в котором выдано ФИО этого студента. Будем использовать для этого: MT_ST(1,СТ_20) - метки, связывающие номер строки и студента. Такие фрагменты будут строиться в процессе формирования картинки меню.
2) Для построения фрагментов требуется счетчик пунктов меню. Будем использовать счетчик на параметрах - PAR(50,..), см. п.10.4.
3) Для запоминания выбранного (N-го) пункта меню (чтобы при возврате в меню выделить именно этот пункт) будем использовать параметр PAR(61,N). Выход из меню - при PAR(61,0).
Программа будет иметь вид:
BEG(/91+) {= начало программы =}
START:IF THEN
B:PAR(61,1) {= устанавливается, что выделенным будет п.1 меню =}
T:MENU_ST(ПМ96)
B:HALT();
MENU_ST(X10):IF B:GETPAR(61,X7)
B:#(X7,0) {= Вызов меню T: до тех пор пока не станет PAR(61,0) =}
THEN
T1:PR_LINE(1,1,"Список студентов") {= информация в верхней строке =}
T1:PR_LINE(1,25,"Выход - по ESC") {= информация в нижней строке =}
B:NEW(X8) {= место в БЗ, откуда будет стирание =}
B:DELFR(MT_ST) {= метки будут строиться заново =}
B:PAR(50,0) {= счётчик пунктов =}
B:REW(MEMORY) {= открывается внутренняя память =}
B:A("Студенты группы",X10,":") {= Заглавие =}
T!:LIST_ST(X10) {= Пункты меню - ФИО студентов =}
B:REW() {= конец построения меню =}
B:MENU(4,4,X>7) {= X7 – пункт меню, который выделяется =}
T1:AN_ST(X10) {= анализ выбранного пункта с выдачей ФИО студента =}
B:C(X8); {= стирание - удаление фрагментов БЗ от X8 =}
{= Построение пунктов меню и меток MT_ST =}
LIST_ST(X10):IF СТУД(X1,X10) N:MT_ST(_,X1)
B:GETPAR(50,X55) B:+(X55,1,X56) THEN B:PAR(50,X56)
MT_ST(X56,X1) {= связывает пункт X56 с студентом X1 =}
T1:POINT_ST(X1,X56); {= выдача ФИО студента X1 =}
POINT_ST(X1,X56):IF ФАМ(X2,X1) ИМЯ(X4,X1) THEN
B:BK() B:A(X56," ",X2," ",X4);
{== Реакция на нажатую клавишу: нажата ESC ==}
AN_ST(X10):IF D:@@(ESC) THEN
B:PAR(61,0); {= обеспечивает выход из меню =}
{== Выбран пункт X51 меню - выдача информации о студенте ==}
AN_ST(X10):IF D:@@(X51) MT_ST(X51,X1) {= выбран п. X51, т.е. студент X1 =}
THEN B:PAR(61,X51) {= обеспечивает возврат в меню с выделением п. X51 =}
T1:INFORM_ST(X1); {= выдача информации о студенте X1 =}
{== Фамилия и имя студента группы X10 выдаются в редактор: ==}
INFORM_ST(X1):IF ФАМ(X2,X1) ИМЯ(X4,X1) СТУД(X1,X10) THEN
B:DELFILE('RES.TXT') {= удаление файла =}
B:REW('RES.TXT') {= создание и запись в файл RES.TXT =}
B:BK() B:A("Студент группы ",X10,":")
B:BK() B:A("Фамилия - ",X2)
B:BK() B:A("Имя - ",X4)
B:REW()
B:GETWINDOW(3,5,50,10,"Студент: ")
B:PAR(22,0) B:PAR(18,0) B:PAR(39,0) {= установка параметров =}
B:EDFILE1('RES.TXT') {= выдача файла RES.TXT в редактор =}
B:DELFR(@@);
{= фрагменты @@ порождаются B:EDFILE1, они могут мешаться =}
{== Информирует на экране в строке с номером X2 - выдает сообщение X40 ==}
PR_LINE(X1,X2,X40):IF THEN B:REW(MEMORY) B:A(X40) B:REW() B:LINES(X1,X2);
END(/92+) @BL(91-,92-) {= Конец программы =}
Продукция строит метки MT_ST(1,СТ_20), MT_ST(2,СТ_21), ... и выдает ФИО студентов. В результате будет построено меню:
--- Студенты группы ПМ96: ----
| 1 Михайлов Владимир |
| 2 Пирогова Елена |
| ... |
При выборе п.2 применится вторая продукция AN_ST(X10), которая за счет MT_ST(2,СТ_21) означит X1=СТ_21 и сделает B:PAR(61,2). Продукция T1:INFORM_ST(СТ_21) выдаст в редактор информацию о студенте СТ_21. При нажатии любой клавиши снова будет вызвана T:MENU_ST(ПМ96), так как значение параметра 61 не 0.
Если (когда выдано меню) нажата клавиша ESC, то применится первая продукция AN_ST(X10), которая сделает PAR(61,2). Тогда T:MENU_ST(ПМ96) станет не применимой и будет выполняться следующий оператор продукции START. А это B:HALT() - выход из программы.
Если необходимо сделать так, чтоб при выделении пункта и нажатии F1 выдавалась информация о студенте, тогда:
AN_ST(X10):IF D:@@(F1) B:GETPAR(7,X51) MT_ST(X51,X1) THEN
B:PAR(61,X51) T1:INFORM_ST(X1);
В более сложных случаях с помощью INFORM_ST(X1) можно обеспечить выдачу более полной информации о студентах, а после T:MENU_ST(ПМ96) могут быть какие-либо другие продукции, например, обеспечивающие ответ на запросы.
Отметим, что если в продукциях переименовать продукции с ..._ST на ..._GR, заменить СТУД на ГР, заменить параметр 61 на 60 и переделать:
POINT_GR(X1,X56):IF THEN B:BK() B:A(X56," - группа ",X1); {= Вместо POINT_ST =}
INFORM_GR(X1):IF ГР(X1,X20) THEN
<выдача в="" редактор="" сведений="" о="" группе="" x1="" факультета="" x20="">;выдача>
то программа T:MENU_GR(ПМ) выдаст меню групп и обеспечит информирование о каждой из них с указанием факультета X20=ПМ.
Структура программы будет, как и при выдаче студентов.
А если вместо T1:INFORM_GR(X1) вызвать B:PAR(61,1) T:MENU_ST(X1), то при выборе пункта (группы) будет выдаваться меню студентов выбранной группы. Таким образом строится система меню, см. п.17.
Домашнее задание 4.
Программа выдачи объектов из выбранной области приложения по уровням в виде меню (дополнение к п.9).
Предыдущий раздел|Следующий раздел