Опубликован: 21.02.2012 | Уровень: специалист | Доступ: платный
Лекция 6:

Программирование диалоговых окон на языке DCL

Аннотация: В диалоговых окнах удобно вводить данные и настройки созданных LISP-приложений. Для создания диалоговых окон разработан специальный язык DCL (Dialog Control Language) . Диалоговые окна описываются в текстовых DCL-файлах с расширением .dcl. Примерами DCL-файлов являются файлы с описанием стандартных диалогов acad.dcl и base.dcl, размещенные в папке C:Documents and Settings UserApplication DataAutodeskAutoCAD 2010R18.0enuSupport. Работа с диалогами производится в интегрированной среде разработки Visual LISP.

Цель лекции: приобрести навыки работы в построении диалоговых окон.

Технология программирования диалогов

Постановка задачи

Рассмотрим пример программы вычерчивания полого рога с углом изгиба 180 градусов.

(defun c:qrog (/ cenrt1 rad1 diam1 circle1 arc1 rog1 thick1 angle1 endp1 col1)
  (setq centr1 '(0 0 0)) ;							исходная базовая точка
  (setq rad1 (getreal "Задайте радиус базовой окружности: "));	радиус рога (80)
  (setq diam1 (getreal "Задайте диаметр направляющей дуги: "));	диаметр изгиба рога (400)
  (setq thick1 (getreal "Задайте толщину стенки рога: "));		толщина стенки в мм (2)
  (setq col1 (getint "Задайте индекс цвета: "));				выбор: 0,1,2,3,4,5,6
  (setq angle1 (* 55.0 (atan rad1 (* diam1 (/ pi 2)))));			угол изгиба рога
  (command "_view" "_top") ;начинаем со стандартного вида;		устанавливаем вид сверху
  (command "_view" "_swiso");					переходим к северо-западному виду
  (command "_circle" centr1 rad1 "");					строим базовую окружность
  (setq circle1 (entlast));				извлекаем имя сущности для базовой окружности
  (command "_ucs" "_x" "90" "");					поворачиваем ПСК
  (setq endp1 (list diam1 0.0));						задаем конечную точку дуги
  (command "_arc" centr1 "e" endp1 "a" "-180" "");			строим дугу изгиба
  (setq arc1 (entlast));				извлекаем имя сущности для дуги и сохраняем его
  (command "_ucs" "_x" "-90");			совмещаем плоскость окружности с плоскостью XY
  (command "extrude" circle1 "" "t" angle1 "p" arc1 "");			строим тело рога
  (setq rog1 (entlast));				извлекаем имя сущности для рога и сохраняем его
  (command "_zoom" "e" "");			растягиваем изображение на весь экран
  (command "_vscurrent" "_r" "");		устанавливаем текущий визуальный стиль - realistic
  (command "_chprop" "_all" "" "_color" col1 "");			закрашиваем заданным цветом
  (command "_view" "_bottom" "");					устанавливаем вид снизу
  (command "_solidedit" "_body" "_shell" rog1 centr1 "" thick1 "" "");	удаляем внутренность рога
  (command "_erase" arc1 "");						удаляем образующую дугу
(princ);									тихий выход из программы
)

Внешний вид рога показан на рис. 6.1.

 Рисунок рога

Рис. 6.1. Рисунок рога

Рог строился путем экструзии базовой окружности вдоль дуги с раствором 180 градусов. Угол сужения брался равным углу сужения подобного прямого конуса. Полость в роге выполнялась с помощью команды Shell.

При запуске функции qrog пользователь задавал требуемые параметры по запросам программы:

  • радиус базовой окружности rad1;
  • диаметр направляющей дуги diam1;
  • толщину стенки рога thick1;
  • индекс цвета col1.

Требуется вместо запросов создать диалоговое окно для одновременного ввода этих параметров.

Создание DCL-файла

Вначале напишем отдельную программу для открытия диалогового окна. В новом чертеже AutoCAD откройте среду Visual LISP по команде Tools - AutoLISP - Visual LISP Editor. По команде File - New File создайте новый файл. Наберите в нем следующий текст программы диалога "rog" на языке DCL. Учтите только, что элементы языка DCL чувствительны к регистру. Все ключевые слова, метки и коды элементов должны состоять только из латинских букв, цифр и символа подчеркивания. Начинаться служебные слова должны с латинской буквы.

//Диалоговое окно установки параметров рога
//
rog: dialog{label="Установка параметров рога";
  :edit_box{label="Радиус окружности ";key="rad" ;value="0.00"; edit_width=8;}
  :edit_box{label="Диаметр дуги, мм";key="diam";value="0.00";edit_width=8;}
  :edit_box{label="Толщина стенки, мм";key="thick";value="0.00";edit_width=6;}
  :spacer{height=1;}
  :edit_box{label="Индекс цвета";key="col";value="0";edit_width=4;}
  :spacer{height=1;}
  ok_cancel;
}

Сохраните написанное в файле C:\Program Files\AutoCAD2007\Support\Rog.dcl. Папка Support принадлежит к маршрутам файлов поддержки. Проверьте это еще раз, выполнив команду Tools - Options - Files - Support File Search Path. Чтобы открыть диалоговое окно на экране, система должна загрузить DCL-файл. Эта загрузка может быть выполнена лишь тогда, когда DCL-файл помещен в данную папку. Иначе нужно указывать полный путь к файлу.

Составление директив

Вся написанная программа называется диалогом. В одном файле может быть несколько диалогов. Рассмотрим структуру программы-диалога.

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

Директивы могут записываться в двух видах:

[<метка>]:<оператор>{<атрибуты>}
<метка>;

Здесь квадратные скобки обозначают необязательность размещенного внутри них элемента. Фигурные скобки и двоеточия являются обычными символами. Метка - идентификатор директивы. Она должна быть уникальной в данном файле.

В листинге программы мы сразу можем выделить директиву описания диалога в целом:

rog: dialog {label="Установка параметров рога";
…
  ok_cancel;
}

rog - это метка, имя диалога;

dialog - это оператор, он вызывает свою подпрограмму, выполняющую действия;

label="…"; - эта надпись будет заголовком диалогового окна;

ok_cancel - внизу окна будут размещены кнопки ОК и CANCEL (Отмена).

Внутри директивы dialog размещены четыре однотипные директивы, имеющие следующий вид:

  :edit_box{label="Радиус окружности "; key="rad"; value="0.00"; edit_width=8;}

Элементы этих директив описывают следующие понятия:

  • edit_box - оператор редактируемого текстового поля;
  • label="…"; - эта надпись будет размещена перед текстовым полем;
  • key="rad"; - код диалога;
  • value="0.00"; - значение, которое содержит текстовое поле по умолчанию;
  • edit_width=8; - ширина окна текстового поля в символах шрифта.

В листинге программы имеются еще две одинаковые директивы

:spacer{height=1;}

spacer - это пустой элемент, обозначающий пропуск строки;

height=1; - атрибут height показывает высоту пропущенной строки. Единицей измерения является стандартная высота строки текущего шрифта.

Итак, в сохраненном файле "Rog.dcl" описано диалоговое окно с именем диалога "rog". Окно должно иметь четыре текстовых поля с видимыми в них значениями по умолчанию.

Файл загрузки диалога

Составим теперь LISP-функцию, которая позволяла бы загружать (load_dialog) и выгружать (unload_dialog) DCL-файлы, открывать и закрывать окна загруженных диалогов. В редакторе Visual LISP создайте новый файл и наберите в нем следующий текст:

(defun c:show_rog ( / num)
  (if (< (setq num (load_dialog "rog.dcl")) 0)(exit))
  (if (not (new_dialog "rog" num)) (exit))
  (start_dialog)
  (unload_dialog num)
  (princ)
);defun

В первой строке определена функция show_rog c локальной переменной num. В переменной num сохраняется внутренний номер открываемого диалогового окна. Обычно он присваивается всем вновь открываемым диалогам по порядку, начиная с единицы.

Во второй строке записана команда (load_dialog "rog.dcl"), загружающая файл rog.dcl. Если полный адрес файла не указан, то система ищет этот файл по стандартному алгоритму поиска файлов поддержки. Если загрузка прошла успешно, то функция load_dialog возвращает положительное целое число, которое присваивается переменной num. Если загрузка не выполнилась, то возвращается отрицательное число. В этом случае выполняется функция exit, прерывающая работу приложения.

В третьей строке проверяется, имеется ли в загруженном DCL-файле rog.dcl диалог с именем "rog", имеющий номер num. Если такого диалога в файле нет, то программа завершается с помощью функции exit. Если такой диалог есть, то активируется диалоговое окно, управление передается функции start_dialog. Эта функция возвращает 1, если пользователь выйдет из диалогового окна с помощью кнопки OK или 0, если пользователь выйдет из диалогового окна с помощью кнопки Cancel.

В пятой строке функция unload_dialog num выгружает файл из оперативной памяти. Возвращаемое значение - nil.

Загрузите файл, перейдите в AutoCAD и наберите в командной строке show_rog. На экране появится диалоговое окно (рис. 6.2).

 Диалоговое окно

Рис. 6.2. Диалоговое окно

Установите параметры в текстовых полях. Щелкните по кнопке ОК. Окно исчезнет с экрана. Файл rog.dcl выгрузится из оперативной памяти. Чтобы воспользоваться результатами работы с окном, нужна программа, анализирующая введенные величины.

Обработка вводимых данных

Исключим из программы черчения рога приглашения задать параметры рога и включим обращение к диалогу "rog". На время наладки программы введем печать четырех параметров в отдельных строках.

(defun c:qrog (/ cenrt1 rad1 diam1 circle1 arc1 rog1 thick1 angle1 endp1 col1)
  (setq centr1 '(0 0 0)) ;					исходная базовая точка
  (if (< (setq num (load_dialog "rog.dcl")) 0)   (exit));	загружаем в память файл "rog.dcl"
  (if (not (new_dialog "rog" num))  (exit))
;;функция new_dialog проверяет наличие в файле диалога "rog"
  (action_tile "rad" "(setq rad1 (atof $value))");		присваиваем значение переменной rad1
  	(terpri);						перевод строки
  	(princ rad1);					выводим на экран значение переменной rad1
  (action_tile   "diam"  "(setq diam1 (atof $value))");	присваиваем значение переменной diam1
  	(terpri);						перевод строки
  	(princ diam1);					выводим на экран значение переменной diam1
  (action_tile "thick" "(setq thick1 (atof $value))");	присваиваем значение переменной thick1
  	(terpri);						перевод строки
  	(princ thick1);					выводим на экран значение переменной thick1
  (action_tile "col" "(setq col1 $value)");		присваиваем значение переменной col1
  	(terpri) ;					перевод строки
 	 (princ col1);					выводим на экран значение переменной col1
  	(terpri);						перевод строки
  (start_dialog);						возвращает 1 или 0
  (unload_dialog num);					выгружает окно из памяти
  (setq angle1 (* 55.0 (atan rad1 (* diam1 (/ pi 2)))));	находим угол сужения тела рога
  (command "_view" "_top") ;				начинаем со стандартного вида сверху
  (command "_view" "_swiso");				переходим к северо-западному виду
  (command "_circle" centr1 rad1 "")	;		строим базовую окружность
  (setq circle1 (entlast));				извлекаем имя сущности для базовой окружности
  (command "_ucs" "_x" "90" "");			поворачиваем ПСК
  (setq endp1 (list diam1 0.0));				находим координаты конечной точки дуги
  (command "_arc" centr1 "e" endp1 "a" "-180" "");	строим образующую дугу
  (setq arc1 (entlast));				извлекаем имя сущности для дуги и сохраняем его
  (command "_ucs" "_x" "-90");			совмещаем плоскость окружности с плоскостью XY
  (command "extrude" circle1 "" "t" angle1 "p" arc1 "");			создаем тело рога
  (setq rog1 (entlast));				извлекаем имя сущности для рога и сохраняем его
  (command "_zoom" "e" "");				растягиваем изображение на весь экран
  (command "_vscurrent" "_r" "")		устанавливаем текущий визуальный стиль realistic
  (command "_chprop" "_all" "" "_color" col1 "");			закрашиваем цветом col1
  (command "_view" "_bottom" "");					устанавливаем вид снизу
  (command "_solidedit" "_body" "_shell" rog1 centr1 "" thick1 "" "");	делаем в теле рога полость
  (command "_erase" arc1 "");						удаляем образующую дугу
  (princ);								тихий выход
)

Для обработки данных, вводимых в текстовых полях диалогового окна, применена функция action_tile. Она помещена между функциями new_dialog и start_dialog. Функция имеет следующий синтаксис:

(action_tile <код> <выражение>)

<код> - это строка с кодом элемента;

<выражение> - строка с LISP-выражением действия, выполняемого при выборе данного элемента;

Возвращаемое значение Т.

Функция action_tile присваивает значения текстовых полей переменным функции qrog. Текстовые поля различаются по кодам этих полей. Значения полей сохраняются в глобальной переменной $value. Тип сохраненных величин - строковые константы. Чтобы обеспечить возможность дальнейших расчетов, применено преобразование строковых констант в вещественные числа с помощью функции atof.

Алексей Тимонин
Алексей Тимонин
Алексей Потапкин
Алексей Потапкин

Здравствуйте.

Подскажите, пожалуйста, каким образом можно передать параметры в макрос написанный в Autocad на VBA? Например, есть процедура, которая отрисовывает заштрихованный прямоугольник (см. ниже). Как её изменить, чтобы на входе от пользователя требовалось ввести также в качестве параметров координаты углов прямоугольника?

Public Sub DrawHatchedBox()

...

End Sub

Сергей Ивков
Сергей Ивков
Россия, Геленджик
Юлия Мягчилова
Юлия Мягчилова
Россия