Диалог в окнах для Турбо бейсика

    Описывается функция FND, организующая диалог в окнах. Функция предназначена для удобного ввода и вывода данных в программах на Турбо бейсике и для управления программой.
  Функция имеет множество опций, облегчающих работу. Два типа окон - с произвольным расположением полей, и с массивом строк с горизонтально расположенными в них полями. Поля - кнопки, поля для ввода данных, поля для чтения результатов, прокрутка строк в окне, запись полей в файл и чтение из файла, подключение по мере надобности новых окон, переход с русского на латинский и обратно - всё это сосредоточено в одной функции. Всё, что нужно сделать - подключить модуль с этой функцией к своей программе строкой $INCLUDE "FNDR.BAS"  и у Вас не будет проблем с организацией удобного и наглядного диалога.
   Функция работает с текстовым экраном, но имеется и аналогичная функция для организации диалога на графическом экране.

ОБЪЕКТЫ ДИАЛОГА

   Совокупность правил работы в окне и значения полей образуют структурную единицу, которую мы будем называть объектом диалога, или D-объектом. Потенциально возможно участие в программе неограниченного количества объектов диалога, но сиюминутно активными в ней могут быть одновременно два - D1, объект первого типа ( с произвольным расположением полей), и D2, объект индексированных строк.
   Этим двум инициализированным объектам соответствуют глобальные массивы переменных:
массивы данных - D1$(50) и D2$(50,16), в последнем 50-число строк, 16 - число полей в строке
и массивы правил работы на полях - DR1$(50) и DR2$(16)


ФУНКЦИЯ  "FND" И ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ

   Используются следующие функции и глобальные переменные:
   FND(A$) - функция диалога
     DKEY$ - список "горячих" клавиш для выхода из этой функции
     DMARK - числовое значение, возвращаемое функцией при нажатии Enter
     D2K - индекс строки D2 объекта
     D2MAX - индекс последней занятой строки D2 объекта
аргумент A$ функции диалога FND указывает на действия, производимые функцией:
   "R1", "R2" - инициализация D-объекта. Данные читаются из массива DATA в теле программы и заносятся в массивы DR1$, D1$ или в D2$, DR2$. Если прочитанная строка начинается с символа W, это значит, что она содержит описание окна, и она запоминается в локальных W1$ или W2$. Признаком конца чтения является ",," в списке DATA.
   "W1", "W2" - построение и очистка окна
   "V1", "V2" - вывод информации в окно, печатаются поля и префиксы
   "D1", "D2" - вход в диалоговый режим и работа в окне типа D1 или D2
"F1 FLNAME", "F2 FLNAME" - запись объекта в указанный файл
"I1 FLNAME", "I2 FLNAME" - инициализация объекта из файла
"S1 FLNAME", "S2 FLNAME" - запись полей объекта в файл
"L1 FLNAME", "L2 FLNAME" - чтение полей объекта из файла
в последних обращениях можно обойтись и без указания файла, но он тогда должен быть предварительно открыт для чтения как #5, а для записи или добавления - как #6, а после окончания чтения или записи закрыт. Такой подход позволяет хранить много объектов в одном файле.
   "Y2" и "Z2" – удаление строки и вставка пустой строки в строки объекта D2
   Можно было бы связать удаление и вставку строк с нажатием клавиш Del и Insert внутри FND функции, но у программиста могут быть и другие планы на эти клавиши, а если он захочет использовать их именно так, то нетрудно указать соответствующие символы ( S и R ) в строке "горячих" клавиш и организовать эти действия.

  Цепочечное исполнение обращений позволяет совместить несколько обращений в одном. Параметры обращений указываются через запятую. Это можно видеть в строке программы-примера, приведённой ниже:
    A=FND("R1,W1,V1")


ДРУГИЕ ПОЛЕЗНЫЕ ФУНКЦИИ

 Кроме того в модуле имеются ещё две функции, которые могут использоваться и самостоятельно:

    FNDIN(F$,DM) - работа в активном поле.
      F$ - начальное значение поля. Оно заносится в глобальную переменную DS$ и выводится на экран начиная от начального положения курсора, и затем может быть изменено. DM>0 запрещает изменение поля (это значит, что поле играет роль кнопки с надписью  F$ на ней )
      DS$ - конечное значение поля. Кроме того функция возвращает порядковый номер "горячей" клавиши из списка DKEY$, если такая клавиша была нажата.
Функция прерывает свою работу, восстанавливает начальное значение поля и возвращает нулевое значение при нажатии на клавишу Esc.
Функция прерывает работу и возвращает отрицательные значения при нажатии следующих клавиш:
  Tab -  возвращается -1, а функция FND в ответ на это отрабатывает переход по умолчанию - на следующее по порядку поле.
   Ctrl/стрелка вправо, влево, вверх, вниз - возвращается -2, -3, -4, -5
   стрелка вверх, вниз - возвращается -4, -5
   Стрелка влево из первой позиции поля - возвращается -3
   Стрелка вправо из последней позиции поля - возвращается -2
   Стрелка вправо и DM>0 (кнопка) - возвращается -2
   Enter - возвращается -6
При работе в активном поле передвигается курсор стрелками вправо, влево и работает Backspace. Переключение с латинского на русский и обратно происходит при нажатии клавиш  Sift/Enter. Переключение сопровождается звуковой сигнализацией. Соответственно режиму устанавливается глобальная переменная  LATRUS  1- если русский и 0 - если латинский.


   FNDLR(K%) - функция для работы с русским алфавитом
      при обращении с K%=-1 загружает строку перекодировки из файла T_C1.FNT
      при обращении с K%=0 переключает LAT-RUS режимы
      при положительном  K% (код нажатой клавиши) возвращает ASC код (в кодировке MS-DOS) символа на позиции  K% в строке перекодировки.

Используется также подпрограмма сдвига строк:
   DW(Y1,X1,Y2,X2,C,P) '--- Сдвиг строк в окне на P ( >0 вверх,<0 вниз )
      Y1,X1,Y2,X2 - координаты левого верхнего и нижнего правого углов
      C - цвет фона. При P=0 поле очищается.
Для исполнения подключается внешний код из файла DW.COM ,где используется функция 6 прерывания int10H (см. Р.Джордейн Справочник программиста п.4.5.1)

  Из сказанного следует, что помимо самого модуля FNDr.BAS при работе в Бейсике или компиляции в текущем каталоге должны присутствовать файлы T_C1.FNT и DW.COM


ПРИМЕР ОРГАНИЗАЦИИ ДИАЛОГА

  Рассмотрим возможности диалога на следующем примере:

$INCLUDE "FNDR.BAS"
COLOR 7,1 : CLS : GOTO 10
M1:
DATA "W05031405$ F2=>D2 "
DATA "4,2P2#A=&.........."
DATA "4,3P3U1#B=&.........."
DATA "4,4R4U2#C=&..","10,4L3U2FM1#K1=&Beep"
DATA ",,"
M2:
 DATA "W03117510C007003047$ Таблица D2 - F1=>D1 - F3 выход "
 DATA  DATA
10 RESTORE M1 : A=FND("R1,W1,V1")
RESTORE M2 : A=FND("R2,W2,V2")
11   DKEY$=";<=" : A=FND("D1")
   IF A=2 THEN 21
   IF A=3 THEN STOP
   SELECT CASE DMARK
       CASE 1 : BEEP
   END SELECT : GOTO 11

21  DKEY$=";<=" : A=FND("D2")
   IF A=1 THEN 11
   IF A=3 THEN STOP
   SELECT CASE DMARK
       CASE 1 : D2$(D2K,2)="Линза R1 R2 T N " : A=FND("V2")
   END SELECT : GOTO 21

   Первая часть программы содержит описание D1 и D2 объектов, вторая часть работает с первым объектом, третья - со вторым. Результаты работы показаны на синем скриншоте над заголовком статьи.

 Взгляните на 5-ю строку программы - DATA "4,2P2#A=&.........."
4 и 2 - координаты поля, отсчитываемые от левого верхнего угла меню.
P2 - указание на то, что при нажатии стрелочки вниз нужно идти на второе поле
  L R U - если они есть, указывают на передвижения по стрелочкам влево, вправо и вверх.
После решётки #, если она есть, указан префикс поля - надпись, которая печатается слева от поля.
После & идёт само поле. Как видно, оно вначале заполнено точками. Потом в процессе работы на него можно прийти и изменять его значение как угодно.

  А вот значение 4-го поля изменить нельзя, оно фиксировано. На это указывает буква F в строке:
  "10,4L3U2FM1#K1=&Beep" зато можно нажать Enter,  DMARK примет значение 1, на что указывает M1, результат будет обработан строками программы
   SELECT CASE DMARK
       CASE 1 : BEEP
   END SELECT : GOTO 11
и раздастся "beep"

А если мы нажмём F3, то окончим работу и выйдем из программы. Дело в том, что символ "=" задан третьим в строке DKEY$=";<=" именно он появляется от функции FND при чтении клавиатуры функцией INKEY$ (эта функция используется для чтения кодов нажатых клавиш), и именно на эти действия направляют строки программы:
      A=FND("D1")
    IF A=3 THEN STOP

Для получения кодов и символов при работе функции INKEY$ можно использовать эту короткую программу:
10 A$=INKEY$
   IF A$="" THEN 10 ' вертимся в цикле, пока не нажмём на клавишу
   PRINT ASC(A$), LEN(A$) 'получили один или два символа, печатаем код первого
   IF LEN(A$)=2 THEN R$=(RIGHT$(A$,1)) : PRINT ASC(R$);" "; R$ 'второй код и символ
   IF A$=" " THEN STOP ' выход, если был нажат пробел
   GOTO 10

  Но давайте посмотрим на внешний вид окон на рисунке. Откуда он такой появился?
Смотрим на строку DATA "W05031405$ F2=>D2 "
  Рамочка нашего маленького окна имеет координатами левого верхнего угла 05 и 03 в отношении угла большого текстового экрана.
Окно внутри рамочки имеет размер 14 столбцов на 05 строк и цвет по умолчанию синий. Также по умолчанию цвета неактивного поля белый на синем, а цвета активного поля - белый на чёрном. После знака $, если он есть указана надпись для верхней части бордюра.
  А сама эта надпись говорит о том, что нажав на F2 мы перейдём на нижнее окно объекта D2.
  Нажимаем F2 , получаем от INKEY$ символ "<", он второй в строке DKEY$=";<="
FND возвращает значение 2, по строке IF A=2 THEN 21 идём на  D2 диалог.

  Окно для D2 диалога уже приготовлено. Почему оно такое разноцветное?
Смотрим на строку 
DATA "W03117510C007003047$ Таблица D2 - F1=>D1 - F3 выход "
после буквы C задаются цвета - 00 чёрный на 7 белом для пассивных полей, 00 чёрный на 3 голубом для активного поля, 04 красный на 7 белом - цвета бордюра.
  Окно можно задать ещё и таким хитрым способом -  DATA "WW", в этом случае для описания окна берётся содержимое глобальной переменной WW$.
Строка с заданием параметров окна может совсем отсутствовать, тогда (по умолчанию) берётся окно размером во весь экран 78 на 22.

  Перейдя в окно D2 ходим стрелочками по всем полям, пишем на них всё, что хотим. Если захотим зайти ниже границы окна, то строки начинают прокручиваться.
Посмотрите, как задаются поля -  DATA Звёздочка * означает, что на этом месте будет выведен порядковый номер строки.
F в описании второго поля означает, что оно фиксировано, а M1 означает, что на нем активно нажатие Enter.
  Посмотрим в текст программы, к чему приведёт нажатие Enter?
   SELECT CASE DMARK
       CASE 1 : D2$(D2K,2)="Линза R1 R2 T N " : A=FND("V2")
   END SELECT
мы меняем содержимое поля 2 на строке номер D2K, а следующим оператором A=FND("V2") визуализируем это изменение в окне, чтобы его сразу же было видно.
А на что же намекает нам такая надпись на поле 2 - "Линза R1 R2 T N" ?
Намекает она нам на содержание последующих полей - там нужно будет последовательно указать радиусы кривизны поверхностей линзы, её толщину и показатель преломления.
  Таким образом мы можем задать в окне D2 некий оптический элемент и рассчитывать ход лучей, пропуская их через него.
  А составляя другую программу можно разместить таким же образом загадки и ответы, слова и их переводы. Можно не визуализировать ответы, и тогда мы увидим содержание поля только тогда, когда мы на него придём. Можно и прятать поля друг под другом.

О ГРАФИЧЕСКОМ РЕЖИМЕ

  К сожалению, чёрное на белом в графическом режиме не получается. Зато получается синее на белом и ярко белое на белом. Цвет фона активного поля распространяется на весь экран. Чтобы не было мельканий рекомендуется указывать цвет фона одинаковым, вот так например (указан фон 7 - белый):
  DATA "W03117510C017157097$ Таблица D2 - F1=>D1 - F6 run - F3 выход "
Если задавать в окнах цвета по-разному, то могут возникнуть и коллизии - на рисунке с демонстрацией графического режима видно, что верхнее окно представляется пустым. Это естественно - там был задан цвет белый на чёрном, но переход в нижнее окно сделал фон в этом окне белым, и символы на нём не видны.
  Цвет для окна неплохо задать и так - C087017097. А чтобы посмотреть, как на общем фоне будет выглядеть графика, в тестовую программу можно внести изменения -
  CASE 1 : FOR C=0 TO 15 : LINE(200+5*C,20)-(220+5*C,100),C : NEXT C
Для подключения графического варианта функции FND на месте первых строк нужно поставить
  $INCLUDE "FNDr_G.BAS"
  SCREEN 9

   Диалог с использованием функции FND оказывается очень удобным и универсальным.
   Тексты модулей "FNDr.bas" и "FNDr_G.bas", файлы T_C1.FNT и DW.COM, а также и текст этой статьи можно скачать тут - https://yadi.sk/d/g15-zV8Fh7Huo
О применении FND модуля можно почитать также здесь – http://www.proza.ru/2015/05/15/1342

   Программа расчёта оптических систем методом Монте-Карло OPTR1_F, работающая в графическом режиме, сделанная на основе описанного модуля, вместе с Бейсиком и со всеми вспомогательными и bas файлами, находится здесь - https://yadi.sk/d/MxlAz2rHipDnm

============== 5.6.2015
К сожалению, современные операционные системы всё меньше поддерживают разработки, сделанные в ДОС. Из программ Турбо бейсика исчезает звук. Чтобы его услышать, приходится запускать программы, используя DOSBox - ящик эмулятор среды Дос.
Но даже при работе с эмулятором из программ исчезает кириллица. Появляются неожиданные сбои в работе графического FND модуля. Поэтому при работе со стареньким бейсиком проверьте эти вещи.
  Свои программы, реализующие музыкальный проект я перевёл из Турбо бейсика на VB6 почти без переделок кода там, где это касалось вычислительной части.
  Интерфейс пришлось делать заново. В целом, доволен этим переводом. С возможностями новых программ вы можете ознакомиться в статьях раздела посвящённого программированию на VB6.
=== ноябрь 2017


Рецензии
Э... простите зачем это в 2015 году, когда достаточно написать
InputBox s;
a=s.value;

Вы археолог информатики?

Такеру Ямато   07.06.2015 09:04     Заявить о нарушении
А мне тогда, в девяностых, больше полюбился Диамс....

Ирина Комова   07.06.2015 09:17   Заявить о нарушении
Ой, приношу извинения, для расчетов в одной, прикладной области Бэйсик конечно удобен.

Хотя комбинация excel+VB все равно продуктивнее.

Такеру Ямато   07.06.2015 09:19   Заявить о нарушении
VB хорош, там где простой текст и иллюстрации. В нём я электронные книги стихов делаю http://www.stihi.ru/2011/04/14/9339
а археолог я потому, что начинал работать ещё на Диалоговом вычислительном комплексе, был такой, в виде шкафа, и Бейсик на нём был. Можно было бы переучиться и на другой язык, но смысла особого для создания прикладных программ я не вижу - трудов много, а результат не лучше чем с моими окнами - я ведь всё продумал именно так, как мне было надо.
Дм.

Дмитрий Маштаков   07.06.2015 10:10   Заявить о нарушении