Программирование диалоговых окон на языке DCL
Функция dimx_tile
Функция dimx_tile вычисляет горизонтальный размер графического элемента с данным кодом (точнее, размер элемента минус 1). Синтаксис:
(dimх_tile <код>)
Аргумент <код> - строка с кодом графического элемента. Возвращаемое значение - целое число с номером крайнего правого пикселя элемента (левый крайний пиксель имеет номер ноль).
Пример:
(dimx_tile "igp2") - может вернуть 50 (всего по горизонтали 51 пиксель)
Функция dimy_tile
Функция dimy_tile вычисляет вертикальный размер графического элемента с данным кодом (точнее, размер элемента минус 1). Синтаксис:
(dimy_tile <код>)
Аргумент <код> - строка с кодом графического элемента. Возвращаемое значение - целое число с номером крайнего нижнего пикселя элемента (верхний крайний пиксель имеет номер ноль)
Пример: (dimy_tile "igp2") - может вернуть 32 (всего по вертикали будет 33 пикселя).
Упражнения с элементами диалоговых окон
Построение элементов
Установите элементы диалогового окна согласно следующей программе:
// Установки элементов диалогового окна
//
elements: dialog {label="Установка элементов диалогового окна";
:column{:row{:boxed_column{label="Элементы управления";
:row{:boxed_column{label="Поле и выпадающий список";
:edit_box {label="Edit_box";key="txt";value="0.00";edit_width=8;}
:popup_list {label="Popup_list";key="pop";width="8";list="Иванов\nПетров\nСидоров";}}
:boxed_column{label="Кнопка и шкала";
:button {label="Button";key="but";color="1";width="8";}
:slider {label="Slider";}}}
:spacer{height=1;}
:radio_row {label="Ряд переключателей (radio_row)";
:radio_button {label="Radio_button 1";value=1;}
:radio_button {label="Radio_button 2";value=0;}
}
}
:boxed_row{:column{label="Список и флажок";
:list_box {label="List_box";key="list";list="Иванов\nПетров\nСидоров";height="8";}
:toggle {label="Toggle";value=1;}
}
}}
:boxed_row{label="Стандартная кнопка закрытия окна";
ok_cancel_help_info;
}}}
Сохраните файл как Elements.dcl в папке Support.
Создайте файл загрузки:
(defun c:show_elements (/ num ddiag)
(if (< (setq num (load_dialog "elements.dcl")) 0)
(prong
(alert "The Elements.dcl file could not be loaded!") (exit))
)
(if (not (new_dialog "elements" num))
(exit)
)
(start_dialog)
(unload_dialog num)
;;;--- If the user pressed the Cancel button
(if (= ddiag 1)
(princ "\n Window cancelled!")
)
;;;--- If the user pressed the Okay button
(if (= ddiag 2)
(progn
(princ "\n The user pressed Okey!")
)
)
(princ)
) ;_defun
Сохраните файл загрузки как Elements.dcl.
Запустите функцию show_elements из командной строки AutoCAD. На экране должно появиться диалоговое окно (рис. 6.3).
Программа может различить в наших действиях лишь нажатие кнопок ОК и Cancel.
Текстовые поля Edit_Box
Измените описание диалогового окна в файле rog.dcl:
//Диалоговое окно установки параметров рога
rog: dialog{label="Установка параметров рога";
:edit_box{label="Радиус окружности ";key="rad" ;value="80.00"; edit_width=8;}
:edit_box{label="Диаметр дуги, мм";key="diam";value="400.00";edit_width=8;}
:edit_box{label="Толщина стенки, мм";key="thick";value="1.00";edit_width=6;}
:spacer{height=1;}
:edit_box{label="Индекс цвета";key="col";value="2";edit_width=4;}
:spacer{height=1;}
ok_cancel;
}
А теперь вернитесь к файлу rog.lsp. В функции qrog отклики на события в диалоговом окне описывались с помощью функции action_tile. Значения переменных сохранялись для каждого отдельного элемента. Опробуйте другой способ сохранения указанных данных - по нажатии кнопки ОК. В этом случае можно оставить значения величин по умолчанию, либо отредактировать их в текстовых полях диалогового окна.
Создайте в этом же файле новую функцию save_vars, которая будет вызываться после нажатия кнопки ОК. Содержимое текстовых полей прочитает функция get_tile.
Следует учесть, что в данном случае переменные rad1, diam1, thick1, col1 должны быть общими для функций qrog и save_vars, т.е. глобальными.
(defun save_vars () (setq rad1 (atof (get_tile "rad"))) (setq diam1 (atof (get_tile "diam"))) (setq thick1 (atof (get_tile "thick"))) (setq col1 (get_tile "col")) )
Программа построения рога будет выглядеть следующим образом:
(defun c:qrog (/ cenrt1 circle1 arc1 rog1 angle1 endp1 dial) (setq centr1 '(0 0 0)) ; исходная базовая точка (if (< (setq num (load_dialog "rog.dcl")) 0); загружаем в память файл "rog.dcl" (progn (alert "Файл Rog.dcl не загружен!"); сообщение о неудачной загрузке (exit) )) (if (not (new_dialog "rog" num)); ;; ;;функция new_dialog проверяет наличие в файле диалога "rog" (progn (alert "Диалог Rog не найден!"); сообщение о неудачном поиске файла (exit) )) ;;;If an action event occurs, do this function (action_tile "accept" "(setq dial 2)(save_vars)(done_dialog)"); действия при нажатии ОК (action_tile "cancel" "(setq dial 1)(done_dialog)"); действия при нажатии CANCEL (start_dialog); активизирует диалоговое окно (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 ""); удаляем ненужную образующую дугу ;;;If the user pressed the Okey Or Cancel button (if(= dial 2) (alert "Congratulations!")); поздравление при успешном построении (if(= dial 1) (alert "Alas!")); увы! - при неудачном построении (princ); тихий выход )
В качестве варианта введите операции сохранения значений переменных в функцию qrog. Сделайте все переменные локальными. Функция save_vars тогда не нужна.
Рассмотрим теперь более подробно работу с отдельными элементами диалоговых окон: с кнопками, со списками, с флажками и с радиокнопками.
Кнопки Button
Создадим DCL-файл описания диалогового окна с тремя кнопками Button и одной кнопкой Cancel. Каждая из трех кнопок должна выдать послание при нажатии.
Расположите кнопки в колонку друг под другом в две группы:
But:dialog {label="Работа с кнопками Button";
:column{:boxed_column {
:button {key="but1";label="Button1";is_default="false";}
:button {key="but2";label="Button2";is_default="false";}
:button {key="but3";label="Button3";is_default="false";}
}
:boxed_row{ok_cancel; }
}
}
Сохраните файл как But.dcl в папке …\Support.
А теперь составьте файл But.lsp для загрузки dcl-файла и описания сценария отклика на события в диалоговом окне. Он будет состоять из двух функций:
(defun C:But1()
;;;--- Load the dcl file
(setq dcl_id (load_dialog "But.dcl"))
;;;--- Load the dialog definition if it is not already loaded
(if (not (new_dialog "But" dcl_id))
(progn
(alert "The But.dcl file could not be loaded!")(exit)
)
)
;;;--- If an action event occurs, do this function
(action_tile "but1" "(doButton 1)")
(action_tile "but2" "(doButton 2)")
(action_tile "but3" "(doButton 3)")
(action_tile "cancel" "(done_dialog)")
;;;--- Display the dialog box
(start_dialog)
;;;--- Unload the dialog box
(unload_dialog dcl_id)
;;;--- Suppress the last echo for a clean exit
(princ)
)
(defun doButton(a)
(cond
((= a 1)(alert "Button 1 was pressed!"))
((= a 2)(alert "Button 2 was pressed!"))
((= a 3)(alert "Button 3 was pressed!"))
)
)
На экране должна быть картинка, подобная рис. 6.4.

