Опубликован: 21.02.2012 | Доступ: свободный | Студентов: 2061 / 499 | Оценка: 4.20 / 4.40 | Длительность: 19:35:00
Специальности: Разработчик аппаратуры
Лекция 6:

Программирование диалоговых окон на языке 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).

 Элементы диалогового окна

Рис. 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.

 Диалоговое окно с кнопками

Рис. 6.4. Диалоговое окно с кнопками
Алексей Тимонин
Алексей Тимонин
Алексей Потапкин
Алексей Потапкин

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

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

Public Sub DrawHatchedBox()

...

End Sub