Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
Среда программирования
Библиотеки C
++
1
Часть 1. Использование ObjectARX........................................................................................................................... 11
Глава 1. Обзор......................................................................................................................................................... 11
Среда программирования ObjectARX...............................................................................................................11
Доступ к Базе данных AutoCAD.................................................................................................................... 11
Взаимодействие с Редактором AutoCAD....................................................................................................12
Создание Интерфейсов пользователя с MFC............................................................................................12
Поддержка МНОГОДОКУМЕНТАЛЬНОГО ИНТЕРФЕЙСА.........................................................................12
Создание Заказных Классов........................................................................................................................12
Формирование Комплексных Приложений.................................................................................................12
Библиотека классов ObjectARX................................................................................................................... 12
AcRx Библиотека........................................................................................................................................... 12
Идентификация типа во время выполнения...............................................................................................13
AcEd Библиотека........................................................................................................................................... 13
AcDb Библиотека........................................................................................................................................... 14
AcGi Библиотека............................................................................................................................................ 14
AcGe Библиотека.......................................................................................................................................... 15
Глава 2. Первичные базы данных......................................................................................................................... 16
Краткий обзор Базы данных AutoCAD..............................................................................................................16
Количество баз данных.................................................................................................................................17
Получение ID объекта................................................................................................................................... 17
Обязательные объекты Базы данных..........................................................................................................17
Создание объектов в AutoCAD..................................................................................................................... 18
Создании объектов в ObjectARX....................................................................................................................... 19
Создание примитивов................................................................................................................................... 19
Создание Нового Уровня..............................................................................................................................20
Открытие и Закрытие объекта ObjectARX..................................................................................................21
Добавление Группы к Словарю Группы.......................................................................................................21
Глава 3. Прикладные Основы ObjectARX.............................................................................................................21
Создание приложения ObjectARX.................................................................................................................... 22
Создание Заказных Классов.............................................................................................................................22
Ответ на Сообщения AutoCAD.........................................................................................................................22
Последовательность событий в приложении ObjectARX...........................................................................24
Осуществление Точки входа для AutoCAD......................................................................................................25
Инициализация ObjectARX Приложения........................................................................................................26
Подготовка к Разгрузке...................................................................................................................................... 26
Приложение Примера........................................................................................................................................ 26
Регистрация Новых Команд.............................................................................................................................. 27
Стек Команды................................................................................................................................................ 27
Порядок поиска............................................................................................................................................. 28
Глобальная переменная против Местных Названий Команды.................................................................28
Прозрачный против Модальных Команд.....................................................................................................28
Загрузка ObjectARX Приложения.................................................................................................................... 29
Путь поиска файлов...................................................................................................................................... 29
Распечатка Загруженных ObjectARX Приложений....................................................................................29
Разгрузка ObjectARX Приложения.................................................................................................................. 29
Разблокировка приложения.............................................................................................................................. 29
AutoCAD, Системный реестр Системы Windows, и Приложения ObjectArx..................................................30
Модификация Системного реестра при Инсталляции Приложения ObjectArx.............................................31
Создание Дополнительных клавиш AutoCAD и Значений.........................................................................31
Создание ключей и значений приложения ObjectArx.................................................................................32
Удаление Системной Информации Системного реестра..........................................................................32
Системная переменная DEMANDLOAD..........................................................................................................32
Загрузка Запроса на Обнаружении Заказных Объектов{*целей*}.................................................................33
Загрузка Запроса на Команде...........................................................................................................................33
Загрузка Запроса на Запуске AutoCAD............................................................................................................34
ARX Команда...................................................................................................................................................... 34
? — Приложения Списка.............................................................................................................................. 34
LOAD.............................................................................................................................................................. 34
UNLOAD......................................................................................................................................................... 34
Commands...................................................................................................................................................... 35
Options............................................................................................................................................................ 35
Выполнение Приложений ObjectArx от AutoLISP............................................................................................35
Обработка ошибок............................................................................................................................................. 36
Глава 4. Операции базы данных рисунка.............................................................................................................38
Инициализация базы данных............................................................................................................................38
Создание и Начальная загрузка Базы данных................................................................................................38
Сохранение Базы данных................................................................................................................................. 38
Установка Заданного по умолчанию Формата файла................................................................................39
Глобальные функции сохранения................................................................................................................39
2
Операция Wblock.............................................................................................................................................. 40
Создание Новой Базы данных от Существующей Базы данных...............................................................40
Создание Новой Базы данных с примитивами................................................................................................40
Копирование Названного Блока...................................................................................................................40
Копирование Массива примитивов..............................................................................................................40
Вставка Базы данных........................................................................................................................................ 40
Установка Текущих Значений Базы данных.....................................................................................................41
Номер цвета Базы данных........................................................................................................................... 41
База данных Linetype Значение................................................................................................................. 41
База данных Linetype Значение Масштаба...............................................................................................41
Значение Уровня Базы данных....................................................................................................................42
Пример Операций Базы данных.......................................................................................................................42
Длинные транзакции.......................................................................................................................................... 43
Класс и Функциональный Краткий обзор.....................................................................................................43
Внешние ссылки................................................................................................................................................. 45
Внешняя ссылка Пред- и Последующая обработка...................................................................................46
AcDbDatabase:: xrefBlockId () Функция........................................................................................................46
AcDbDatabase:: restoreOriginalXrefSymbols () Функция..............................................................................46
AcDbDatabase::restoreForwardingXrefSymbols () Функция..........................................................................47
Закрытие файла и Проверки Последовательности....................................................................................47
Индексы и Фильтры........................................................................................................................................... 47
AcDbIndexFilterManager Namespace............................................................................................................48
AcDbIndex Класс............................................................................................................................................ 48
AcDbFilter класс............................................................................................................................................. 48
AcDbFilteredBlockIterator Класс.................................................................................................................... 48
AcDbCompositeFilteredBlockIterator Класс...................................................................................................48
Рисунок Итоговой Информации........................................................................................................................48
AcDbDatabaseSummaryInfo Класс................................................................................................................48
AcDbSummaryInfoReactor Класс.................................................................................................................. 49
AcDbSummaryInfoManager Класс.................................................................................................................49
Глобальные Итоговые Информационные Функции....................................................................................49
Сохраненный Программным обеспечением Autodesk....................................................................................49
Глава 5. Объекты Базы данных.............................................................................................................................49
Открытие и Закрытие Объектов Базы данных................................................................................................49
Удаление объекта.............................................................................................................................................. 51
Монопольное использование Базы данных Объектов....................................................................................51
Добавление Объектно - определенных Данных..............................................................................................52
Расширенные Данные.................................................................................................................................. 52
Словарь Расширения.................................................................................................................................... 53
Стирание объекта.............................................................................................................................................. 56
Запись Объекта в файл..................................................................................................................................... 57
Глава 6. Примитивы................................................................................................................................................ 57
Определенные Примитивы............................................................................................................................... 57
Монопольное использование Примитива........................................................................................................58
Общие Свойства Примитива............................................................................................................................. 59
Цвет примитива............................................................................................................................................. 60
Linetype примитива..................................................................................................................................... 60
Примитив Linetype Масштаб......................................................................................................................61
Видимость Примитива.................................................................................................................................. 61
Уровень Примитива....................................................................................................................................... 61
Общие функции Примитива.............................................................................................................................. 62
Объектные точки привязки................................................................................................................................ 62
Функции преобразования.................................................................................................................................. 63
Пересечение точек........................................................................................................................................ 63
GS Маркеры и Подпримитивы.....................................................................................................................64
Высвечивание Вложенных Блочных Ссылок..............................................................................................68
Расчленение примитивов............................................................................................................................. 72
Создание Образцов Примитивов AutoCAD......................................................................................................73
Создание Простого Примитива.................................................................................................................... 73
Создание записи простой таблицы блока...................................................................................................73
Создание записи таблицы блоков с определениями атрибута.................................................................74
Создание блок-ссылки с Атрибутами..........................................................................................................75
Выполнение итераций через Запись таблицы блоков...............................................................................77
Сложные примитивы.......................................................................................................................................... 78
Создание Сложного Примитива................................................................................................................... 78
Выполнение итераций через Вершину в Ломаной линии..........................................................................78
Доступ к Системе координат............................................................................................................................. 79
Система координат Примитива.................................................................................................................... 79
AcDb2dPolylineVertex.................................................................................................................................... 79
Функции Кривой.................................................................................................................................................. 80
3
Соединение Гиперсвязей с примитивами........................................................................................................80
AcDbHyperlink Класс..................................................................................................................................... 80
AcDbHyperlinkCollection Класс...................................................................................................................... 81
AcDbEntityHyperlinkPE Класс........................................................................................................................ 81
Пример Гиперсвязи....................................................................................................................................... 81
Глава 7.Контейнерные Объекты............................................................................................................................ 82
Сравнение Таблиц идентификаторов и Словарей..........................................................................................82
Таблицы идентификаторов............................................................................................................................... 83
Таблица блоков............................................................................................................................................. 84
Таблица Уровня............................................................................................................................................. 84
Iterators........................................................................................................................................................... 86
Словари.............................................................................................................................................................. 87
Группы и Словарь Группы............................................................................................................................. 87
MLINE Словарь Стиля.................................................................................................................................. 88
Словарь Размещения................................................................................................................................... 89
Создание Словаря........................................................................................................................................ 89
Выполнение итераций по Входам Словаря................................................................................................90
Размещения........................................................................................................................................................ 91
ObjectARX Классы Размещения................................................................................................................. 91
Xrecords.............................................................................................................................................................. 92
DXF Коды Группы для Xrecords.................................................................................................................. 92
Примеры........................................................................................................................................................ 92
Часть 2. Интерфейсы пользователя..........................................................................................................................93
Глава 8. MFC........................................................................................................................................................... 93
Введение............................................................................................................................................................. 94
Использование MFC с Приложениями ObjectArx............................................................................................94
MFC и Немодальные Диалоговые окна.......................................................................................................94
Приложения ObjectArx с Динамически Связанным MFC................................................................................94
Параметры настройки Проекта Visual C++ для Динамически Связанного MFC......................................94
Отладка Приложений ObjectArx с Динамический MFC..............................................................................95
Управление ресурсами................................................................................................................................. 95
Встроенная MFC Поддержка Интерфейса пользователя...............................................................................96
Иерархия Классов......................................................................................................................................... 97
AdUi Передача сообщений.......................................................................................................................... 97
AdUi Окна подсказок..................................................................................................................................... 97
AdUi Диалоговые классы.............................................................................................................................97
AcUi Диалоговые классы.............................................................................................................................. 98
AdUi Расширяемость Позиции табуляции Поддержки Классов................................................................98
AdUi и AcUi Классы Строки управления.....................................................................................................98
AdUi и AcUi Средства редактирования.......................................................................................................99
AdUi и AcUi Средство управления Поля со списком...............................................................................100
AcUi MRU Поля со списком........................................................................................................................ 100
AdUi Классы Кнопки.................................................................................................................................... 101
AcUi Классы Кнопки.................................................................................................................................... 102
Постоянство Данных Диалога.................................................................................................................... 102
Использование и распространение Системы Диалога Позиции табуляции AdUi.................................102
Построение заказного диалога с табуляторами, расширяемого.............................................................103
Распространение AutoCAD Встроенные Диалоги Позиции табуляции..................................................103
Использование AdUi и AcUi с VC ++ AppWizard.........................................................................................104
Создайте ObjectARX MFC Прикладной Скелет.......................................................................................104
Создание MFC-диалога, используя Visual Studio.....................................................................................105
Создание классов и средств управления..................................................................................................106
Создайте Обработчики для Диалога.........................................................................................................106
Добавьте Код к Обработчикам................................................................................................................... 107
Глава 9. Наборы выборов, примитивы и функции таблиц идентификаторов..................................................111
Набор Выборов и имена Примитива...............................................................................................................111
Обработка Наборов Выбора............................................................................................................................ 111
Списки Фильтра Набора Выбора............................................................................................................... 113
Образцы Подстановочных знаков в Списках Фильтра.............................................................................114
Фильтрация для Расширенных Данных.....................................................................................................114
Относительные Испытания........................................................................................................................ 116
Условная Фильтрация................................................................................................................................. 116
Манипуляция наборами выборов..............................................................................................................116
Имя Примитива и Функции Данных................................................................................................................ 119
Функции Имени Примитива........................................................................................................................ 119
Метки примитива и их использования.......................................................................................................120
Контекст примитива и координатное преобразовывание данных...........................................................121
Функции Данных Примитива...................................................................................................................... 124
Сложные примитивы................................................................................................................................... 127
4
Анонимные Блоки....................................................................................................................................... 129
Примечания относительно Расширенных Данных...................................................................................130
Регистрация Приложения........................................................................................................................... 132
Поиск расширенных данных...................................................................................................................... 132
Управление использованием памяти расширенными данными.............................................................133
Использование Меток в Расширенных данных........................................................................................133
Xrecord Объекты........................................................................................................................................ 134
Доступ к таблицам идентификаторов............................................................................................................135
Глава10. Глобальные Функции для Взаимодействия с AutoCAD.....................................................................136
Запросы AutoCAD и Команды......................................................................................................................... 136
Общий Доступ............................................................................................................................................. 136
Использование acedCmd ()....................................................................................................................... 137
Приостановка ввода пользователя............................................................................................................138
Принятие указения точки командой AutoCAD...........................................................................................138
Системные Переменные............................................................................................................................ 138
Символы AutoLISP...................................................................................................................................... 139
Поиск Файла................................................................................................................................................ 140
Объектная Привязка................................................................................................................................... 140
Описатели Области просмотра.................................................................................................................. 141
Геометрические Утилиты............................................................................................................................ 141
Функция Утилиты Текстового поля.............................................................................................................142
Получение ввода пользователя...................................................................................................................... 144
Функции ввода пользователя..................................................................................................................... 144
Функции контроля ввода пользователя.....................................................................................................145
Графическое перемещение Наборов Выбора..........................................................................................147
Прерывания от пользователя..................................................................................................................... 147
Возвращение Значений к Функциям AutoLISP..........................................................................................148
Преобразования............................................................................................................................................... 148
Строковые Преобразования....................................................................................................................... 148
Реальные преобразования......................................................................................................................... 149
Обработка Символьного типа......................................................................................................................... 150
Преобразования Системы координат............................................................................................................150
Контроль Дисплея............................................................................................................................................ 151
Интерактивный Вывод................................................................................................................................ 151
Контроль Графических и Текстовых Экранов низкого уровня.................................................................152
Контроль относительно Графики Нижнего уровня и Ввода пользователя.............................................152
Калибровка Таблетки....................................................................................................................................... 153
Сопоставление подстановочных знаков........................................................................................................154
Часть 3. Определение новых классов.................................................................................................................... 155
Глава 11. Получение заказного класса ObjectARX...........................................................................................155
Образование класса пользователя................................................................................................................ 155
Идентификация Класса Во время выполнения.............................................................................................156
Макрокоманда Объявления Класса...............................................................................................................156
Макрокоманды Выполнения Класса...............................................................................................................157
Функция Инициализации Класса.................................................................................................................... 158
Глава 12. Наследование от AcDbObject............................................................................................................158
Перегрузка AcDbObject Виртуальные функции...........................................................................................158
AcDbObject: необходимые функции для перегрузки..............................................................................158
AcDbObject: Функции Часто Перегружаемые..........................................................................................158
AcDbObject: Функции Иногда Перегружаемые........................................................................................159
AcDbObject: Функции Редко Перегружаемые..........................................................................................159
AcRxObject: Функции Редко Перегружаемые..........................................................................................159
AcDbEntity: Функции к Перегрузке...........................................................................................................160
AcDbCurve: Функции к Перегрузке...........................................................................................................160
Реализация Элемента Функции.................................................................................................................... 161
Сохранение Объектов в DWG и DXF файлах...............................................................................................162
DwgOut () Функция..................................................................................................................................... 162
DwgIn () Функция........................................................................................................................................ 163
DxfOut () Функция....................................................................................................................................... 163
DxfIn () Функция.......................................................................................................................................... 163
Проверка ошибок........................................................................................................................................ 163
Реализация DWG Файловые Функции......................................................................................................163
Типовой Код для dwgOutFields ().............................................................................................................163
Типовой Код для dwgInFields ()................................................................................................................ 164
Реализация DXF Файловые Функции.............................................................................................................165
Диапазоны Кода DXF-группы..................................................................................................................... 165
Объектные Ссылки.......................................................................................................................................... 170
Ссылки Монопольного использования (Ownership References)..........................................................170
Использования Монопольного использования.........................................................................................171
5
Типы Монопольного использования..........................................................................................................171
Формирование Иерархии Монопольных использований.........................................................................171
Ссылки Указателя............................................................................................................................................ 176
Жесткие Указатели...................................................................................................................................... 176
Мягкие Указатели........................................................................................................................................ 176
Проблемы длинных транзакций для объектов пользователя......................................................................176
Чистка (Purge).................................................................................................................................................. 178
Отмена и Восстановление (Undo и Redo)......................................................................................................178
Автоматическая Отмена............................................................................................................................. 178
Частичная Отмена...................................................................................................................................... 178
Redo ( Восстановить )................................................................................................................................. 180
subErase, subOpen, subClose, and subCancel................................................................................................180
Пример Заказного Объектного Класса...........................................................................................................186
Файл Заголовка........................................................................................................................................... 186
Файл реализации........................................................................................................................................ 186
Поддержка Версии объекта............................................................................................................................ 189
Класс Versioning.......................................................................................................................................... 189
Класс Versioning Пример.......................................................................................................................... 189
Использование Класса Versioning............................................................................................................190
Класс Реализации Versioning................................................................................................................... 190
Переименование Класса................................................................................................................................. 191
Данные Класса или Xdata Номера версии....................................................................................................191
Глава 13. Наследование от AcDbEntity..............................................................................................................192
Наследование Заказных примитивов.............................................................................................................192
AcDbEntity перегружаемые функции.......................................................................................................192
AcDbEntity функции, обычно перегружаемые.........................................................................................193
AcDbEntity Функции, редко перегружаемые............................................................................................193
Перегрузка Общих Функций Примитива........................................................................................................194
Перегрузка worldDraw () и viewportDraw ()...........................................................................................194
Перегрузка saveAs ().................................................................................................................................. 195
Реализация функций OSNAP..................................................................................................................... 196
Реализация Функции точки захвата (grip)..................................................................................................197
Реализация Функции точки растяжения....................................................................................................199
Функции Преобразования........................................................................................................................... 199
Пересечение с Другими примитивами.......................................................................................................200
Пересечение Заказного Примитива с Другим Примитивом.....................................................................203
Взрыв Примитива........................................................................................................................................ 204
Расширение Функциональных возможностей Примитива............................................................................204
Использование AcEdJig................................................................................................................................... 204
Наследование Нового Класса от AcEdJig.................................................................................................204
Общие Шаги для Использования AcEdJig................................................................................................204
Установка Параметров для Перетащенной Последовательности..........................................................205
Цикл перетаскивания.................................................................................................................................. 205
Реализация sampler(), update(), и entity()..................................................................................................206
Добавление Примитива к Базе данных.....................................................................................................208
Типовой Код................................................................................................................................................. 209
Часть 4. Специализированные темы....................................................................................................................... 212
Глава14. Полномочные Объекты (Proxy)............................................................................................................212
Определение прокси-объекта......................................................................................................................... 212
Цикл жизни прокси-объекта............................................................................................................................ 212
Прокси-объект для пользователя................................................................................................................... 213
Отображение прокси-примитивов.................................................................................................................. 213
Редактирование прокси-примитивов..............................................................................................................213
Разгрузка приложения..................................................................................................................................... 214
Глава15. Уведомления......................................................................................................................................... 214
Краткий обзор уведомлений............................................................................................................................ 214
Реакторные Классы..................................................................................................................................... 214
Типы Объектных Реакторов....................................................................................................................... 215
Использование Реакторов............................................................................................................................... 215
AcDbObject и События Уведомления Базы данных...............................................................................216
Заказные Уведомления.............................................................................................................................. 216
Использование Редактора Реактор...........................................................................................................216
Использование Реактора Базы данных.....................................................................................................216
Использование Объектного Реактора.......................................................................................................218
Пример формирования зависимостей в объекте.....................................................................................220
Немедленная и задержанная передача событий....................................................................................223
Руководящие принципы использования уведомления............................................................................224
Глава16. Многодокументная среда..................................................................................................................... 224
Краткий обзор................................................................................................................................................... 225
Контексты Выполнения Документа............................................................................................................225
6
Образцы Данных......................................................................................................................................... 225
Документ Блокировка................................................................................................................................. 225
Классы Управления Документа.................................................................................................................. 226
Терминология................................................................................................................................................... 226
Активный Документ..................................................................................................................................... 226
Приложение................................................................................................................................................. 226
Прикладной Контекст.................................................................................................................................. 226
Команда....................................................................................................................................................... 226
Команда, MDI............................................................................................................................................... 227
Команда, повторно неиспользуемая.........................................................................................................227
Командный процессор................................................................................................................................ 227
Текущий Документ....................................................................................................................................... 227
База данных................................................................................................................................................. 227
Документ...................................................................................................................................................... 227
Рисунок........................................................................................................................................................ 227
Сеанс редактирования............................................................................................................................... 227
Контекст выполнения приложения............................................................................................................227
MDI-совместимый....................................................................................................................................... 227
"В приложении"............................................................................................................................................ 228
"В контексте "............................................................................................................................................... 228
"В документе".............................................................................................................................................. 228
Статический................................................................................................................................................. 228
Сессия.......................................................................................................................................................... 228
Стек Отмены................................................................................................................................................ 228
SDI Переменная Системы............................................................................................................................... 228
Уровни Совместимости................................................................................................................................... 228
SDI-ТОЛЬКО Уровень.................................................................................................................................. 229
MDI-ЗНАЯ Уровень...................................................................................................................................... 229
MDI-СПОСОБНЫЙ Уровень....................................................................................................................... 230
MDI-РАСШИРЕННЫЙ Уровень................................................................................................................... 230
Взаимодействие с Множественными документами......................................................................................231
Доступ к текущему документу и связанным с ним объектам..................................................................231
Доступ к базам данных, связанным с нетекущими документами............................................................231
Установка текущего документа без его активации...................................................................................232
События уведомления документа.................................................................................................................. 232
Специфические для приложения объекты документа..................................................................................232
Повторно неспользуемые команды................................................................................................................232
Создание Неповторно используемой Команды........................................................................................232
Повторно неиспользуемые команды AutoCAD.........................................................................................233
Много-документные команды......................................................................................................................... 233
Отключение переключения документа..........................................................................................................234
Прикладной контекст выполнения.................................................................................................................. 234
Код, вызванный под прикладным контекстом выполнения.....................................................................235
Различия кода под прикладным контекстом выполнения........................................................................235
Другие соображения по прикладному контексту выполнения.................................................................235
Undo базы данных и средства управления транзакции................................................................................236
Документо-независимые базы данных...........................................................................................................236
Пример MDI-ЗНАЮЩЕГО приложения..........................................................................................................237
Глава17. Управление транзакцией...................................................................................................................... 241
Краткий обзор управления транзакциями......................................................................................................241
Менеджер транзакции..................................................................................................................................... 242
Вложение транзакций...................................................................................................................................... 242
Границы транзакции........................................................................................................................................ 243
Получение указателей на объекты в транзакции..........................................................................................243
Недавно созданные объекты и транзакции...................................................................................................243
Передавать-разовые руководящие принципы...............................................................................................244
Отмена и транзакции....................................................................................................................................... 244
Смешивание модели транзакции с открытым и близким механизмом........................................................244
Транзакции и генерирование графики...........................................................................................................244
Реакторы Транзакции...................................................................................................................................... 245
Пример вложенных транзакций...................................................................................................................... 245
Глава18. Глубокое клонироване.......................................................................................................................... 251
Основы глубокого клонирования.................................................................................................................... 251
Использование clone() против deepClone().............................................................................................251
Ключевые концепции Клонирования.........................................................................................................251
Типичная операция глубокого клона.........................................................................................................252
Клонируемые Объекты от Различных Владельцев..................................................................................253
Реализация deepClone() для заказных классов......................................................................................255
Команды AutoCAD для использования глубокого клона и Wblock-клона.............................................255
Клонируемая Стадия.................................................................................................................................. 256
7
Стадия Трансляции..................................................................................................................................... 256
Словарь имен объектов.............................................................................................................................. 257
Перегрузка deepClone () Функция............................................................................................................260
Перегрузка wblockClone () Функция.........................................................................................................262
Использование appendAcDbEntity () В течение Клонирования............................................................267
Обработка жестких ссылок к AcDbEntities в течение wblockClone()...................................................268
Глава 19. Расширение Протокола....................................................................................................................... 273
Определение расширения протокола............................................................................................................273
Расширение протокола pеализации...............................................................................................................273
Объявление и определение классов расширения протокола.................................................................273
Регистрация классов расширения протокола...........................................................................................274
Заданный по умолчанию Класс для Расширения Протокола..................................................................275
Разгрузка Приложения................................................................................................................................ 275
Использование расширения протокола в приложении............................................................................275
Расширение протокола для команды MATCH...............................................................................................275
Пример расширения протокола...................................................................................................................... 276
Глава 20. Глобальные сервисные функции ObjectARX....................................................................................278
Общие характеристики функций ObjectARX................................................................................................278
Сравнение вызовов глобальных функций ObjectARX и AutoLISP.......................................................278
Возвращаемые значения против результатов функций...........................................................................279
Внешние Функции........................................................................................................................................ 279
Обработка ошибок...................................................................................................................................... 280
Связь между Приложениями...................................................................................................................... 281
Обработка Внешних Приложений..............................................................................................................283
Переменные, типы и значения, определенные в ObjectARX......................................................................284
Общие Типы и Определения...................................................................................................................... 284
Полезные значения..................................................................................................................................... 287
Буфера pезультатов и Коды Типа..............................................................................................................287
Коды Типа Результата, определенные ObjectARX..................................................................................288
DXF Коды Группы........................................................................................................................................ 288
ObjectARX функциональные коды типа результата................................................................................290
Коды Служебного бита Ввода пользователя............................................................................................290
Списки и другие динамически размещенные данные...................................................................................291
Управление памятью Буфера результата.................................................................................................292
Глава 21. Точки ввода в процессе выполнения..................................................................................................295
Заказные режимы объектной привязки..........................................................................................................295
Создание и регистрация заказного режима объектной привязки...........................................................296
Создание Классов Расширения Протокола..............................................................................................296
Создание Заказного Глифа........................................................................................................................ 297
Пример заказного режима объектной привязки.......................................................................................297
Управление точками ввода............................................................................................................................. 300
Менеджер точки ввода................................................................................................................................ 300
События контекста ввода........................................................................................................................... 301
Фильтры точки ввода и мониторы..............................................................................................................304
Глава 22. Конфигурация приложения................................................................................................................. 309
Менеджер профилей....................................................................................................................................... 310
AcApProfileManager Класс.......................................................................................................................... 310
AcApProfileManagerReactor Класс..............................................................................................................310
Часть 5. Взаимодействие с Другими Средами........................................................................................................312
Главa 23. COM, ActiveX Автоматизация и Менеджер свойств объекта............................................................312
Краткий обзор................................................................................................................................................... 312
Использование Объектов COM AutoCAD от ObjectARX и Других Сред.....................................................313
Доступ к интерфейсам COM от ObjectARX..............................................................................................313
AutoCAD ActiveX Выполнение Автоматизации.............................................................................................320
Отношения между AcDbObjects и Объектами Автоматизации..............................................................320
AcAxOleLinkManager................................................................................................................................... 321
Создание Объекта COM............................................................................................................................. 322
Выполнение Объектов Автоматизации.....................................................................................................322
Шаблоны ATL............................................................................................................................................... 323
Взаимодействие с AutoCAD............................................................................................................................ 323
Блокировка документа..................................................................................................................................... 324
Создание Файла Системного реестра............................................................................................................324
Демонстрация Функциональных возможностей Автоматизации..................................................................325
Введение Файла Проекта ATL.................................................................................................................... 325
Запись Обертки COM.................................................................................................................................. 326
Формирование и Регистрация COM DLL...................................................................................................329
Менеджер Свойства объекта API................................................................................................................... 329
Выполнение COM AutoCAD........................................................................................................................ 330
Статические OPM Интерфейсы COM.............................................................................................................330
8
ICategorizeProperties Интерфейс...............................................................................................................330
IPerPropertyBrowsing Интерфейс...............................................................................................................330
IOPMPropertyExtension Интерфейс...........................................................................................................331
IOPMPropertyExpander Интерфейс............................................................................................................331
Глава 24. API COM дизайн-центра AutoCAD......................................................................................................334
API Дизайн-центра AutoCAD........................................................................................................................... 334
Интерфейс IAcDcContentBrowser...............................................................................................................335
Интерфейс IAcDcContentView.................................................................................................................... 335
Интерфейс IAcDcContentFinderSite...........................................................................................................335
Интерфейс IAcDcContentFinder.................................................................................................................. 335
Интерфейс IAcPostDrop............................................................................................................................ 335
Требования системного реестра для компонента Дизайн-центра AutoCAD...............................................335
Ключи приложений...................................................................................................................................... 335
Ключи расширений...................................................................................................................................... 336
CLASSID Регистрация................................................................................................................................ 336
Реализация интерфейса для AutoCAD Дизайн-центра................................................................................337
Настройка Дизайн-центра AutoCAD...............................................................................................................338
Создайте ActiveX Проект Библиотеки Шаблона......................................................................................338
Добавьте Поддержку Системного реестра и Новый Объект COM ATL...................................................338
Добавьте Код, чтобы Поддержать Новый Объект COM ATL....................................................................340
Часть 6. Библиотеки ObjectARX.............................................................................................................................. 345
Глава 25. Библиотеки ObjectDBX....................................................................................................................... 345
Введение.......................................................................................................................................................... 345
Краткий обзор.............................................................................................................................................. 345
Ведущие Приложения................................................................................................................................. 345
ObjectDBX Библиотеки.............................................................................................................................. 345
Интерфейс пользователя и Доступ к базе данных...................................................................................345
Использование ObjectDBX............................................................................................................................. 346
Начало с ObjectDBX.................................................................................................................................. 346
ObjectDBX Библиотечные Изменения......................................................................................................346
Различия между ObjectDBX и ObjectARX....................................................................................................347
AcEditorReactor Класс................................................................................................................................. 347
AcGi API....................................................................................................................................................... 347
Локализация и XMX Файлы............................................................................................................................ 347
Управление транзакцией................................................................................................................................. 348
AcTransaction и Классы AcTransactionReactor..........................................................................................348
AcTransactionManager и Классы AcDbTransactionManager......................................................................348
Создание Средства просмотра....................................................................................................................... 349
Компоненты Средства просмотра.............................................................................................................349
AcGi.............................................................................................................................................................. 349
AcGix............................................................................................................................................................ 349
Различия AcGix от просмотра в AutoCAD.................................................................................................350
SimpleView................................................................................................................................................... 351
WhipView...................................................................................................................................................... 351
ViewAcDb..................................................................................................................................................... 352
Основная операция средства просмотра..................................................................................................352
Предложения конфигурации...................................................................................................................... 352
Загрузка по требованию.................................................................................................................................. 352
Установка ObjectDBX Библиотек................................................................................................................... 353
Использование COMMONFILES................................................................................................................ 353
Установка версии как SHAREDFILE...........................................................................................................353
Гарантируйте, что Файлы Находятся на Пути..........................................................................................353
Советы и технические приемы........................................................................................................................ 355
ACAD_OBJID_INLINE_INTERNAL..............................................................................................................355
AcDbDatabase - советы............................................................................................................................... 355
AcDbDatabase:: insert()............................................................................................................................. 356
Поиск активных областей просмотра в пространстве модели................................................................356
Подробности относительно областей просмотра.....................................................................................357
Всегда проверяйте Ваши рисунки в AutoCAD 2000..................................................................................357
Использование DWG файлов более ранних версий................................................................................357
Расширенные данные примитива..............................................................................................................358
Растровые Изображения............................................................................................................................ 358
Известные Ограничения.................................................................................................................................. 358
Глава 26. Библиотека графического интерфейса..............................................................................................358
AcGi Краткий обзор.......................................................................................................................................... 359
SetAttributes Функция.................................................................................................................................. 360
WorldDraw () Функция................................................................................................................................ 360
ViewportDraw () Функция............................................................................................................................. 361
Тип Регенерации Области просмотра.......................................................................................................361
9
Установка Черт Примитива............................................................................................................................. 362
Черты Подпримитива.................................................................................................................................. 362
Пример Использования AcGi..................................................................................................................... 364
Примитивы........................................................................................................................................................ 365
Сеть.............................................................................................................................................................. 365
Оболочка (Shell).......................................................................................................................................... 367
Дуга.............................................................................................................................................................. 369
Полилиния................................................................................................................................................... 370
Текст............................................................................................................................................................. 370
Использование Drawables в Вашем Объекте..............................................................................................372
Двумерные соты (Tessellation).................................................................................................................... 372
Isolines.......................................................................................................................................................... 373
Преобразования............................................................................................................................................... 373
Система координат модели........................................................................................................................ 374
Мировая система координат...................................................................................................................... 374
Система координат Глаза........................................................................................................................... 374
Система координат Дисплея...................................................................................................................... 374
Примеры Преобразования......................................................................................................................... 374
Пример 1: Системы координат................................................................................................................... 374
Пример 2: Определение Невидимых линий для Объекта для Стандартного Дисплея.........................375
Пример 3: Получение Координат Окна......................................................................................................377
Пример 4: Вычисление Круга, чтобы Рисовать........................................................................................378
Подготовка................................................................................................................................................... 380
Пример отсечения границ.......................................................................................................................... 380
Глава 27. Использование Библиотеки Геометрии..............................................................................................381
Краткий обзор AcGe Библиотеки.................................................................................................................... 381
Глобальные данные и функции..................................................................................................................382
Использование базовых геометрических типов............................................................................................383
Использование классов линии и плоскостей................................................................................................385
Параметрическая Геометрия.......................................................................................................................... 385
Кривые......................................................................................................................................................... 385
Поверхности................................................................................................................................................ 387
Классы cпециальной оценки........................................................................................................................... 388
Эффективное использование вычислителей кривой и поверхности......................................................391
Постоянные AcGe примитивы........................................................................................................................ 392
AcGe Примеры Постоянства...................................................................................................................... 392
Глава 28.Использование Библиотеки Контурных представлений....................................................................394
Домен{*область*}............................................................................................................................................. 395
Топологические Объекты................................................................................................................................ 396
Использование Топологических Объектов в Вашей Программе.............................................................397
Использование Топологического Traversers в Вашей Программе.........................................................397
От Топологического Traversers до Объектов...........................................................................................398
От сети нитей к сети объектов................................................................................................................... 399
AcBr Описания Класса.................................................................................................................................... 399
Классы Примитива...................................................................................................................................... 399
Классы Сдерживания.................................................................................................................................. 399
Классы Сети................................................................................................................................................ 399
Traverser Классы......................................................................................................................................... 400
Перечислимые типы........................................................................................................................................ 400
Коды возврата ошибки................................................................................................................................ 400
Уровень проверок правильности...............................................................................................................400
ShellType...................................................................................................................................................... 401
LoopType...................................................................................................................................................... 401
Контроль Формы Элемента Сети...............................................................................................................401
Формирование Приложения............................................................................................................................ 401
Пример приложения, используя AcBr библиотеку........................................................................................402
Часть 7. Приложения................................................................................................................................................ 402
Приложение A. Перемещение ADS программ к ObjectARX.............................................................................402
Перемещение к ObjectARX............................................................................................................................ 402
AcrxEntryPoint () Функция............................................................................................................................ 402
Файлы Заголовка......................................................................................................................................... 402
Приложения Загрузки: ADS против ObjectARX............................................................................................403
Формирование ADS приложения в среде ObjectARX..................................................................................403
Типовое ObjectARX-приложение.................................................................................................................... 403
ObjectARX-эксклюзивный тип данных............................................................................................................406
Приложение B. Программируемые Диалоговые окна........................................................................................406
Краткий обзор................................................................................................................................................... 406
Функциональная схема.................................................................................................................................... 406
Пример диалогового окна................................................................................................................................ 407
Типовой файл DCL...................................................................................................................................... 407
10
Пример функции ObjectARX..................................................................................................................... 407
Функции, не позволенные, в то время как диалоговое окно активно......................................................408
Функции обратного вызова......................................................................................................................... 409
Заданные по умолчанию действия............................................................................................................409
Принятие параметров в функциях обратного вызова..............................................................................409
Сокрытие Диалоговых окон........................................................................................................................ 411
Определения и Объявления........................................................................................................................... 413
Метки для Диалоговых окон и Неперекрывающих расположений..........................................................413
Определения Функции Повторного вызова...............................................................................................413
Коды Состояния.......................................................................................................................................... 413
Обработка полей ввода................................................................................................................................... 414
Режимы Инициализации и Значения.........................................................................................................414
Изменение Режимов Повторного вызова и Значений..............................................................................414
Введение Списков и Всплывающих Списков............................................................................................415
Значения Списка Обработки...................................................................................................................... 416
Создание изображения............................................................................................................................... 417
Ввод Кнопки Изображения......................................................................................................................... 418
Обработка Радио-Кластеров...................................................................................................................... 418
Обработка Слайдеров................................................................................................................................ 419
Обработка окна редактирования...............................................................................................................419
Специфичные для приложения Данные...................................................................................................420
11
Часть 1. Использование ObjectARX
Глава 1. Обзор
Приложение ObjectARX - динамически загружаемая библиотека (DLL), использующая адресное пространство
AutoCAD и посылающая ему прямые функциональные запросы. Можно добавлять новые классы к среде
программы ObjectARX и экспортировать их для использования другими программами.
Создаваемые ObjectARX-объекты фактически неразличимы от встроенных объектов AutoCAD. Вы можете
также расширить протокол ObjectARX, прибавляя функции во
время выполнения сеанса AutoCAD.
Эта глава содержит краткий обзор библиотек классов AutoCAD и дает информацию для получения помощи по
ObjectARX.
Данное руководство предполагает, что Вы знакомы с AutoCAD и объектно-ориентированным
программированием на C++.
Этот раздел - краткий обзор этих тем. Более подробно они будут обсуждены в последующих разделах.
12
Создание Заказных Классов
Вы можете усиливать классы в иерархии ObjectARX, чтобы создать ваши собственные
заказные классы. Кроме того, Вы можете использовать обширную графику
Библиотеки ObjectARX при создании заказных классов.
ObjectARX приложения может связываться с другими интерфейсами программирования, типа VLisp, ActiveX, и
COM. Кроме того, ObjectARX приложения могут взаимодействовать с Internet связанными с объектами URL,
загружая и сохраняя чертежные файлы от WWW.
Все приложения ObjectARX должны связаться с acad.lib и rxapi.lib. Другие библиотеки могут также требоваться
в зависимости от префикса ObjectARX класса и функции, что Вы используете.
Следующие разделы берут, ближе смотрят на каждую из ObjectARX библиотек.
Для получения дополнительной информации относительно определенных(удельных) классов и функций
элемента, см. ObjectARX справочники.
AcRx Библиотека
AcRx библиотека обеспечивает классы с системным уровнем для DLL инициализации и соединения и для
регистрации класса во время выполнения и идентификации. Базовый класс этой библиотеки - AcRxObject,
который обеспечивает следующие средства:
AcRx библиотека также обеспечивает набор макрокоманд C++, чтобы помочь Вам создать новые ObjectARX
классы, полученные из AcRxObject (см. главу 11, «Получение
заказного ObjectARX класса»).
AcRxDictionary - другой важный класс в этой библиотеке. Словарь - a
Отображение от текстовой строки до другого объекта(цели). AcRx библиотека размещает ее объекты, классы,
и сервисные словари в глобальном объектном словаре, который
является образцом AcRxDictionary класса. Приложения могут прибавлять объекты к
этому словарю так, чтобы они были доступны для других приложений.
Иерархия классов для AcRx библиотеки следующие:
AcRxObject
AcRxClass
13
AcRxDictionary
AcRxDynamicLinker
AcRxEvent
AcEditor
AcRxService
AcRxKernal
AcDbServices
AcEdServices
AcadAppInfo
AcEd Библиотека
AcEd библиотека обеспечивает классы для определения и регистрации новых команд AutoCAD, которые
работают как встроенные команды. Новые команды, которые Вы определяете, упомянуты как “родные”
команды, потому что они постоянно находятся в той же самой внутренней структуре (AcEdCommandStack) как
встроенные команды. AcEd библиотека также обеспечивает редактора реактором и набором из глобальных
функций для взаимодействия с AutoCAD. Важный класс в этом библиотеке - AcEditorReactor; это контролирует
состояние редактора AutoCAD и уведомляет приложение, когда указанные события происходят, типа старта,
окончания или команды отмены.
Иерархия классов для AcEd библиотеки следующие:
AcRxObject
AcEdCommand
AcEdCommandStack
AcEdUlContext
AcEdJlg
AcEdInputPointFilter
AcEdInputPointMonitor
AcEdInputPointMeneger
AcEdSolidSubEntitySelector
AcTransaction
AcDbTransactionMeneger
AcTransactionMeneger
Для информации относительно регистрации новых команд AutoCAD, использующих ObjectARX, cм. главу 3, “
ObjectARX Прикладные Основы. ” Для примера использования
Редактор реактор, см. главу 15, “Уведомление”.
AcDb Библиотека
AcDb библиотека обеспечивает классы, которые составляют базу данных AutoCAD.
Эта база данных сохраняет всю информацию для графических объектов, называемых
Объекты, которые составляют рисунок AutoCAD, также как неграфический Объект (например, уровни,
linetypes, и текстовые стили) которые являются также частью рисунка. Вы можете сделать запрос и управлять
существующими образцами Объектов AutoCAD и объекты библиотеки AcDb, Вами могут создавать новые
образцы из объектов базы данных.
База данных AutoCAD содержит эти главные элементы:
набор девяти таблиц идентификаторов, которые имеют уникально названный входом таблицы
идентификаторов Объектов. Эти объекты представляют различный обычно используемый
AcDbDatabase Объекты и компоненты данных.
словарь названий объектов (класса AcDbDictionary), который обеспечивает “Оглавление” для рисунка
AutoCAD. Первоначально, эта таблица содержания содержит ИДЕНТИФИКАТОРЫ из четырех других
14
словарей, используемых в соответствии с AutoCAD.Приложения, которые Вы разрабатываете,
однако, являются свободными прибавить другие объекты Словарей.
фиксированный набор приблизительно 200 переменных заголовка, чей значения установлены
AutoCAD.
Иерархия классов для AcDb библиотеки следующие:
AcRxObject
Для получения дополнительной информации на AcDb библиотеке, см. главу 2, “ Учебник для начинающих
Базы данных, ” глава 4, “ Операции Базы данных, ” глава 5, “ Объекты(цели) Базы данных, ” глава 6,
“Объекты”, и глава 7, “ Контейнерные Объекты(цели). ” Для информации относительно получения новых
классов от AcDbObject и AcDbEntity, см. главу 12, “ Происходящий от AcDbObject ” и главу 13, “ Происходящий
от AcDbEntity. ”
AcGi Библиотека
AcGi библиотека обеспечивает графический интерфейс, используемый для рисунка объектов AutoCAD. Эта
библиотека используется AcDbEntity функциями элемента
WorldDraw (), viewportDraw (), и saveAs (), вся часть стандартного протокола объекта. WorldDraw () функция
должен быть определен всеми заказными классами объекта. Объект AcGiWorldDraw обеспечивает API, через
который AcDbEntity:: worldDraw () может производить его графическое представление во всех областях
просмотра одновременно. Точно так же объект(цель) AcGiViewportDraw обеспечивает API, через который
AcDbEntity:: viewportDraw () функция может про-ducedifferent графические представления для каждой области
просмотра.
Иерархия классов для AcGi библиотеки следующие:
AcRxObject
AcGiCommonDraw
AcGiWorldDraw
AcGiWorldDraw
AcGiContext
AcGiEdgeData
AcGiFaceData
AcGiGeometry
AcGiViewportGeometry
AcGiWorldGeometry
15
AcGiLinetypeEngine
AcGiSubEntityTraits
AcGiDrawableTraits
AcGiTextStyle
AcGiVertexData
AcGiViewport
AcGiDrawable
AcGiGlyph
Для получения дополнительной информации при использовании AcGi классы, см. главу 13, “ Происходящий
от AcDbEntity. ”
AcGe Библиотека
AcGe библиотека используется AcDb библиотекой и обеспечивает сервисные классы типа векторов и матриц,
которые используются, чтобы исполнить общие двумерные и трехмерные геометрические операции. Это
также обеспечивает основные геометрические объекты типа точек, кривых, и поверхностей.
AcGe библиотека состоит из двух главных подмножеств: классы для двумерной геометрии и классов для
трехмерной геометрии. Главные абстрактные классы - AcGeEntity2d и AcGeEntity3d. Несколько основных
классов, не полученные из любого другого класса включают AcGePoint2d, AcGeVector2d, и AcGeMatrix2d
(показанный в начале иерархии классов). Эти основные классы могут использоваться, чтобы исполнить много
типов общих(обычных) операций, типа добавления вектора к точке, вычисление точки или векторного
произведения двух векторов, и вычисления программы двух матриц. Классы с более высоким уровнем этой
библиотеки осуществлены, используя thesebasic классы. Иерархия классов для AcGe библиотеки следующие:
AcGeEntity2D AcGeEntity2D
AcGeBoundBlock2d AcGeBoundBlock3d
AcGeClipBoundary2d AcGeCurve3d
AcGeCurve2d AcGeCircArc3de
AcGeCircArc2d AcGeCompositeCurve3d
AcGeCompositeCurve2d AcGeEllipArc3e
AcGeEllipArc2d AcGeExternalCurve3d
AcGeExternalCurve2d AcGeLinearEnt3d
AcGeLinearEnt2d AcGeLine3d
AcGeLine2d AcGeLineSeg3d
AcGeLineSeg2d AcGeRay3d
AcGeRay2d AcGeMatrix3d
AcGeOffsetCurve2d AcGeOffsetCurve3d
AcGeSplineEnt2d AcGeSplineEnt3d
AcGeCubicSplineCurve2d AcGeCubicSplineCurve3d
AcGeNurbCurve2d AcGeNurbCurve3d
AcGePolyline2d AcGePolyline3d
AcGeCurveCurveInt2d AcGeAugPolyline3d
AcGePointEnt2d AcGeCurveCurveInt3d
AcGePointOnCurve2d AcGeCurveSurfInt
AcGePosition2d AcGePointEnt3d
AcGePointOnCurve3d
AcGeCurveBoundary AcGePointOnSurface
AcGe AcGePosition3d
AcGeContext AcGeSurfSurfInt
AcGeDwgIO AcGeSurface
AcGeDxfIO AcGeCone
AcGeFileIO AcGeCylinder
AcGeFiler AcGeExternalBoundedSurface
AcGeInterval AcGeExternalSurface
AcGeKnotVector AcGeNurbSurface
16
AcGeLibVersion AcGeOffsetSurface
AcGeMatrix2d AcGePlanarEnt
AcGeMatrix3d AcGeBoundedPlanet
AcGePoint2d AcGePlane
AcAxPoint2d AcGeSphere
AcGePoint3d AcGeTorus
AcAxPoint3d
AcGeScale2d
AcGeScale3d
AcGeTol
AcGeVector2d
AcGeVector3d
AcGe библиотека обеспечивает несколько различных систем координат. Для получения дополнительной
информации, см. главу 27, “ Использование Библиотеки Геометрии. ” Выборка программ этого справочника
иллюстрирует многочисленные обычные использования классов AcGe.
L a y e r T a b le B lo c k T a b le O t h e r S y m b o l T a b le s N a m e d O b je c t D ic t io n a r y
L a y e r T a b le R e c o r d B lo c k T a b le R e c o r d T h e ir S y m b o l T a b le R e c o r d s O b je c t s
E n t it y
17
В течение сеанса редактирования Вы можете получить базу данных для текущего рисунка, вызывая
следующую глобальную функцию:
acdbHostApplicationServices()->workingDatabase()
Получение ID объекта
Через ID Вы можете получить указатель на фактический объект базы данных для обеспечения исполнения
операций с ним. Для примера, см. “Открытие и Закрытие ObjectARX Объекты” на странице 27.
Вы можете получить ID объекта несколькими способами:
Создание объекта и добавление его в конец базы данных. База данных тогда дает объекту ID и
возвращает его Вам.
Используют протокол базы данных для получения ID объектов, которые созданы автоматически,
когда база данных создана (типа фиксированного набора таблиц идентификаторов и названного
объектного словаря).
Используют класс - определенный протокол для получения объекта IDs. Некоторые классы, типа
таблиц идентификаторов и словарей, определяют объекты, которые имеют другие объекты. Эти
классы обеспечивают протокол для получения объекта IDs находящихся в собственности объектов.
Используют iterator, чтобы шагнуть через список или устанавить объект. AcDb библиотека
обеспечивает множество iterators, которые могут использоваться, чтобы шагнуть через различные
виды контейнерных объектов (AcDbDictionaryIterator, AcDbObjectIterator).
Сделать запрос набору выборов. После того, как пользователь выбрал объект, Вы можете
спрашивать, чтобы набор выборов для списка имен объекта выбранных объектов, и от имен,
преобразовал к объекту IDs. Для получения дополнительной информации на selectionsets, см. главу
6, “Объекты”.
Эти объекты могут быть автоматически созданы в новой базе данных при параметре kTrue в
конструкторе buildDefaultDrawing. Принятие KFalse создает пустую базу данных, в которую DWG или DXF
™ файл может быть загружен.
18
Когда Вы сначала вызываете AutoCAD, и база данных находится в ее заданном по умолчанию состоянии,
объекты добавлены в пространство модели, основное пространство в AutoCAD, который используется
для модельной геометрии и графики. Бумажное пространство предназначено, чтобы поддержать
“документационную” геометрию и графику, типа основ пленки для изготовления топологических чертежей,
блоков заголовка, и annotational текста. Команды создания объекта в AutoCAD (LINE, в этом случае)
заставляют объект быть добавленными к текущей базе данных также как к блоку пространства модели.
Вы можете спрашивать любой объект, принадлежащий базе данных.
Затем, предположите, что пользователь создает круг командой:
circle 9,3 2
Снова, AutoCAD создает образец соответствующего объекта — здесь, AcDbCircle — и прибавляет это к
пространству модели.
19
Наконец, группируем все объекты вместе:
group 3,2 9,3
AutoCAD создает новую группу и прибавляет ее к словарю GROUP, который содержится в объектном
словаре имен. Новая группа содержит список ID объектов, которые составляют группу.
Создание примитивов
Следующий код ObjectARX создает линию и прибавляет это к таблице блоков пространства модели:
AcDbObjectId
createLine()
{
AcGePoint3d startPt(4.0, 2.0, 0.0);
AcGePoint3d endPt(10.0, 7.0, 0.0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);
20
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pLine);
pBlockTableRecord->close();
pLine->close();
return lineId;
}
AcDbObjectId createCircle()
{
AcGePoint3d center(9.0, 3.0, 0.0);
AcGeVector3d normal(0.0, 0.0, 1.0);
AcDbCircle *pCirc = new AcDbCircle(center, normal, 2.0);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId circleId;
pBlockTableRecord->appendAcDbEntity(circleId, pCirc);
pBlockTableRecord->close();
pCirc->close();
return circleId;
}
void
createNewLayer()
{
AcDbLayerTable *pLayerTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLayerTable, AcDb::kForWrite);
AcDbLayerTableRecord *pLayerTableRecord =
new AcDbLayerTableRecord;
pLayerTableRecord->setName("ASDK_MYLAYER");
21
Открытие и Закрытие объекта ObjectARX
Все примеры кода, показанные в этой главе иллюстрируют протокол для открытия и закрытия объектов,
который вы будете должны соблюсти всякий раз, когда Вы работаете с объектами резидента-базы. Этот
протокол гарантирует, что объекты - физически в памяти, когда к ним должны обращаться.Прежде, чем Вы
можете изменять объект, Вы должны открыть его:
Открытые функции имеют параметр режима, который определяет, открываете ли Вы объект для чтения,
записи или уведомления. В то время как объект открыт для записи, Вы можете изменять его. Когда Вы
закончите, Вы должны явно закрыть объект как показано в следующем примере, независимо от режима, в
котором это было открыто:
pObject->close();
Acad::ErrorStatus
changeColor(AcDbObjectId entId, Adesk::UInt16 newColor)
{
AcDbEntity *pEntity;
acdbOpenObject(pEntity, entId,AcDb::kForWrite);
pEntity->setColorIndex(newColor);
pEntity->close();
return Acad::eOk;
}
ПРЕДУПРЕЖДЕНИЕ! Непосредственно удаление объекта, который был добавлен к базе, заставляет AutoCAD
грохаться.
void
createGroup(AcDbObjectIdArray& objIds, char* pGroupName)
{
AcDbGroup *pGroup = new AcDbGroup(pGroupName);
for (int i = 0; i < objIds.length(); i++) {
pGroup->append(objIds[i]);
}
// Put the group in the group dictionary that resides
// in the named object dictionary.
//
AcDbDictionary *pGroupDict;
acdbHostApplicationServices()->workingDatabase()
->getGroupDictionary(pGroupDict, AcDb::kForWrite);
AcDbObjectId pGroupId;
pGroupDict->setAt(pGroupName, pGroup, pGroupId);
pGroupDict->close();
pGroup->close();
}
22
Выполнение приложения ObjectARX
Следующие разделы обсуждают общие шаги разработки приложения ObjectARX более подробно.
ОБРАТИТЕ ВНИМАНИЕ, что ObjectARX Мастер доступен для создания ObjectARX проекты. См.
objectarx\utils каталог в ObjectARX SDK.
Сообщение Описание
23
KPreQuitMsgSent, когда AutoCAD выходит, но прежде, чем это начинает разгружать все
приложения ObjectARX..
Следующая таблица перечисляет сообщения, что AutoCAD посылает приложениям, которые имеют
буферизованный функцию AutoLISP с acedDefun ():
Сообщение Описание
Следующая таблица перечисляет сообщения, что приложение получает, если это имеет
зарегистрированный сервис с ObjectARX.
Сообщение Описание
Следующая таблица перечисляет сообщения, что приложение должно ответить к тому, если это
использует ActiveX Автоматизацию. См. главу 23, “ ОБЩАЯ ОБЪЕКТНАЯ МОДЕЛЬ, ActiveX
Автоматизация, и Объектный Менеджер Свойства. ”
Сообщение Описание
kOleUnloadAppMsg Посылается, чтобы определить, может ли приложение быть выгружено (то есть
ни один из его объектов ActiveX или интерфейсов не упомянут другими
приложениями).
См. rxdefs.h файл, где эти константы перечисления определены в соответствии с объявлением типа
AppMsgCode. Вы будете должны решить, на которые сообщения ваше приложение ObjectARX ответит.
Следующая таблица описывает рекомендуемые действия после получения данного сообщения.
ObjectARX прикладные реакции на сообщения AutoCAD
24
возводящие в степень любое из этих предположений приведут к состоянию
ошибки, иногда фатальному.
AcDb и AcGi библиотеки вообще еще не активен, хотя связано AcRx, и другие
структуры на месте
25
Если приложение загружено, когда рисунок уже открытый, последовательно посланы сообщения
kInitAppMsg и kLoadDwgMsg. Когда приложение ObjectARX разгружено, в то время как сеанс
редактирования происходит - kUnloadDwg и kUnloadApp.
extern "C"
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt);
26
}
return AcRx::kRetOK;
}
Подготовка к Разгрузке
Когда ваше приложение разгружено, Вы должны очистить любые заказные классы или
Команды, которые ваше приложение создало. Это должно иметь место в AcRx:: kUnloadAppMsg случае
вашего acrxEntryPoint () функция, или в функции Названный от того случая.
Разгрузить приложение ObjectARX
1, если Вы создали команды с acedRegCmds макрокомандой или acedDefun (), Удалите их. Обычно ObjectARX
команды удалены группами, использованием AcedRegCmds- > removeGroup ().
2, если Вы создали заказные классы, удаляют их.
Используйте deleteAcRxClass () функция, чтобы удалить ваши заказные классы из AcRx дерево во время
выполнения. Классы должны быть удалены, начинаясь с Полученные классы сначала, подготавливая дерево
классов к родительским классам.
3 Удаляют любые объекты, добавленные приложением.
Не имеется никакого способа сообщить AutoCAD забывать относительно AcDbObject образцов это
Являются в настоящее время резидентом в базе данных. Однако, когда приложение Разгруженный, AutoCAD
автоматически повернет такие объекты в образцы AcDbProxyObject или AcDbProxyEntity.
4 Удаляют любые реакторы, которые были приложены к любому AcDbObject, AcDbDatabase,
AcRxDynamicLinker, или объект{*цель*} AcEditor. (Постоянные реакторы На AcDbObjects - исключение; они
станут полномочными объектами, когда Приложение разгружено.)
5, если Вы создали, сервисное название, удаляет это.
Вы можете использовать AcrxServiceDictionary- >, удаляют () функцию, чтобы удалить любого
Обслуживание{*служба*}, которое ваше приложение имеет буферизованный. См. распечатку для
AcrxServiceDictionary в ObjectARX Ссылке{*справочниках*}.
Приложение Примера
Следующие функции орудий приложения примера, которые называются
Когда приложение загружено и разгруженный. Его функция инициализации добавляется
Две новых команды к AutoCAD: СОЗДАЙТЕ и ВЫПОЛНИТЬ ИТЕРАЦИИ. Это также инициализирует Новый
класс AsdkMyClass и прибавляет это к ObjectARX иерархии с
AcrxBuildClassHierarchy () функция (. AsdkMyClass описан в “ Пример Заказного Объектного Класса ” на
странице 338.)
// Функция инициализации, называемая от acrxEntryPoint ()
// Функция в течение kInitAppMsg случая{*регистра*} используется, чтобы прибавить команды
// К команде располагают в стеке и прибавлять классы к ACRX классу
// Иерархия.
//
void
initApp()
27
{
acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_CREATE", "CREATE", ACRX_CMD_MODAL,
createDictionary);
acedRegCmds->addCommand("ASDK_DICTIONARY_COMMANDS",
"ASDK_ITERATE", "ITERATE", ACRX_CMD_MODAL, iterateDictionary);
AsdkMyClass::rxInit();
acrxBuildClassHierarchy();
}
// Функция очистки, называемая от acrxEntryPoint ()
// Функция в течение kUnloadAppMsg случая{*регистра*} удаляет это приложение
// Команда сходит с команды, располагают в стеке, и удаляет это приложение
// Заказные классы от ACRX иерархии классов во время выполнения.
//
void
unloadApp()
{
acedRegCmds->removeGroup("ASDK_DICTIONARY_COMMANDS");
Стек Команды
Команды AutoCAD сохранены в группах в стеке команды, который
Определенный AcEdCommandStack классом. Один образец стека команды
Создан в сеанс AutoCAD. Этот стек состоит из заказных команд
То, что Вы определили. AcedRegCmds () макрокоманда дает Вам, обращаются к
Стек команды.
Когда Вы прибавляете команду, Вы также назначаете это название{*имя*} группы. Хорошая политика{*полис*}
Должен использовать ваш буферизованный префикс разработчика для названия{*имени*} группы, чтобы
избежать названия{*имени*}
Столкновения с другими командами. Команда называет в пределах данной группы
Должен быть уникален, и названия{*имена*} группы должны быть уникальны. Однако, множественные
приложения
Может прибавлять команду того же самого названия{*имени*}, потому что группа называет Делает команды
однозначными.
Acad::ErrorStatus
addCommand(
const char* cmdGroupName,
const char* cmdGlobalName,
const char* cmdLocalName,
Adesk::Int32 commandFlags,
AcRxFunctionPtr functionAddr,
AcEdUIContext *UIContext=NULL,
28
int fcode=-1,
HINSTANCE hResourceHandle=NULL);
CmdGroupName
Представление ASCII группы, чтобы прибавить команду к.
Если группа не существует, это создано прежде, чем команда добавлена.
CmdGlobalName
Представление ASCII команды называет, чтобы добавиться. Это название{*имя*} представляет
глобальное или неоттранслированное название{*имя*} (см. “ Глобальная переменная против Местных
Названий{*имен*} Команды ” на странице 42).
CmdLocalName
Представление ASCII команды называет, чтобы добавиться. Это название{*имя*} представляет
местное или оттранслированное название{*имя*}.
CommandFlags
Флажки, связанные с командой. Возможные значения - ACRX_CMD_TRANSPARENT,
ACRX_CMD_MODAL, ACRX_CMD_USEPICKSET, и ACRX_CMD_REDRAW (см. “ Прозрачный против
Модальных Команд ” на странице 42).
FunctionAddr
Адрес функции, которая будет выполнена, когда эта команда вызвана в соответствии с AutoCAD.
UiContext
Входной указатель на AcEdUIContext класс повторного вызова.
Fcode
Введите целочисленный код, назначенный на команду.
ПРИМЕЧАНИЕ, которое строго рекомендует, чтобы все имена команд имели Ваш
зарегистрированный префикс разработчика с четырьмя символами, чтобы избежать возможных конфликтов с
командами в других приложениях. Например, MOVE команда разработчика с префиксом ASDK должна быть
ASDKMOVE.
Использование вашего зарегистрированного префикса разработчика также рекомендуется для имен группы.
Порядок поиска
Когда команда вызвана, стек команды обыскан названием{*именем*} группы, затем названием{*именем*}
команды в пределах группы. Вообще, первая группа зарегистрировалась, будет первый обысканный, но Вы не
можете всегда предсказывать, каков этот заказ{*порядок*} будет. Используйте AcEdCommandStack::
popGroupToTop () функция, чтобы определить, что специфическая группа должна быть обыскана сначала. На
уровне пользователей, опция Group команды ARX позволяет пользователю определять которую группу искать
сначала.
29
Если такие столкновения - не проблема, делая новые команды прозрачные результаты в большей гибкости
использования.
Разблокировка приложения
По умолчанию, приложения блокированы и не могут быть разгружены. Чтобы быть классифицирован как
“незагружаемое” приложение, приложение должно гарантировать, что AutoCAD и другие приложения больше
не обращаются{*относятся*} к любым объектам{*целям*}, или структурирует приложение, определил.
Прежде, чем Вы делаете приложение незагружаемым, быть очень осторожным, что никакие клиентские
приложения не содержат активные указатели на любые объекты{*цели*} в вашем адресном пространстве. Для
списка операций очистки приложение должно исполнить, чтобы быть незагружаемым, см. “ Подготовка к
Разгрузке ” на странице 38.
Если Вы хотите делать ваше приложение незагружаемым, Вы должны сохранить значение pkt параметра,
посланного с AcRx:: kInitAppMsg. Pkt параметр будет использоваться unlockApplication () на. По умолчанию,
прикладная программа блокирована. Если Вы разблокируете приложение, это может быть разгружено.
30
AcRxDynamicLinker::lockApplication(void* pkt) const;
bool
AcRxDynamicLinker::unlockApplication(void* pkt) const;
Загрузка по запросу
Загрузка Запроса - особенность AutoCAD, который автоматически пытается загружать приложение
ObjectARX, которое - не резидент в AutoCAD. Приложения ObjectARX могут быть предназначены для
загрузки в соответствии с AutoCAD под одним или большим количеством следующих обстоятельств:
когда читается чертежный файл, который содержит заказные объекты, созданные отсутствующим
приложением;
когда пользователь или другое приложение выпускает одну из команд отсутствующего приложения;
когда AutoCAD начат;
ОБРАТИТЕ ВНИМАНИЕ, что приложение ObjectARX может быть запрос, загруженный от пути на местной
машине, или, используя адрес Internet.
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R15.0\
ACAD-1:409\
...
AcadLocation:REG_SZ:f:\ACAD2000
Language:REG_SZ:English
ProductName:REG_SZ:AutoCAD Map R15.0
...
31
Клавиша{*ключ*} временной метки также используется, чтобы идентифицировать версию AutoCAD, который в
настоящее время загружен (или версия, которая была наиболее недавно загружена). Эта идентификация
необходима, потому что “текущая” версия AutoCAD сбрасывает информацию в глобальной переменной
HKEY_CLASSES_ROOT раздел системного реестра для его собственного использования, когда это загружено.
Значение CurVer в разделе клавиши{*ключа*} выпуска системного реестра используется, чтобы
идентифицировать текущую версию, например:
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R15.0\
...
CurVer:REG_SZ:ACAD-1:409
Когда AutoCAD пытается требовать загрузку Приложение ObjectArx, это смотрит в разделе системного
реестра, который принадлежит самому последнему выпуску AutoCAD для информации относительно
Приложения ObjectArx. Если это не находит ObjectARX информацию там, это проверяет{*отмечает*} раздел
для предыдущего выпуска AutoCAD, и так далее в обратном заказе{*порядке*}, пока информация не найдена
или информация выпуска AutoCAD истощена.
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\releaseNum\
ACAD-1:LocaleID\
Applications\
ApplicationName\
LoadCtrls:REG_DWORD:acrxAppLoadReason
RegPath:REG_SZ:RegistryPathWhereLoaderIsSpecified
32
0x04 Загружают приложение на обращение команды.
0x08 Загружают приложение по запросу пользователем или другим приложением.
0x10 Не загружают приложение.
Значение в клавише{*ключе*} Loader должно включить полный путь и имя файла модуля, который AutoCAD
должен загрузиться сначала. Модуль загрузчика впоследствии ответствен за загрузку любых других модулей,
которые составляют приложение.
Следующий пример иллюстрирует размещение и типы значения прикладного раздела системного системного
реестра:
\\ HKEY_LOCAL_MACHINE\SOFTWARE\
...
RegistryPathWhereLoaderIsIdentified\
Loader\Module:REG_SZ:DirPathFileName
Name\DescriptiveName:REG_SZ:User Friendly App Name
Commands\GlobalCommandName1:REG_SZ:LocalCommandName1
GlobalCommandName2:REG_SZ:LocalCommandName2
GlobalCommandName3:REG_SZ:LocalCommandName3
GlobalCommandName4:REG_SZ:LocalCommandName4
GlobalCommandName5:REG_SZ:LocalCommandName5
Groups\
GroupName:REG_SZ:GroupName
...
Значение Модуля должно присутствовать, но не используется кроме как метка - заполнитель в системном
реестре. Точно так же Название{*имя*} Приложения Дружественный к пользователю должно присутствовать,
но в настоящее время не используется.
Значение в клавише{*ключе*} Groups может использоваться, чтобы уникально идентифицировать группы
команд приложений ObjectARX и поэтому команды также.
33
DEMANDLOAD системная переменная позволяет пользователю отключать загрузку запроса всех Приложений
ObjectArx, которые имеют системные параметры настройки системного реестра, определяющие загрузку
запроса на обращении команды, и полномочном обнаружении. Это не может заставлять приложение быть
загруженным запросом, если соответствующие системные параметры настройки системного реестра не
существуют.
ОБРАТИТЕ ВНИМАНИЕ, что загрузка Запроса на обнаружении заказных классов будет только
работать с классами, которые получены из AcDbObject, или непосредственно или косвенно.
Как гипотетический пример, давайте предполагать, что AutoCAD читает файл, созданный Приложением
ObjectArx polysamp (изделие{*программа*} PolySamp компании).
1 После чтения чертежного файла, AutoCAD сталкивается с заказными объектами{*целями*}, созданными с
приложением polysamp, и решает, что приложение не загружено.
2 AutoCAD находит, что DEMANDLOAD системная переменная установлена, чтобы допустить
загрузке запроса приложений на полномочном обнаружении, так что это ищет раздел Приложений
AutoCAD системного реестра для polysamp клавиши{*ключа*}.
В пределах этой клавиши{*ключа*}, это находит значение LoadCtrls, которое определяет
условия{*состояния*}, при которых приложение должно быть загружено, и значение RegPath,
которое обеспечивает полный путь системного реестра для polysamp модуля. Этот раздел
системного реестра смотрел бы кое-что вроде этого:
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R15.0\
ACAD-1:409\
Applications\PolyCAD\
LoadCtrls:REG_DWORD:0xd
RegPath:REG_SZ:
\\HKEY_LOCAL_MACHINE\SOFTWARE\PolySampInc\polysamp
3 AutoCAD читает polysamp\Loader клавишу{*ключ*}, чтобы определить каталог, путь, и имя файла модуля,
который будет загружен. Этот раздел каталога смотрел бы кое-что вроде этого:
\\ HKEY_LOCAL_MACHINE\SOFTWARE\
PolySampInc\polysamp\
Loader\MODULE:REG_SZ:c:\polysampinc\arx\polyui.arx
Name\PolySamp:REG_SZ:PolyCad
4 AutoCAD тогда пытается загружать ObjectARX модуль. Если загрузки модуля успешно, AutoCAD прибавляет
маркер{*дескриптор*} приложения к списку прикладных маркеров{*дескрипторов*}, которые будут посланы
kLoadDwgMsg сообщение. AutoCAD тогда подтверждает{*проверяет*}, что приложение было загружено
должным образом, и подтверждает{*проверяет*}, что заказной класс зарегистрирован. Если приложение было
загружено успешно, AutoCAD продолжится
Загружать чертежный файл. Если ObjectARX модуль не может быть загружен, или если все еще не имеется
выполнения класса, доступные, заказные объекты{*цели*} обработаны как proxies, и загрузка продолжается.
\\ HKEY_LOCAL_MACHINE\SOFTWARE\
Autodesk\ ...
...
PolySampInc\polysamp\
Loader\MODULE:REG_SZ:c:\polysampinc\arx\polyui.arx
Name\PolySamp:REG_SZ:PolyCad
34
Commands\
ASDKPOLY:REG_SZ:ASDKPOLY
ASDKDRAGPOLY:REG_SZ:ASDKDRAGPOLY
ASDKPOLYEDIT:REG_SZ:ASDKPOLYEDIT
Groups\
ASDK:REG_SZ:ASDK
...
В этом примере, зарегистрированный префикс разработчика разработчика (ASDK) используется как префикс
для всех команд, чтобы гарантировать, что не будет иметься никакого возможного конфликта с командами
того же самого названия{*имени*} в других приложениях.
Приложение ObjectArx должно также включить соответствующие запросы к acedRegCmds макрокоманде для
загрузки запроса на команде, чтобы работать.
\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R15.0\
ACAD-1:409\
Applications\PolyCAD\
LoadCtrls:REG_DWORD:0x02
RegPath:REG_SZ:
ARX Команда
Следующие разделы описывают команду ARX и ее опции. Начальная подсказка следующие:
? /Load/Unload/Commands/Options: Введите опцию, или нажмите ENTER
? — Приложения Списка
Перечисляет в настоящее время загруженные приложения ARX.
LOAD
Загружает .arx файл, который Вы определяете в стандартном файловом диалоговом окне. Если FILEDIA
установлен в 0, диалоговое окно не отображено, и Вы вводите название{*имя*} файла, чтобы загрузиться в
ответ на следующую подсказку:
Файл расширения{*продления*} Во время выполнения: Введите название{*имя*}
UNLOAD
Разгружает указанную программу ARX. Некоторые приложения не могут быть разгружены. См. “ Разгрузка
Приложения ObjectArx ” на странице 44 для описания того, как программист решает, может ли программа быть
разгружена пользователем с этой командой.
35
Commands
Отображает все названия{*имена*} команды во всех группах команд, зарегистрированных от программ ARX.
Options
Представляет связанные разработчиком опции приложения ARX.
Options (Group/CLasses/Services): Enter an option
Group
Перемещает указанную группу команд, зарегистрированных от приложений ARX, чтобы быть первой группой,
обысканной при решении названий{*имен*} команд AutoCAD. Другие зарегистрированные группы, если
имеется любой, впоследствии обысканы, в том же самом заказе{*порядке*}, как прежде, чем команда ARX
была выполнена.
Заказ{*порядок*} поиска важен только, когда название{*имя*} команды перечислено в множественных группах.
Этот механизм позволяет различным приложениям ARX определять те же самые названия{*имена*} команды
в их собственных отдельных группах команд.
ARX приложения, которые определяют группы, команд должны издать название{*имя*} группы в их
документации.
Группа не предназначена, чтобы быть выбранной пользователем непосредственно. Пользователь определяет,
которая группа обыскана сначала, взаимодействуя со сценарием, который выполняет команду ARX с опцией
Group. Эта возможность обычно внедряется в ключевые сценарии пункта меню. Пользователь выбирает пункт
меню от сценария.
Ключевой сценарий пункта меню выполняет опцию Group, чтобы установить, которая группа обыскана
сначала, давая команды того же самого названия{*имени*} (но вероятно различные функциональные
возможности) от одного прикладного старшинства по командам от другого.
Например, приложения по имени ABC и XYZ Интерьеры определяют группы ABC команд и XYZ,
соответственно. Большинство команд Конструкции ABC названо с терминологией конструкции, в то
время как большинство XYZ команды Интерьеров названо со внутренней областью, украшающей
терминологию, но и приложения определяют команды по имени INVENTORY и ORDERS. При работе
над аспектами конструкции рисунка, пользователь выбирает пункт меню, определенный
Конструкцией ABC, и следующий сценарий выполняется:
ARX
Группа
ABC
Сценарий выталкивает набор команд Construction ABC, чтобы дать этому высший приоритет и
решать INVENTORY к версии Конструкции ABC команды. Позже, когда внутренний проектировщик
работает над рисунком к тому же самому набору загруженных приложений, выбор, ключевой
значок гарантирует, что XYZ команды Интерьеров имеют старшинство.
Classes
Отображает иерархию классов классов C++, полученных из объектов{*целей*}, зарегистрированных в
системе, ли зарегистрированный в соответствии с AutoCAD или в соответствии с программой ARX.
Services
Перечисляет названия{*имена*} всех услуг, зарегистрированных в соответствии с AutoCAD и в
соответствии с загруженными программами ARX.
36
Внешняя функция может быть вызвана функцией AutoLISP, также как в интерактивном режиме. Приложения
ObjectArx не могут вызывать функции AutoLISP. Приложение ObjectArx может отыскивать и устанавливать
значение символов AutoLISP (тип данных символа должен быть распознаваемый к программе C++).
Приложение ObjectArx может определять новую команду AutoCAD с тем же самым C:XXX соглашением как
AutoLISP. Вы вызываете внешнюю функцию, вводя ее название{*имя*} в Приглашении ко вводу команды, без
круглых скобок.
Определение внешней функции заменяет любое предыдущее определение того же самого названия{*имени*}.
Если два Приложения ObjectArx определяют функции с тем же самым названием{*именем*}, функция в
первом приложении, которое будет загружено потеряна; если Вы разгружаете второе приложение, Вы не
можете вызывать{*называть*} двойную функцию.
Обработка ошибок
Примеры в этом руководстве опустили необходимую проверку ошибок, чтобы упростить код. Однако, вы
будете всегда хотеть проверить состояние возвращения и брать соответствующее действие. Следующий
пример показывает соответствующему использованию проверки ошибок для нескольких примеров,
показанных сначала в главе 2, “ Учебник для начинающих Базы данных. ”
Acad::ErrorStatus
createCircle(AcDbObjectId& circleId)
{
circleId = AcDbObjectId::kNull;
AcGePoint3d center(9.0, 3.0, 0.0);
AcGeVector3d normal(0.0, 0.0, 1.0);
AcDbCircle *pCirc = new AcDbCircle(center, normal, 2.0);
if (pCirc == NULL)
return Acad::eOutOfMemory;
AcDbBlockTable *pBlockTable;
Acad::ErrorStatus es =
acdbHostApplicationServices()->workingDatabase()->
getSymbolTable(pBlockTable, AcDb::kForRead);
if (es != Acad::eOk) {
delete pCirc;
return es;
}
AcDbBlockTableRecord *pBlockTableRecord;
es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
if (es != Acad::eOk) {
Acad::ErrorStatus es2 = pBlockTable->close();
if (es2 != Acad::eOk) {
acrx_abort("\nApp X failed to close Block" " Table. Error: %d", acadErrorStatusText(es2));
}
delete pCirc;
return es;
}
es = pBlockTable->close();
if (es != Acad::eOk) {
acrx_abort("\nApp X failed to close Block Table."
" Error: %d", acadErrorStatusText(es));
}
es = pBlockTableRecord->appendAcDbEntity(circleId,
pCirc);
if (es != Acad::eOk) {
Acad::ErrorStatus es2 = pBlockTableRecord->close();
if (es2 != Acad::eOk) {
acrx_abort("\nApp X failed to close"
" Model Space Block Record. Error: %s",
acadErrorStatusText(es2));
}
delete pCirc;
return es;
}
es = pBlockTableRecord->close();
if (es != Acad::eOk) {
acrx_abort("\nApp X failed to close"
" Model Space Block Record. Error: %d",
acadErrorStatusText(es));
}
es = pCirc->close();
if (es != Acad::eOk) {
acrx_abort("\nApp X failed to"
" close circle entity. Error: %d",
acadErrorStatusText(es));
}
return es;
}
Acad::ErrorStatus
37
createNewLayer()
{
AcDbLayerTableRecord *pLayerTableRecord
= new AcDbLayerTableRecord;
if (pLayerTableRecord == NULL)
return Acad::eOutOfMemory;
Acad::ErrorStatus es
= pLayerTableRecord->setName("ASDK_MYLAYER");
if (es != Acad::eOk) {
delete pLayerTableRecord;
return es;
}
AcDbLayerTable *pLayerTable;
es = acdbHostApplicationServices()->workingDatabase()->
getSymbolTable(pLayerTable, AcDb::kForWrite);
if (es != Acad::eOk) {
delete pLayerTableRecord;
return es;
}
// The linetype object ID default is 0, which is
// not a valid ID. Therefore, it must be set to a
// valid ID, the CONTINUOUS linetype.
// Other data members have valid defaults, so
// they can be left alone.
//
AcDbLinetypeTable *pLinetypeTbl;
es = acdbHostApplicationServices()->workingDatabase()->
getSymbolTable(pLinetypeTbl, AcDb::kForRead);
if (es != Acad::eOk) {
delete pLayerTableRecord;
es = pLayerTable->close();
if (es != Acad::eOk) {
acrx_abort("\nApp X failed to close Layer"
" Table. Error: %d",
acadErrorStatusText(es));
}
return es;
}
AcDbObjectId ltypeObjId;
es = pLinetypeTbl->getAt("CONTINUOUS", ltypeObjId);
if (es != Acad::eOk) {
delete pLayerTableRecord;
es = pLayerTable->close();
if (es != Acad::eOk) {
acrx_abort("\nApp X failed to close Layer"
" Table. Error: %d",
acadErrorStatusText(es));
}
return es;
}
pLayerTableRecord->setLinetypeObjectId(ltypeObjId);
es = pLayerTable->add(pLayerTableRecord);
if (es != Acad::eOk) {
Acad::ErrorStatus es2 = pLayerTable->close();
if (es2 != Acad::eOk) {
acrx_abort("\nApp X failed to close Layer"
" Table. Error: %d",
acadErrorStatusText(es2));
}
delete pLayerTableRecord;
return es;
}
es = pLayerTable->close();
if (es != Acad::eOk) {
acrx_abort("\nApp X failed to close Layer"
" Table. Error: %d",
acadErrorStatusText(es));
}
es = pLayerTableRecord->close();
if (es != Acad::eOk) {
acrx_abort("\nApp X failed to close Layer"
" Table Record. Error: %d",
acadErrorStatusText(es));
}
return es;
}
38
Глава 4. Операции базы данных рисунка
Эта глава описывает основной протокол базы данных, включая, как создать базу данных, как
читать в чертежном файле, и как сохранить базу данных. Wblock и операции вставки также
описаны здесь. Для более детальной информации относительно deepClone и wblock операций, см.
главу 18, при Глубоко Имитации. ”
Начальная База данных
Создание и Начальная загрузка Базы данных
Сохранение Базы данных
wblock Операция
Вставка Базы данных
Установка Текущих Значений Базы данных
Пример Операций Базы данных
Длинные транзакции
Внешние ссылки
Индексы и Фильтры
Рисунок Итоговой Информации
Из прошлого, сохраненного программным обеспечением Autodesk
Некоторые из таблиц идентификаторов уже содержат один или большее количество записей. Таблица
уровня содержит уровень 0. Блочная таблица первоначально содержит три записи: *MODEL_SPACE,
*PAPER_SPACE, и *PAPER_SPACE0. Linetype таблица всегда имеет НЕПРЕРЫВНЫЙ, BY_LAYER, и
BY_BLOCK linetype. Таблица зарегистрированных приложений всегда имеет ACAD. Текстовая таблица
стиля всегда имеет СТАНДАРТНЫЙ.
словарь имен объектов. Когда база данных создана, этот словарь уже содержит два словаря баз
данных: словарь ГРУППЫ и MLINE словарь стиля. В пределах MLINE словаря стиля, СТАНДАРТНЫЙ
стиль - всегда имеется.
N фиксированный набор переменных заголовка. (Они - не объекты базы данных.)
AcadErrorStatus
AcDbDatabase::readDwgFile(char* fileName);
Если Вы получаете любой из кодов ошибки слежения, Вы вероятно хотите возвратить рисунок к стандарту,
AutoCAD возвращает механизм, обеспеченный интерфейсом пользователя:
KDwgNeedsRecovery
KDwgCRCDoesNotMatch
KDwgSentinelDoesNotMatch
KdwgObjectImproperlyRead
39
Acad:: ErrorStatus
AcDbDatabase:: saveAs (char* имя файла);
Имя файла может быть путь к местному файлу, или адресу Internet.
Acad::ErrorStatus
acdbSaveAsR13(
AcDbDatabase* pDb,
const char* fileName);
40
Acad::ErrorStatus
acdbSaveAsR14(
AcDbDatabase* pDb,
const char* fileName);
Обе функции принимают указатель базы данных и имя файла, и выписывают рисунок в Выпуске AutoCAD 13
или Выпускают 14 формата DWG, соответственно.
Операция Wblock
AcDbDatabase класс содержит перегруженный wblock () функция с тремя формами, которые соответствуют
опциям команды WBLOCK AutoCAD.
Acad:: ErrorStatus
AcDbDatabase::wblock(AcDbDatabase*& NewDb);
Эта функция создает новую базу данных от вызванной базы данных ("this").
Любые неупомянутые символы во входной базе данных опущены в новой базе данных (который делает новую
базу данных потенциально уборщиком и меньший чем оригинал). Однако, это не заботится о копировании
определенных приложением объектов, чей монопольное использование внедрено в названном объектном
словаре. Вы должны передать{*переместить*} данные прикладной программы от исходной базы данных до
целевой базы данных, используя AcEditorReactor функции уведомления.
Acad:: ErrorStatus
AcDbDatabase::wblock(AcDbDatabase*& NewDb,
AcDbObjectId recordId);
Acad::ErrorStatus
AcDbDatabase::wblock(AcDbDatabase*& newDb,
const AcDbObjectIdArray& idArray,
const AcGePoint3d* point);
Эта функция создает новую базу данных, которая включает объекты, указанные в idArray параметре.
Объекты, которые могут быть в образцовых пространственных или бумажных пространственных блочных
отчетах{*записях*} таблицы входной базы данных, помещены в образцовое пространство{*пробел*} новой
базы данных. Также включенный в новую базу данных - объекты, принадлежащие или упомянутый теми
объектами, также как владельцами тех объектов. Указанный пункт{*точка*} - пункт{*точка*} начала координат,
во внешних координатах, для нового рисунка (то есть это - арифметическая запятая вставки в образцовом
пространстве{*пробеле*} новой базы данных).
41
ОБРАТИТЕ ВНИМАНИЕ На INSERT() функции исполняют глубоко имитацию, как описано в главе 18, при
Глубоко Имитации. ”
Если конфликты возникают, когда исходные и целевые базы данных объединяются (например, если обе базы
данных имеют то же самое название{*имя*} linetype), AutoCAD использует версию в целевой базе данных.
Следующая функция эквивалентна стандарту, тянущему{*рисующему*} команду INSERT:
Acad:: ErrorStatus
AcDbDatabase::insert(AcDbObjectId& BlockId,
const char* pBlockName,
AcDbDatabase* pDb);
Эта функция копирует объекты с образцового пространства{*пробела*} входной базы данных (pDb) в
указанный блочный отчет{*запись*} таблицы (pBlockName) и возвращает блок ID нового блочного
отчета{*записи*} таблицы (blockId). Приложение должно тогда создать ссылку{*справочники*} к блочной
таблице, делают запись и прибавляют это к базе данных.
Следующая функция эквивалентна команде AutoCAD:
Acad:: ErrorStatus
AcDbDatabase::insert (const AcGeMatrix3d& Xform,
AcDbDatabase* pDb);
Эта функция копирует объекты с образцового пространства{*пробела*} входной базы данных (pDb) и
помещает их в текущее пространство{*пробел*} новой базы данных (бумажное пространственное или
образцовое пространство{*пробел*}), применяя указанное преобразование (xform) к объектам.
Acad::ErrorStatus
AcDbDatabase::setCecolor(const AcCmColor& color);
Acad::ErrorStatus
AcDbDatabase::setCeltype(AcDbObjectId);
Acad::ErrorStatus
AcDbDatabase::setLtscale(double);
Acad::ErrorStatus
42
AcDbDatabase::setCeltscale(double);
Acad::ErrorStatus
AcDbDatabase::setPsltscale(Adesk::Boolean)
Adesk::Boolean AcDbDatabase::psltscale() const;
Acad::ErrorStatus
AcDbDatabase::setClayer(AcDbObjectId);
void
createDwg()
{
AcDbDatabase *pDb = new AcDbDatabase();
AcDbBlockTable *pBtbl;
pDb->getSymbolTable(pBtbl, AcDb::kForRead);
AcDbBlockTableRecord *pBtblRcd;
pBtbl->getAt(ACDB_MODEL_SPACE, pBtblRcd,
AcDb::kForWrite);
pBtbl->close();
AcDbCircle *pCir1 = new AcDbCircle(AcGePoint3d(1,1,1),
AcGeVector3d(0,0,1),
1.0),
*pCir2 = new AcDbCircle(AcGePoint3d(4,4,4),
AcGeVector3d(0,0,1),
2.0);
pBtblRcd->appendAcDbEntity(pCir1);
pCir1->close();
pBtblRcd->appendAcDbEntity(pCir2);
pCir2->close();
pBtblRcd->close();
// AcDbDatabase::saveAs() does not automatically
// append a DWG file extension, so it
// must be specified.
//
pDb->saveAs("test1.dwg");
delete pDb;
}
void
readDwg()
{
// Set constructor parameter to kFalse so that the
// database will be constructed empty. This way only
// what is read in will be in the database.
//
AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);
// The AcDbDatabase::readDwgFile() function
// automatically appends a DWG extension if it is not
// specified in the filename parameter.
//
pDb->readDwgFile("test1.dwg");
// Open the model space block table record.
//
AcDbBlockTable *pBlkTbl;
pDb->getSymbolTable(pBlkTbl, AcDb::kForRead);
AcDbBlockTableRecord *pBlkTblRcd;
pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd,
AcDb::kForRead);
pBlkTbl->close();
43
AcDbBlockTableRecordIterator *pBlkTblRcdItr;
pBlkTblRcd->newIterator(pBlkTblRcdItr);
AcDbEntity *pEnt;
for (pBlkTblRcdItr->start(); !pBlkTblRcdItr->done(); pBlkTblRcdItr->step())
{
pBlkTblRcdItr->getEntity(pEnt,
AcDb::kForRead);
acutPrintf("classname: %s\n",
(pEnt->isA())->name());
pEnt->close();
}
pBlkTblRcd->close();
delete pBlkTblRcdItr;
delete pDb;
}
Длинные транзакции
Длинные транзакции используются, чтобы поддержать Особенность редактирования Ссылки{*справочников*}
AutoCAD и очень полезны для Приложений ObjectArx. Эти классы и функции обеспечивают схему
приложений, чтобы проверить объекты для редактирования и проверяют{*отмечают*} их назад в к их
первоначальному местоположению. Эта операция заменяет первоначальные объекты отредактированными.
Имеются три типа длинного операционного контроля:
От нормального блока в пределах того же самого рисунка
От внешней ссылки (таблица перекрестных ссылок) рисунка
От несвязанной, временной базы данных
44
Отношения между DeepCloneTypes и DuplicateRecordCloning для Различные команды и функции
void
refEditApiExample()
{
AcDbObjectId transId;
AcDbDatabase* pDb;
char *fname;
struct resbuf *rb;
// Get a dwg file from the user.
//
rb = acutNewRb(RTSTR);
acedGetFileD("Pick a drawing", NULL, "dwg", 0, rb);
fname = (char*)acad_malloc(strlen(rb->resval.rstring) + 1);
strcpy(fname, rb->resval.rstring);
acutRelRb(rb);
// Open the dwg file.
//
pDb = new AcDbDatabase(Adesk::kFalse);
pDb->readDwgFile(fname);
// Get the block table and then the model space record.
//
AcDbBlockTable *pBlockTable;
pDb->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pOtherMsBtr;
pBlockTable->getAt(ACDB_MODEL_SPACE, pOtherMsBtr,
AcDb::kForRead);
pBlockTable->close();
// Create an iterator
//
AcDbBlockTableRecordIterator *pIter;
pOtherMsBtr->newIterator(pIter);
// Set up an object ID array.
//
AcDbObjectIdArray objIdArray;
// Iterate over the model space BTR. Look specifically
// for Lines and append their object ID to the array.
//
for (pIter->start(); !pIter->done(); pIter->step()) {
AcDbEntity *pEntity;
pIter->getEntity(pEntity, AcDb::kForRead);
// Look for only AcDbLine objects and add them to the
// objectId array.
//
if (pEntity->isKindOf(AcDbLine::desc())) {
objIdArray.append(pEntity->objectId());
}
pEntity->close();
}
delete pIter;
pOtherMsBtr->close();
// Now get the current database and the object ID for the
// current database’s model space BTR.
45
//
AcDbBlockTable *pThisBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pThisBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pThisMsBtr;
pThisBlockTable->getAt(ACDB_MODEL_SPACE, pThisMsBtr,
AcDb::kForWrite);
pThisBlockTable->close();
AcDbObjectId id = pThisMsBtr->objectId();
pThisMsBtr->close();
// Create the long transaction. This will check all the entities
// out of the external database.
acapLongTransactionManagerPtr()->checkOut(transId,
objIdArray, id);
// Now modify the color of these entities.
//
int colorIndex;
acedGetInt("\nEnter color number to change entities to: ",
&colorIndex);
AcDbObject* pObj;
if (acdbOpenObject(pObj, transId, AcDb::kForRead) == Acad::eOk)
{
// Get a pointer to the transaction
//
AcDbLongTransaction* pLongTrans =
AcDbLongTransaction::cast(pObj);
if (pLongTrans != NULL) {
// Get a work set iterator
//
AcDbLongTransWorkSetIterator* pWorkSetIter =
pLongTrans->newWorkSetIterator();
// Iterate over the entities in the work set
// and change the color.
for (pWorkSetIter->start(); !pWorkSetIter->done(); pWorkSetIter->step()) {
AcDbEntity *pEntity;
acdbOpenAcDbEntity(pEntity, pWorkSetIter->objectId(),
AcDb::kForWrite);
pEntity->setColorIndex(colorIndex);
pEntity->close();
}
delete pWorkSetIter;
}
pObj->close();
}
// Pause just to see the change.
//
char str[132];
acedGetString(0, "\nNote the new colors. Press return to \
check the objects back in to the original database", str);
// Check the entities back in to the orginal database.
//
acapLongTransactionManagerPtr()->checkIn(transId);
// Save the original database, since we made changes
//
pDb->saveAs(fname);
// Close and Delete the database.
//
delete pDb;
pDb = NULL;
acad_free(fname);
}
Внешние ссылки
Внешние ссылки (таблицы перекрестных ссылок) могут быть созданы и управляться через несколько
глобальных функций. Эти глобальные функции подражают возможностям команды XREF AutoCAD. Функции,
обеспеченные
acedXrefAttach ()
acedXrefOverlay ()
acedXrefUnload ()
acedXrefDetach ()
acedXrefReload ()
acedXrefBind ()
acedXrefXBind ()
46
acedXrefCreateBlockname ()
acedXrefReload ()
Для информации относительно команды XREF AutoCAD, см. Руководство программиста AutoCAD.
Главное, программирующее соображение{*рассмотрение*} относительно таблиц перекрестных ссылок - то,
что, для каждой таблицы перекрестных ссылок, который приложен к рисунку, отдельная база данных создана,
чтобы представить рисунок, содержащий таблицу перекрестных ссылок. Блочный отчет{*запись*} таблицы в
основном рисунок содержит название{*имя*} внешнего рисунка и указывать на объекты образцового
пространства{*пробела*} внешне упомянутого рисунка. База данных таблицы перекрестных ссылок также
содержит другие блочные отчеты{*записи*} таблицы и входы таблицы идентификаторов, требуемые, чтобы
решить все ссылки{*справочники*} от основного блочного отчета{*записи*} таблицы (уровни, linetypes, и так
далее).
Вы можете создавать редактора реактор, как описано в главе 15, “Уведомлении”, контролировать события
таблицы перекрестных ссылок. AcEditorReactor класс обеспечивает следующие реакторные функции
повторного вызова:
beginAttach ()
otherAttach ()
abortAttach ()
endAttach ()
redirected ()
comandeered ()
При использовании этих функций, будьте внимательным, чтобы обратить внимание, которая база данных
возвращается. Также, знайте, что рисунок таблицы перекрестных ссылок может самостоятельно содержать
таблицы перекрестных ссылок к дополнительным рисункам. Для получения дополнительной информации на
AcEditorReactor классе, см. ObjectARX Ссылку{*справочники*}.
Объекты Таблицы перекрестных ссылок в рисунке могут изменяться, но они не могут быть сохранены к
первоначальному рисунку таблицы перекрестных ссылок (рисунок оригинала только для чтения).
47
загружено от ее файла. Таблица перекрестных ссылок - тогда в условии{*состоянии*}, где это
может изменяться и сохранен назад к файлу. После запроса этой функции, рисунок главного
компьютера - больше не в правильном{*допустимом*} государстве{*состоянии*} для
перегенерального или для любых модификаций команды таблицы перекрестных ссылок или
перезагрузок. Модификации базы данных, сохраните{*экономьте*} назад, и
restoreForwardingXrefSymbols () функция должна назваться прежде, чем что - нибудь, что могло бы
позволять перегенеральный.
AcDbDatabase::restoreForwardingXrefSymbols () Функция
RestoreForwardingXrefSymbols () функция восстанавливает таблицу перекрестных ссылок назад к
правильному{*допустимому*}, приложенное государство{*состояние*}. Мало того, что это
восстанавливает оригинал решенные символы, но и это также разыскивает недавно добавленные
символы и решает их также. RestoreForwardingXrefSymbols () функция не может обрабатывать
недавно добавленный, вложенные отчеты{*записи*} таблицы блока таблицы перекрестных ссылок,
если они уже не существуют и решены в ведущем рисунке.
Индексы и Фильтры
Индекс и классы фильтра и функции обеспечивают схему приложений, чтобы определить заказные индексы и
заказную фильтрацию блочных данных. Приложение может определять его создания заказных ИС AcDbFilter,
AcDbIndex, и AcDbFilteredBlockIterator. Это регистрирует AcDbFilter с блочной ссылкой{*справочниками*} через
AcIndexFilterManager:: addFilter (), и AcDbIndex с соответствующим блочным отчетом{*записью*} таблицы
через AcIndexFilterManager:: addIndex (). После того, как это, regens таблиц перекрестных ссылок и блоков
будет уважать запрос, определенный AcDbFilter, и использовать AcDbFilteredBlockIterator, чтобы решить то,
что объект IDs будет обработан в течение перегенерального. Индексы будут сохраняться современными
через или приложением, явно вызывающим AcIndexFilterManager:: updateIndexes (), или приложение может
полагаться на AutoCAD, сохраняют{*экономят*} операцию, вызывающую AcIndexFilterManager:: updateIndexes
() на сохраняемом AcDbDatabase.
AcDbIndex:: rebuildFull () или AcDbIndex:: rebuildModified () вызывается в течение
AcIndexFilterManager:: updateIndexes () запрос.
Текущее использование схемы индексации в AutoCAD - быстрая загрузка запроса подрезанных таблиц
перекрестных ссылок. Пространственный индекс (объект AcDbSpatialIndex) сохранен в рисунке refed. Объект
AcDbSpatialFilter определяет том{*объем*} зажима блочной ссылки{*справочников*} к таблице перекрестных
ссылок в ведущем рисунке. Когда загрузка запроса включена для таблицы перекрестных ссылок,
пространственный том{*объем*} фильтра используется, чтобы пересечь данные таблицы перекрестных
ссылок через пространственный индекс, чтобы к странице в от DWG файла только те объекты, чей графика
пересекает том{*объем*} зажима.
Эти классы и функции обеспечивают интерфейс для:
N Модифицирующие индексы
N Добавление и удаление индексов, чтобы блокировать отчеты{*записи*} таблицы
N Добавление и удаление фильтров, чтобы блокировать ссылки{*справочники*}
N Запрос для индексов от блочных отчетов{*записей*} таблицы
N Запрос для фильтров от блочных ссылок{*справочников*}
N Выполняющий итерации через блокируют отчеты{*записи*} таблицы и посещение только
подмножество объектов
Основные классы и вовлеченные функции
N AcDbIndexFilterManager namespace
N AcDbIndex класс
N AcDbFilter класс
N AcDbFilteredBlockIterator класс
48
N AcDbCompositeFilteredBlockIterator класс
AcDbIndexFilterManager Namespace
AcDbIndexFilterManager namespace - коллекция функций, который обеспечивает индекс и доступ
фильтра и эксплуатационные функциональные возможности.
AcDbIndex Класс
AcDbIndex класс - базовый класс для всех индексных объектов. AcDbSpatialIndex и AcDbLayerIndex
происходят от этого класса.
Хранение индекса современный достигнуто через AcDbIndexFilterManager:: updateIndexes () функциональные
запросы, явно вызываемые (или приложением или AutoCAD).
AcDbFilteredBlockIterator будет служить как средства, чтобы посетить весь AcDbObjectIds, которые
являются “нажатиями” от запроса, определенного AcDbFilter, пропускал{*прошел*} к его
конструктору. Например, в пространственном индексном случае{*регистре*}, образец объекта
AcDbSpatialFilter прошел к newIterator () метод определит область{*регион*} запроса. Объект
AcDbSpatialIndex, через его newIterator () метод, обеспечит AcDbSpatialIndexIterator, который
возвратит объект IDs, которые соответствуют объектам, которые соответствуют в пределах
тома{*объема*} запроса.
AcDbFilter класс
AcDbFilter класс, как предполагается, определяет “запрос”. Это обеспечивает “клавишу”{*“ключ”*} к
AcDbCompositeFilteredBlockIterator, для которого соответствующий индекс получен через indexClass
() метод.
AcDbFilteredBlockIterator Класс
AcDbFilteredBlockIterator класс обеспечивает метод обработать “запрос” на индексе. Это
используется AcDbCompositeFilteredBlockIterator.
AcDbCompositeFilteredBlockIterator Класс
AcDbCompositeFilteredBlockIterator класс обеспечивает замену к нормальной блочной итерации.
Обеспечивая список фильтра в init () метод, объект AcDbCompositeFilteredBlockIterator ищет
передачу AcDbIndex полученные объекты через AcDbFilter:: indexClass () метод, и создает объекты
AcDbFilteredBlockIterator. Если совпадение -to-date indexClass () объекты не доступны, это создает
AcDbFilteredBlockIterator через AcDbFilter:: newIterator () метод. Это тогда заказывает композицию
объектов AcDbFilteredBlockIterator, основанных на AcDbFilteredBlockIterator:: estimatedHits () и
AcDbFilteredBlockIterator::buffersForComposition () методы. Коллекция фильтров - конъюнкция
условий{*состояний*}. Это означает, что объект ID выводится от iterator только, если бы вводы ()
метод каждого фильтра приняли бы объект ID.
AcDbDatabaseSummaryInfo Класс
AcDbDatabaseSummaryInfo класс формирует набор символьных строк, которые могут
использоваться, чтобы прибавить дополнительную информацию к DWG файлу. Максимальная
длина этих строк - 511 символов. Эта информация сохранена и восстановлена{*отыскана*} в
объекте Summary Information с определенными методами для каждого информационного поля.
Предопределенные поля
N Заголовок
N Тема
N Автор
N Ключевые слова
49
N Комментарии
N Последний{*прошлый*} сохраненный
N номер Пересмотра
N ядро Гиперсвязи
Вы можете создавать ваши собственные заказные поля в дополнение к предопределенным полям.
Эти заказные поля сохранены в списке, и Вы можете управлять заказными полями или их
названием{*именем*} (или клавиша{*ключ*}) или позиция (индекс) в списке. Заказные поля индексированы,
начинаясь в 1, и не имеется никакого предела числу полей, которые Вы можете создавать.
AcDbSummaryInfoReactor Класс
Этот класс обеспечивает реактор, чтобы сообщить, изменена{*заменена ли*} итоговая информация.
AcDbSummaryInfoManager Класс
AcDbSummaryInfoManager класс организовывает итоговые информационные реакторы, с методами
прибавлять и удалить реакторы, и посылать уведомление, что итоговая информация изменилась.
Acad:: ErrorStatus
AcdbPutSummaryInfo (
Константа AcDbDatabaseSummaryInfo* pInfo);
AcDbSummaryInfoManager*
AcdbGetSummaryInfoManager ();
50
редактирования, от создания до стирания AcDbDatabase, в котором объект постоянно находится.
Открытые функции берут объект ID как параметр и возвращают указатель на объект AcDbObject.
Этот указатель правилен, пока объект не закрыт, как показано в следующем рисунке.
Acad::ErrorStatus
AcDbDatabase::acdbOpenObject(AcDbObject*& obj,
AcDbObjectId id,
AcDb::OpenMode mode,
Adesk::Boolean
openErasedObject =
Adesk::kFalse);
Acad::ErrorStatus
getAcDbObjectId(AcDbObjectId& retId,
Adesk::Boolean createIfNotFound,
const AcDbHandle& objHandle,
Adesk::UInt32 xRefId=0);
AcDbObject* pObject;
AcDbHandle handle;
pObject->getAcDbHandle(handle);
ОБРАТИТЕ ВНИМАНИЕ Всякий раз, когда объект базы данных открыт, это должно быть закрыто в
самой ранней возможной возможности. Вы можете использовать AcDbObject:: близко () функция,
чтобы закрыть объект базы данных.
Вообще, Вы получаете объект через выбор, и это возвращено в форме ads_name. Вы тогда
должны обменять ads_name на AcDbObjectId и открывать это. Следующая функция демонстрирует
этот процесс:
AcDbEntity*
selectEntity(AcDbObjectId& eId, AcDb::OpenMode openMode)
{
ads_name en;
ads_point pt;
acedEntSel("\nSelect an entity: ", en, pt);
51
// Exchange the ads_name for an object ID.
//
acdbGetObjectId(eId, en);
AcDbEntity * pEnt;
acdbOpenObject(pEnt, eId, openMode);
return pEnt;
}
Следующая таблица показывает возвращенным кодам ошибки, когда Вы пытаетесь открывать объект в
различных режимах, и объект уже открытый.
Удаление объекта
Когда Вы создаете образец объекта AcDbObject с намерением добавления в конец этого к базе
данных, используете AcDbObject:: новый () функция. Когда объект сначала создан и еще не был
добавлен к базе данных, Вы можете удалять это. Однако, как только объект был добавлен к базе
данных, Вы не можете удалять это; AutoCAD управляет стиранием всех объектов резидента базы.
52
Каждая таблица идентификаторов имеет специфический тип отчета{*записи*} таблицы
идентификаторов.
объект AcDbDictionary может иметь любой объект AcDbObject.
объект Any AcDbObject может иметь словарь расширения{*продления*}; объект имеет его
словарь расширения{*продления*}.
Расширенные Данные
Расширенные{*продленные*} данные (xdata) созданы приложениями, написанными с ObjectARX или
AutoLISP и могут быть добавлены к любому объекту. Xdata состоит из списка связей resbufs, используемого
приложением. (AutoCAD обслуживает{*поддерживает*} информацию, но не использует это.) данные связаны с
кодом группы DXF в диапазоне от 1000 до 1071.
Этот механизм пространствено - эффективен и может быть полезен для добавления легких данных к объекту.
Однако, xdata ограничен 16КБ и существующим набором кодов группы DXF и напечатает.
Для более детального описания xdata, см. Руководство Настройки AutoCAD.
Используйте AcDbObject:: xData () функция, чтобы получить resbuf цепочку, содержащую копию
xdata для объекта:
virtual resbuf*
AcDbObject::xData(const char* regappName = NULL) const;
Следующий пример использует xData () функция, чтобы получить xdata для выбранного объекта и
затем печатает xdata на экран. Это тогда прибавляет строку (testrun) к xdata и называет setXdata ()
функцией, чтобы изменить xdata объекта. Этот пример также иллюстрирует использование
upgradeOpen () и downgradeOpen () функции.
// Эта функция называет selectObject () функцией, чтобы позволить
// пользователю выбирать объект; тогда это обращается к xdata объекта
// и посылает список printList () функцию, которая перечисляет значения resval и restype.
//
void
printXdata()
{
// Select and open an object.
//
AcDbObject *pObj;
if ((pObj = selectObject(AcDb::kForRead)) == NULL) {
return;
}
// Get the application name for the xdata.
//
char appname[133];
if (acedGetString(NULL,
"\nEnter the desired Xdata application name: ",
appname) != RTNORM)
{
return;
}
// Get the xdata for the application name.
//
struct resbuf *pRb;
pRb = pObj->xData(appname);
53
if (pRb != NULL) {
// Print the existing xdata if any is present.
// Notice that there is no -3 group, as there is in
// LISP. This is ONLY the xdata, so
// the -3 xdata-start marker isn’t needed.
//
printList(pRb);
acutRelRb(pRb);
} else {
acutPrintf("\nNo xdata for this appname");
}
pObj->close();
}
void
addXdata()
{
AcDbObject* pObj = selectObject(AcDb::kForRead);
if (!pObj) {
acutPrintf("Error selecting object\n");
return;
}
// Get the application name and string to be added to
// xdata.
//
char appName[132], resString[200];
appName[0] = resString[0] = ’\0’;
acedGetString(NULL, "Enter application name: ",
appName);
acedGetString(NULL, "Enter string to be added: ",
resString);
struct resbuf *pRb, *pTemp;
pRb = pObj->xData(appName);
if (pRb != NULL) {
// If xdata is present, then walk to the
// end of the list.
//
for (pTemp = pRb; pTemp->rbnext != NULL; pTemp = pTemp->rbnext)
{;}
} else {
// If xdata is not present, register the application
// and add appName to the first resbuf in the list.
// Notice that there is no -3 group as there is in
// AutoLISP. This is ONLY the xdata so
// the -3 xdata-start marker isn’t needed.
//
acdbRegApp(appName);
pRb = acutNewRb(AcDb::kDxfRegAppName);
pTemp = pRb;
pTemp->resval.rstring
= (char*) malloc(strlen(appName) + 1);
strcpy(pTemp->resval.rstring, appName);
}
// Add user-specified string to the xdata.
//
pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString);
pTemp = pTemp->rbnext;
pTemp->resval.rstring
= (char*) malloc(strlen(resString) + 1);
strcpy(pTemp->resval.rstring, resString);
// The following code shows the use of upgradeOpen()
// to change the entity from read to write.
//
pObj->upgradeOpen();
pObj->setXData(pRb);
pObj->close();
acutRelRb(pRb);
}
Словарь Расширения
Каждый объект может иметь словарь расширения{*продления*}, который может содержать
произвольный набор объектов AcDbObject. При использовании этого механизма, несколько
приложений могут прикреплять данные к тому же самому объекту. Словарь
расширения{*продления*} требует более верхний чем xdata, но это также обеспечивает более
гибкий механизм более высокой способностью{*вместимостью*} для добавляющихся данных.
54
Для примера использования словаря расширения{*продления*}, чтобы прикрепить произвольную
строку к любому AcDbObject, см. программу edinvent в каталоге выборок.
void
createXrecord()
{
AcDbXrecord *pXrec = new AcDbXrecord;
AcDbObject *pObj;
AcDbObjectId dictObjId, xrecObjId;
AcDbDictionary* pDict;
pObj = selectObject(AcDb::kForWrite);
if (pObj == NULL) {
return;
}
// Try to create an extension dictionary for this
// object. If the extension dictionary already exists,
// this will be a no-op.
//
pObj->createExtensionDictionary();
// Get the object ID of the extension dictionary for the
// selected object.
//
dictObjId = pObj->extensionDictionary();
pObj->close();
// Open the extension dictionary and add the new
// xrecord to it.
//
acdbOpenObject(pDict, dictObjId, AcDb::kForWrite);
pDict->setAt("ASDK_XREC1", pXrec, xrecObjId);
pDict->close();
// Create a resbuf list to add to the xrecord.
//
struct resbuf* head;
ads_point testpt = {1.0, 2.0, 0.0};
head = acutBuildList(AcDb::kDxfText,
"This is a test Xrecord list",
AcDb::kDxfXCoord, testpt,
AcDb::kDxfReal, 3.14159,
AcDb::kDxfAngle, 3.14159,
AcDb::kDxfColor, 1,
AcDb::kDxfInt16, 180,
0);
// Add the data list to the xrecord. Notice that this
// member function takes a reference to a resbuf NOT a
// pointer to a resbuf, so you must dereference the
// pointer before sending it.
//
pXrec->setFromRbChain(*head);
pXrec->close();
acutRelRb(head);
}
// The listXrecord() function gets the xrecord associated with the
// key "ASDK_XREC1" and lists out its contents by passing the resbuf
// list to the function printList().
//
void
listXrecord()
{
AcDbObject *pObj;
AcDbXrecord *pXrec;
AcDbObjectId dictObjId;
AcDbDictionary *pDict;
pObj = selectObject(AcDb::kForRead);
if (pObj == NULL) {
return;
}
// Get the object ID of the object’s extension dictionary.
//
dictObjId = pObj->extensionDictionary();
pObj->close();
// Open the extension dictionary and get the xrecord
// associated with the key ASDK_XREC1.
//
acdbOpenObject(pDict, dictObjId, AcDb::kForRead);
55
pDict->getAt("ASDK_XREC1", (AcDbObject*&)pXrec,
AcDb::kForRead);
pDict->close();
// Get the xrecord’s data list and then close the xrecord.
//
struct resbuf *pRbList;
pXrec->rbChain(&pRbList);
pXrec->close();
printList(pRbList);
acutRelRb(pRbList);
}
int
createXrecord()
{
struct resbuf *pXrec, *pEnt, *pDict, *pTemp, *pTemp2;
ads_point dummy, testpt = {1.0, 2.0, 0.0};
ads_name xrecname, ename, extDict = {0L, 0L};
// Have the user select an entity. Then get its data.
//
if (acedEntSel("\nselect entity: ", ename, dummy) != RTNORM)
{
acutPrintf("\nNothing selected");
acedRetVoid();
return RTNORM;
}
pEnt = acdbEntGet(ename);
// Now check to see if the entity already has an
// extension dictionary.
//
for (pTemp = pEnt; pTemp->rbnext != NULL; pTemp = pTemp->rbnext)
{
if (pTemp->restype == 102) {
if (!strcmp("{ACAD_XDICTIONARY", pTemp->resval.rstring))
{
ads_name_set(pTemp->rbnext->resval.rlname, extDict);
break;
}
}
}
// If no extension dictionary exists, add one.
//
if (extDict[0] == 0L) {
pDict = acutBuildList(RTDXF0, "DICTIONARY", 100,
"AcDbDictionary", 0);
acdbEntMakeX(pDict, extDict);
acutRelRb(pDict);
pDict = acutBuildList(102, "{ACAD_XDICTIONARY", 360,
extDict, 102, "}", 0);
for (pTemp = pEnt; pTemp->rbnext->restype != 100; pTemp = pTemp->rbnext)
{;}
for (pTemp2 = pDict; pTemp2->rbnext != NULL; pTemp2 = pTemp2->rbnext)
{;}
pTemp2->rbnext = pTemp->rbnext;
pTemp->rbnext = pDict;
acdbEntMod(pEnt);
acutRelRb(pEnt);
}
// At this point the entity has an extension dictionary.
// Create a resbuf list of the xrecord’s entity information
// and data.
//
pXrec = acutBuildList(RTDXF0, "XRECORD",
100, "AcDbXrecord",
1, "This is a test Xrecord list", //AcDb::kDxfText
10, testpt, //AcDb::kDxfXCoord
40, 3.14159, //AcDb::kDxfReal
50, 3.14159, //AcDb::kDxfAngle
60, 1, //AcDb::kDxfColor
70, 180, //AcDb::kDxfInt16
0);
// Create the xrecord with no owner set. The xrecord’s
// new entity name will be placed into the xrecname
56
// argument.
//
acdbEntMakeX (pXrec, xrecname);
acutRelRb (pXrec);
// Set the xrecord’s owner to the extension dictionary
//
acdbDictAdd(extDict, "ASDK_XRECADS", xrecname);
acedRetVoid();
return RTNORM;
}
// Accesses the xrecord associated with the key ASDK_XRECADS in
// the extension dictionary of a user-selected entity. Then
// list out the contents of this xrecord using the printList
// function.
//
int
listXrecord()
{
struct resbuf *pXrec, *pEnt, *pTemp;
ads_point dummy;
ads_name ename, extDict = {0L, 0L};
// Have the user select an entity; then get its data.
//
if (acedEntSel("\nselect entity: ", ename, dummy) != RTNORM) {
acutPrintf("\nNothing selected");
acedRetVoid();
return RTNORM;
}
pEnt = acdbEntGet(ename);
// Get the entity name of the extension dictionary.
//
for (pTemp = pEnt;pTemp->rbnext != NULL;pTemp = pTemp->rbnext) {
if (pTemp->restype == 102) {
if (!strcmp("{ACAD_XDICTIONARY", pTemp->resval.rstring)){
ads_name_set(pTemp->rbnext->resval.rlname, extDict);
break;
}
}
}
if (extDict[0] == 0L) {
acutPrintf("\nNo extension dictionary present.");
return RTNORM;
}
pXrec = acdbDictSearch(extDict, "ASDK_XRECADS", 0);
if(pXrec) {
printList(pXrec);
acutRelRb(pXrec);
}
acedRetVoid();
return RTNORM;
}
Стирание объекта
Любой объект в базе данных может быть стерт следующей функцией:
Acad::ErrorStatus
AcDbObject::erase(Adesk::Boolean Erasing = Adesk::kTrue);
ОБРАТИТЕ ВНИМАНИЕ Erase() имеет различные результаты для объектов базы данных и примитивов, с
последствиями для нестирания их:
когда объект базы данных стерт, информация относительно того объекта удалена из словаря. Если
объект нестерт со стиранием (kfalse), информация автоматически не повторно представлена. Вы
Должен использовать setAt () функция, чтобы прибавить информацию к словарю снова.
когда объект стерт, это просто помечено как стерто в блочном отчете{*записи*} таблицы. Объект
может быть нестерт со стиранием (kfalse).
extern Acad::ErrorStatus
acdbOpenObject(AcDbObject*& obj,
AcDbObjectId objId,
AcDb::OpenMode openMode,
57
Adesk::Boolean openErasedObject =
Adesk::kFalse);
Глава 6. Примитивы
Эта глава описывает примитивы — объекты базы данных с графическим представлением. Это перечисляет
свойства и операции, все примитивы имеют в общем{*обычном*}. Примеры показывают, как создать блоки,
вставки, и комплексные примитивы, и как выбирать и высветить подпримитивы.
Определенные Примитивы
Монопольное использование Примитива
Выпуск AutoCAD 12 Примитивов
Общие{*обычные*} Свойства Примитива
Общие{*обычные*} Функции Примитива
Создание Образцов Примитивов AutoCAD
Комплексные Примитивы
Доступ Системы координат
Функции Кривой
Связывающиеся Гиперсвязи с Примитивами
Определенные Примитивы
Примитив в базе данных имеет графическое представление. Примеры примитивов включают
строки, круги, дуги, текст, solids, области{*регионы*}, сплайны, и эллипсы. AcDbEntity класс получен
из AcDbObject.
58
С несколькими исключениями, примитивы содержат всю необходимую информацию относительно их
геометрии. Несколько примитивов содержат другие объекты, которые проводят{*держат*} их геометрическую
информацию или атрибуты. Сложные примитивы включают следующее:
AcDb2dPolyline, который имеет объекты AcDb2dPolylineVertex
AcDb3dPolyline, который имеет объекты AcDb3dPolylineVertex
AcDbPolygonMesh, который имеет объекты AcDbPolygonMeshVertex
AcDbPolyFaceMesh, который имеет объекты AcDbPolyFaceMeshVertex и объекты
AcDbFaceRecord
AcDbBlockReference, который имеет объекты AcDbAttribute
AcDbMInsertBlock, который имеет объекты AcDbAttribute
Примеры создания и выполнения итераций через сложные примитивы обеспечиваются в “ Сложные
Примитивы ” на странице 134.
59
Примитивы AutoCAD 12
Следующие примитивы были включены в Выпуск AutoCAD 12 и объявлены в dbents.h файле. Вы не можете
безопасно получать новые классы из следующего
Выпустите 12 примитивов:
N AcDb2dPolyline
N AcDb3dPolyline
N AcDbPolygonMesh
N AcDbPolyFaceMesh
N AcDbSequenceEnd
N AcDbBlockBegin
N AcDbBlockEnd
N AcDbVertex
N AcDbFaceRecord
N AcDb2dVertex
N AcDb3dPolylineVertex
N AcDbPolygonMeshVertex
N AcDbPolyFaceMeshVertex
N AcDbMInsertBlock
60
Графическое название{*имя*} стиля
Когда Вы добавляете примитив к блочному отчету{*записи*} таблицы, AutoCAD автоматически
вызывает AcDbEntity:: setDatabaseDefaults () функция, которая устанавливает свойства в их
значения по умолчанию, если Вы явно не установили их.
AcDbViewport приобретает параметры настройки текущего графического окна.
Если свойство было явно не определено для примитива, текущее значение базы данных для того свойства
используется. См. главу 4, “ Операции Базы данных, ” для описания функций члена, используемых для
установки и получения текущих значений свойства, связанных с базой данных.
Цвет примитива
Цвет Примитива может быть установлен и читать как числовые индексные значения в пределах от
от 0 до 256, или образцами AcCmColor, который обеспечивается для будущего использования
расширенной цветовой моделью. В настоящее время, цвет использований AutoCAD индексирует
только. Правильный цветной индекс может быть получен от образца AcCmColor использование
AcCmColor:: getColorIndex () функция члена.
Цвет индексирует 1 до 7, используются для стандартных цветов, как показано в следующей таблице:
257 Никаких цвета. Только подарок{*настоящее*} со времени, примитив является первым instantiated до его
цвета, установлен в значение между 0 и 256, или примитив добавлен к базе данных и принимает текущий
цветной индекс базы данных.
Если номер цвета определен для примитива, текущий номер цвета значения по умолчанию базы данных
игнорируется. Используйте следующие функции, чтобы устанавливать и сделать запрос цвета примитива:
virtual Acad::ErrorStatus
AcDbEntity::setColorIndex(Adesk::UInt16 color);
Adesk::UInt16
AcDbEntity::colorIndex() const;
Linetype примитива
Значение linetype указывает на вход таблицы идентификаторов, который определяет ряд точек и
подчеркивает штриховой линией используемый для рисунка строк. Когда примитив - instantiated,
его linetype установлен в NULL. Когда примитив добавлен к базе данных, если linetype не был
определен для примитива, linetype установлен в поток базы данных linetype значение. Это
значение по умолчанию сохранено в CELTYPE системной переменной.
Linetype может быть определен по имени, строкой, или объектом ID AcDbLineTypeTableRecord в
целевой базе данных примитива.
61
Следующие функции дают возможность Вам установить linetype для примитива, или по имени или объектом
ID:
virtual Acad::ErrorStatus
AcDbEntity::setLinetype(const char* newVal);
virtual Acad::ErrorStatus
AcDbEntity::setLinetype(AcDbObjectId newVal);
Эта функция возвращает объект ID для отчета{*записи*} таблицы идентификаторов определение linetype:
Acad::ErrorStatus
AcDbEntity::setLinetypeScale(double newVal);
double
AcDbEntity::linetypeScale() const;
Регенерация Рисунка
Когда примитив восстановлен, его эффективный масштаб linetype - изделие{*программа*} и, примитива
linetype масштаб и глобальная база данных linetype масштаб. Для небумажных пространственных
примитивов, масштаб linetype рассчитан следующим образом:
Видимость Примитива
Если Вы определяете, что примитив невидим, это будет невидимо независимо от других параметров
настройки в базе данных. Другие коэффициенты{*факторы*} могут также заставлять примитив быть
невидимыми.
Например, примитив не будет отображен, если его уровень выключен или закрепляется.
Значение AcDb:: Видимость может быть или kInvisible или kVisible.
Acad::ErrorStatus
AcDbEntity::setVisibility(AcDb::Visibility newVal);
AcDb::Visibility
AcDbEntity::visibility() const;
Уровень Примитива
Все примитивы имеют связанный уровень. База данных всегда содержит по крайней мере один уровень
(уровень 0). Как с linetypes, Вы можете определить уровень для примитива. Если Вы не определяете
уровень, заданное по умолчанию значение уровня базы данных используется для нового примитива.
62
Каждый уровень также связал свойства, которые включают замораживающийся / таял, вкл\выкл, блокируемый
/ разблокир, цвет, linetype, и область просмотра (см. главу 7, “ Контейнерные Объекты ”). Когда цвет
примитива или linetype - BYLAYER, значение свойства уровня используется для примитива.
Если значение уровня определено для примитива, текущее значение уровня базы данных игнорируется.
Следующие функции дают возможность Вам установить уровень для примитива, или по имени или объектом
ID:
Acad::ErrorStatus
AcDbEntity::setLayer(const char* newVal);
Acad::ErrorStatus
AcDbEntity::setLayer(AcDbObjectId newVal);
Эта функция возвращает объект ID для текущего уровня (объект типа AcDbLayerTableRecord):
63
уместные поспешные пункты{*точки*} для указанного режима Object Snap. Следующая таблица
перечисляет возможные режимы Object Snap.
virtual Acad::ErrorStatus
AcDbEntity::getOsnapPoints(
AcDb::OsnapMode osnapMode,
int gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const;
GeomIds параметр в настоящее время не используется. Перекрестная объектная изюминка не использует эту
функцию.
Функции преобразования
AcDbEntity класс обеспечивает две функции преобразования:
virtual Acad::ErrorStatus
AcDbEntity::transformBy(const AcGeMatrix3d& xform);
virtual Acad::ErrorStatus
AcDbEntity::getTransformedCopy(const AcGeMatrix3d& xform,
AcDbEntity*& ent) const;
Пересечение точек
IntersectWith () функция возвращает пункты{*точки*}, где примитив пересекает другой примитив в рисунке.
Входные значения для этой функции - примитив и перекрестный тип, который может быть один из
следующего:
kOnBothOperands (никакой примитив расширен{*продлен*})
kExtendThis
kExtendArg
kExtendBoth
Например, предположите, что рисунок содержит три строки, показанные в следующей иллюстрации. Line1 -
"это" и line3 - примитив параметра. Если перекрестный тип - kExtendThis, пункт{*точка*} возвращен как
пункт{*точка*}, где line1 ("это") пересек бы line3, если line1 были расширены{*продлены*}. Если перекрестный
тип - kExtendArgument, и line2 - примитив параметра, никакие данные не возвращены, потому что, даже если
это было расширено{*продлено*}, line2 не будет пересекать line1. Если перекрестный тип - kExtendBoth, и
line2 - примитив параметра, пункт{*точка*} B возвращен. Если перекрестный тип - kExtendNone, и line2 -
примитив параметра, никакие данные не возвращены.
64
Вторая форма берет дополнительный параметр, который является самолетом проектирования для
определения очевидного пересечения двух примитивов. Они - сигнатуры для intersectWith () функция:
virtual Acad::ErrorStatus
AcDbEntity::intersectWith(
const AcDbEntity* ent,
AcDb::Intersect intType,
AcGePoint3dArray& points,
int thisGsMarker = 0,
int otherGsMarker = 0) const;
virtual Acad::ErrorStatus
AcDbEntity::intersectWith(
const AcDbEntity* ent,
AcDb::Intersect intType,
const AcGePlane& projPlane,
AcGePoint3dArray& points,
int thisGsMarker = 0,
int otherGsMarker = 0) const;
GS Маркеры и Подпримитивы
Чтобы тянуть{*рисовать*} себя, каждый примитив делает запросы к графическим примитивам типа ломаных
линий, кругов, и дуг, содержащихся в AcGi библиотеке. Любой класс, полученный из AcDbEntity может
связывать систему графики (GS) маркер с векторами дисплея, которые это использует, чтобы
тянуть{*рисовать*} себя. Каждый подкласс примитива управляет, где это вставляет его GS маркеры. Когда
пользователь выбирает примитив, GS маркер используется, чтобы выделить, которая часть примитива была
выбрана.
Solids полученный из AcDb3dSolid составлены из вершины, граней, и лиц.
Каждый из этих элементов может быть идентифицирован GS маркером. Создатель класса примитива решает,
где GS маркеры должны быть вставлены, в зависимости от того, что является наиболее естественным для
примитива. Поле, например, создает GS маркер для каждой строки, имел обыкновение тянуть{*рисовать*}
поле. Цилиндр создает три GS маркеры — один для его вершины, основания, и вне лиц.
Примитив составлен из подпримитивов следующего типа: вершина, край, или лицо. В настоящее время,
единственные примитивы, которые поддерживают подпримитивы - тела, области{*регионы*}, solids, и mlines.
Используйте getSubentPathsAtGsMarker () функция, чтобы получить пути к подпримитивам, которые связаны с
частностью GS маркер.
Больше чем один подпримитив могут быть связаны с одиночным маркером. В случае поля, например, маркер
4 идентифицирует более низкий передний край поля.
Если Вы просите о вершине, связанной с этим маркером, две вершина, которая формируется, оконечные
точки этой строки возвращены. Если Вы просите о гранях, связанных с этим маркером, один примитив —
строка — возвращен. Если Вы просите о лицах, связанных с этим маркером, данные для лицевой
поверхности и нижней поверхности поля возвращены.
Путь Подпримитива
Путь подпримитива уникально идентифицирует подпримитив в пределах специфического
примитива в рисунке. Этот путь, класса AcDbFullSubentPath, состоит из массива объекта IDs и
объекта ID подпримитива:
{ AcDbObjectIdArray mObjectIds;
AcDbSubentId mSubentId;
}
Массив содержит объект IDs, которые определяют путь к “основному” примитиву.
Например, блочная ссылка{*справочники*} (примитив, что ссылки{*справочники*} блочный
отчет{*запись*} таблицы) могли бы содержать два поля, каждый из типа AcDb3dSolid. Массив
объектов ID содержит два входа: ИДЕНТИФИКАТОР блочной ссылки{*справочников*},
сопровождаемой ИДЕНТИФИКАТОРОМ основного примитива [InsertID, SolidID].
Второй элемент AcDbFullSubentPath - объект AcDbSubentId, который имеет тип подпримитива
(вершина, край, или лицо) и индекс подпримитива в списке. Используйте тип функций
AcDbSubentId () и index() чтобы обратиться к данным члена.
Используя предыдущий пример, второй край твердых будет иметь его AcDbFullSubentPath как
65
{(InsertID, solid1ID)
(kEdgeSubentType, 2)};
Если бы Вы имеете твердый только, AcDbFullSubentPath был бы следующим образом для первого
лица твердых.
{(solidID)
(kFaceSubentType, 1)};
Пример высвечивание
Пример кода позже в этом разделе показывает, как высветить подпримитив.
Следующая процедура перечисляет основные шаги.
1 Получают GS маркер для выбранного примитива от набора выборов.
2 Передают GS маркер к классу примитива, который будет преобразован{*конвертирован*} к пути
подпримитива, используя getSubentPathsAtGsMarker () функция. Определите тип подпримитива, вы
заинтересованы (вершина, край, лицо).
3, как только Вы имеете путь к выбранному подпримитиву, вы готовы назвать подсветку ()
функцией, проходящей в правильном пути подпримитива.
Выбор Примитива
Для выбора, вы будете использовать комбинацию глобальных функций. Сначала, используйте
acedSSGet () функция, чтобы получить набор выборов. Тогда, используйте acedSSNameX ()
функция, чтобы получить подпримитив GS маркер для выбранного примитива.
int acedSSGet(
const char *str,
const void *pt1,
const ads_point pt2,
const struct resbuf *entmask,
ads_name ss);
int acedSSNameX(
struct resbuf** rbpp,
const ads_name ss,
const longvi);
virtual Acad::ErrorStatus
AcDbEntity::getSubentPathsAtGsMarker(
AcDb::SubentType type,
int gsMark,
const AcGePoint3d& pickPoint,
const AcGeMatrix3d& viewXform,
int& numPaths,
AcDbFullSubentPath*& subentPaths
int numInserts = 0,
AcDbObjectId* entAndInsertStack = NULL) const;
Первый параметр к этой функции - тип подпримитива, вы заинтересованы (вершина, край, или
лицо). В примере закодируют в “ Высвечивание{*увеличение яркости*} - tity, ” первый запрос к этой
функции определяет kEdgeSubentType, потому что вы собираетесь высвечивать соответствующий
край. Второй запрос к getSubentPathsAtGsMarker () функция определяет kFaceSubentType, потому
что вы собираетесь высвечивать каждое лицо, связанное с выбранным подпримитивом.
PickPoint и viewXform параметры используются как дополнительный ввод для некоторых
примитивов (типа mlines) когда GS маркер один не обеспечивает достаточно информации, чтобы
возвратить пути подпримитива. В примере закодируют в “ Высвечивание{*увеличение яркости*}
Подпримитива, ” они не используются.
NumInserts и entAndInsertStack параметры используются для вложенных вставок. И acedNEntSel ()
и acedNEntSelP () функции возвращают название{*имя*} примитива уровня листа, плюс стек
вставок.
Высвечивание{*увеличение яркости*} Подпримитива
Как только вы получили путь подпримитива к выбранному примитиву, самая твердая{*самая
трудная*} часть этого процесса закончена. Теперь, Вы нуждаетесь только в запросе подсветка ()
функция и проход в пути подпримитива. Если Вы вызываете{*называете*} подсветку () функция без
любых параметров, значение по умолчанию должна высветить целый примитив.
66
Следующий типовой код иллюстрирует шаги, описанные для выбора примитива, получение пути
подпримитива, и высвечивания{*увеличения яркости*} различных типов подпримитивов, связанных с GS
маркером. Этот код также иллюстрирует другую полезную функцию подпримитива:
virtual AcDbEntity*
AcDbEntity::subentPtr(const AcDbFullSubentPath& id) const;
Эта функция возвращает указатель на копию подпримитива, описанного указанным путем, который может
тогда быть добавлен к базе данных (как показано в примере).
ПРИМЕЧАНИЕ ожидается, что Вы будете должны перегрузить функции getSubentPathsAtGsMarker
(), getGsMarkersAtSubentPath () и subentPtr () когда, Вы создает новые подклассы AcDbEntity.
Подсветка () функция, однако, осуществлена в AcDbEntity, выравнивают, и как ожидается, будет
перегружен. Однако, если это перегружено, любое новое выполнение этой функции должно
назвать AcDbEntity:: подсветкой () чтобы исполнить высвечивание{*увеличение яркости*}.
67
// AcDbFullSubentIdPath, which is then used to highlight
// and unhighlight the edge used to select the object.
// Next, the object’s subentPtr() function is used to get
// a copy of the edge. This copy is then added to the
// database. Finally, the object is closed.
//
void
highlightEdge(const AcDbObjectId& objId, const int marker)
{
char dummy[133]; // space for acedGetString pauses below
AcDbEntity *pEnt;
acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead);
// Get the subentity ID for the edge that is picked
//
AcGePoint3d pickpnt;
AcGeMatrix3d xform;
int numIds;
AcDbFullSubentPath *subentIds;
pEnt->getSubentPathsAtGsMarker(AcDb::kEdgeSubentType,
marker, pickpnt, xform, numIds, subentIds);
// At this point the subentId’s variable contains the
// address of an array of AcDbFullSubentPath objects.
// The array should be one element long, so the picked
// edge’s AcDbFullSubentPath is in subentIds[0].
//
// For objects with no edges (such as a sphere), the
// code to highlight an edge is meaningless and must
// be skipped.
//
if (numIds > 0) {
// Highlight the edge.
//
pEnt->highlight(subentIds[0]);
// Pause to let user see the effect.
//
acedGetString(0, "\npress <RETURN> to continue...",
dummy);
// Unhighlight the picked edge.
//
pEnt->unhighlight(subentIds[0]);
// Get a copy of the edge, and add it to the database.
//
AcDbEntity *pEntCpy = pEnt->subentPtr(subentIds[0]);
AcDbObjectId objId;
addToModelSpace(objId, pEntCpy);
}
delete []subentIds;
pEnt->close();
}
68
pEnt->unhighlight(subentIds[i]);
}
delete []subentIds;
pEnt->close();
}
Acad::ErrorStatus
addToModelSpace(AcDbObjectId &objId, AcDbEntity* pEntity)
{
AcDbBlockTable *pBlockTable;
AcDbBlockTableRecord *pSpaceRecord;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
pBlockTable->getAt(ACDB_MODEL_SPACE, pSpaceRecord,
AcDb::kForWrite);
pSpaceRecord->appendAcDbEntity(objId, pEntity);
pBlockTable->close();
pEntity->close();
pSpaceRecord->close();
return Acad::eOk;
}
void
createInsert()
{
// Create a nested insert and try highlighting its
// various subcomponents.
//
// There are six entities in total -- three polys and
// three boxes (solids). We’ve named them: poly1, poly2,
// poly3, and box1, box2, box3. We also have three
// inserts: ins1, ins2, ins3.
//
// ins3 is an insert of a block that contains (poly3, box3)
// ins2 is an insert of a block that contains (poly2, box2,
// ins3).
// ins1 is an insert of a block that contains (poly1, box1,
// ins2).
//
// Let's create these entities first.
//
69
// Polys
//
AsdkPoly *poly1, *poly2, *poly3;
AcGeVector3d norm(0, 0, 1);
if ((poly1=new AsdkPoly)==NULL){
acutPrintf("\nOut of Memory.");
return;
}
if (poly1->set(AcGePoint2d(2, 8),AcGePoint2d(4, 8), 6, norm, "POLY1",0) != Acad::eOk){
acutPrintf("\nCannot create object with given parameters.");
delete poly1;
return;
}
if ((poly2=new AsdkPoly)==NULL){
acutPrintf("\nOut of Memory.");
delete poly1;
return;
}
if (poly2->set(AcGePoint2d(7, 8), AcGePoint2d(9, 8), 6, norm, "POLY2",0) != Acad::eOk){
acutPrintf("\nCannot create object with given parameters.");
delete poly1;
delete poly2;
return;
}
if ((poly3=new AsdkPoly)==NULL){
acutPrintf("\nOut of Memory.");
delete poly1;
delete poly2;
return;
}
if (poly3->set(AcGePoint2d(12, 8),AcGePoint2d(14, 8), 6, norm, "POLY3",0)!=Acad::eOk){
acutPrintf("\nCannot create object with given parameters.");
delete poly1;
delete poly2;
delete poly3;
return;
}
postToDb(poly1);
postToDb(poly2);
postToDb(poly3);
// Boxes
//
AcDb3dSolid *box1, *box2, *box3;
box1 = new AcDb3dSolid();
box2 = new AcDb3dSolid();
box3 = new AcDb3dSolid();
box1->createBox(2, 2, 2);
box2->createBox(2, 2, 2);
box3->createBox(2, 2, 2);
AcGeMatrix3d mat;
mat(0, 3) = 2; mat(1, 3) = 2;
box1->transformBy(mat);
mat(0, 3) = 7; mat(1, 3) = 2;
box2->transformBy(mat);
mat(0, 3) = 12; mat(1, 3) = 2;
box3->transformBy(mat);
postToDb(box1);
postToDb(box2);
postToDb(box3);
// Inserts
//
// Arguments to BLOCK are:
// blockname,
// insert point,
// select objects,
// empty string for selection complete
// Arguments to INSERT are:
// blockname,
// insertion point,
// xscale,
// yscale,
// rotation angle
//
acedCommand_command(RTSTR, "_globcheck", RTSHORT, 0, RTNONE);
acedCommand(RTSTR, "BLOCK", RTSTR, "blk3", RTSTR, "0,0",
RTSTR, "14,8", RTSTR, "11,1", RTSTR, "",
RTNONE);
acedCommand(RTSTR, "INSERT", RTSTR, "blk3", RTSTR,
70
"0,0", RTSHORT, 1, RTSHORT, 1, RTSHORT,
0, RTNONE);
acedCommand(RTSTR, "BLOCK", RTSTR, "blk2", RTSTR, "0,0",
RTSTR, "9,8", RTSTR, "6,1", RTSTR, "11,1",
RTSTR, "", RTNONE);
acedCommand(RTSTR, "INSERT", RTSTR, "blk2", RTSTR,
"0,0", RTSHORT, 1, RTSHORT, 1, RTSHORT,
0, RTNONE);
acedCommand(RTSTR, "BLOCK", RTSTR, "blk1", RTSTR, "0,0",
RTSTR, "4,8", RTSTR, "1,1", RTSTR, "6,1",
RTSTR, "", RTNONE);
acedCommand(RTSTR, "INSERT", RTSTR, "blk1", RTSTR,
"0,0", RTSHORT, 1, RTSHORT, 1, RTSHORT,
0, RTNONE);
return;
}
void
hilitInsert()
{
Adesk::Boolean interrupted = Adesk::kFalse;
acutPrintf("\nSelect an insert");
Acad::ErrorStatus es = Acad::eOk;
AcDbEntity *ent = NULL;
AcDbEntity *ent2 = NULL;
AcDbBlockReference *blRef = NULL;
AcDbObjectId objectId, blRefId;
ads_name ename, sset;
for (;;) {
switch (acedSSGet(NULL, NULL, NULL, NULL, sset)) {
case RTNORM:
{
struct resbuf *rb;
if (acedSSNameX(&rb, sset, 0) != RTNORM) {
acutPrintf("\n acedSSNameX failed");
acedSSFree(sset);
return;
}
int sel_method;
ads_name subname;
short marker;
AcGePoint3d pickpnt;
AcGeVector3d pickvec;
if (!extractEntityInfo(rb,
sel_method,
ename,
subname,
marker,
pickpnt,
pickvec)) {
acutPrintf("\nextractEntityInfo failed");
acedSSFree(sset);
return;
}
acedSSFree(sset);
assert(marker != 0);
if (marker == 0) {
acutPrintf("\nmarker == 0");
return;
}
// Get the insert first.
//
AOK(acdbGetObjectId(blRefId, ename));
AOK(acdbOpenAcDbEntity(ent, blRefId,
AcDb::kForRead));
assert(ent != NULL);
blRef = AcDbBlockReference::cast(ent);
if (blRef == NULL) {
acutPrintf("\nNot an insert.");
AOK(ent->close());
continue;
}
struct resbuf *insStack;
ads_point pickpoint;
ads_matrix adsmat;
pickpoint[0] = pickpnt[0];
pickpoint[1] = pickpnt[1];
71
pickpoint[2] = pickpnt[2];
// Now get details on the entity that was
// selected.
//
if (acedNEntSelP(NULL, ename, pickpoint, TRUE,
adsmat, &insStack) != RTNORM)
{
acutPrintf("\nFailure in acedNEntSelP");
return;
}
assert(insStack != NULL);
AOK(acdbGetObjectId(objectId, ename));
AOK(acdbOpenAcDbEntity(ent2, objectId,
AcDb::kForRead));
assert(ent2 != NULL);
// Make an array of AcDbObjectIds from the
// insertStack. Don’t use the "smart array"
// AcDbObjectIdArray class, because the
// getSubentPathsAtGsMarker() function expects argument
// eight to be of type AcDbObjectId*. Just
// make room for approximately 100 IDs in the array.
//
AcDbObjectId *idArray = new AcDbObjectId[100];
int count = 0;
struct resbuf *rbIter = insStack;
AcDbObjectId objId;
acdbGetObjectId(objId, ename);
idArray[count++] = objId;
while (rbIter != NULL) {
ename[0] = rbIter->resval.rlname[0];
ename[1] = rbIter->resval.rlname[1];
acdbGetObjectId(objId, ename);
idArray[count++] = objId;
rbIter = rbIter->rbnext;
}
count--;
acutRelRb(insStack);
// First, we’ll highlight an edge.
//
int numPaths;
AcDbFullSubentPath *subentPaths;
AcGeMatrix3d xform;
es = blRef->getSubentPathsAtGsMarker(
AcDb::kEdgeSubentType,
marker,
pickpnt,
xform,
numPaths,
subentPaths,
count,
idArray);
assert(numPaths == 1);
// Highlight and unhighlight the selected edge.
//
acutPrintf("\nHighlighting the first edge.");
es = blRef->highlight(subentPaths[0]);
pressEnterToContinue();
es = blRef->unhighlight(subentPaths[0]);
// If this is a solid, it will have faces.
// In this case, let’s highlight them.
//
if(ent2->isKindOf(AcDb3dSolid::desc())) {
es = blRef->getSubentPathsAtGsMarker(
AcDb::kFaceSubentType,
marker,
pickpnt,
xform,
numPaths,
subentPaths,
count,
idArray);
assert(numPaths == 2);
// Highlight and unhighlight the selected
// faces.
//
acutPrintf("\nHighlighting the first"
" face.");
es = blRef->highlight(subentPaths[0]);
72
pressEnterToContinue();
es = blRef->unhighlight(subentPaths[0]);
acutPrintf("\nHighlighting the next face.");
es = blRef->highlight(subentPaths[1]);
pressEnterToContinue();
es = blRef->unhighlight(subentPaths[1]);
}
delete []subentPaths;
// Now, let’s highlight the whole entity.
//
acutPrintf("\nHighlighting the entire entity");
AcDbFullSubentPath subPath;
for (int i = count; i >= 0; i--) {
subPath.objectIds().append(idArray[i]);
}
es = blRef->highlight(subPath);
pressEnterToContinue();
es = blRef->unhighlight(subPath);
// Finally, let’s highlight each enclosing
// insert.
//
for (i = count -1; i >= 0; i --) {
subPath.objectIds().removeAt(
subPath.objectIds().length() - 1);
acutPrintf("\nHighlighting insert layer %d",
i + 1);
blRef->highlight(subPath);
pressEnterToContinue();
es = blRef->unhighlight(subPath);
}
} // case RTNORM
break;
case RTNONE:
case RTCAN:
return;
default:
continue;
} // switch
break;
} //for (;;)
AOK(ent->close());
AOK(ent2->close());
return;
}
Расчленение примитивов
Некоторые примитивы могут взрываемся, или анализир{*расчленен*}, в набор более простых элементов.
Определенное поведение зависит от класса. Например, поля могут взрываемся в области{*регионы*}, затем
выравнивают. Ломаные линии могут взрываемся в доли строки. Mtext примитив может вз в отдельный
текстовый примитив для каждой строки первоначального объекта. Mline примитив может вз в
индивидуальные строки. Когда Вы взрываете блочную ссылку{*справочники*}, AutoCAD копирует все
примитивы в блочной ссылке{*справочниках*} и затем разбивает их на их компоненты.
Взрывающийся () функция создает массив объектов, полученных из AcDbEntity.
Следующая таблица показывает тому, что случается, когда Вы взрываете каждый примитив, когда это -
отдельно и когда это находится в блочной вставке, которая неоднородно масштабируется.
Взрыв примитивов
Entity By Itself Nonuniform Scaling
(when in a block)
AcDb3dSolid Regions,bodies NA; can’t be exploded
AcDbBody Regions, bodies NA
Ac2dDbPolyline Lines, arcs Self/NA
Ac3dPolyline Lines Self
AcDbArc Self Ellipse
AcDbCircle Self Ellipse
AcDbDimension Solids, lines, text,strings, points NA
AcDbEllipse Self Self
AcDbLeader Self NA
AcDbLine Self Self
AcDbRay Self Self
AcDbSpline Self Self
AcDbXline Self Self
AcDbFace Self Self
AcDbMline Lines Self
73
AcDbMText One text entity for each line Self
AcDbPoint Self Self
AcDbPolyFaceMesh AcDbFace Self
AcDbPolygonMesh Self Self
AcDbRegion Curves (splines, lines, NA
arcs, circles)
AcDbShape Self Self
AcDbSolid Self Self
AcDbText Self Self
AcDbTrace Self Self
Explode() - функция только для чтения, которая не изменяет первоначальный примитив. Это возвращает
набор примитивов для приложения, чтобы обработать как желательно. Одно потенциальное использование
этой функции должно взорвать сложный примитив, чтобы произвести более простые примитивы и затем
работать на тех примитивах. Например, если Вы осуществляли intersectForPoints () функция для ломаной
линии, могло бы быть проще имеет дело с индивидуальные части ломаной линии скорее чем законченный
примитив.
Следующие инструкции истинны для команды EXPLODE (но не для функции explode ()):
Визуальное появление{*вид*} постоянный.
взрываемый примитив стерт от базы данных.
Одни или более новые примитивы созданы и добавлены в конец к базе данных.
AcDbObjectId
createLine()
{
AcGePoint3d startPt(4.0, 2.0, 0.0);
AcGePoint3d endPt(10.0, 7.0, 0.0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pLine);
pBlockTableRecord->close();
pLine->close();
return lineId;
}
void
makeABlock()
{
// Create and name a new block table record.
//
AcDbBlockTableRecord *pBlockTableRec
= new AcDbBlockTableRecord();
pBlockTableRec->setName("ASDK-NO-ATTR");
74
// Get the block table.
//
AcDbBlockTable *pBlockTable = NULL;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForWrite);
// Add the new block table record to the block table.
//
AcDbObjectId blockTableRecordId;
pBlockTable->add(blockTableRecordId, pBlockTableRec);
pBlockTable->close();
// Create and add a line entity to the component’s
// block record.
//
AcDbLine *pLine = new AcDbLine();
AcDbObjectId lineId;
pLine->setStartPoint(AcGePoint3d(3, 3, 0));
pLine->setEndPoint(AcGePoint3d(6, 6, 0));
pLine->setColorIndex(3);
pBlockTableRec->appendAcDbEntity(lineId, pLine);
pLine->close();
pBlockTableRec->close();
}
Когда Вы закрываете запись таблицы блоков, блок начинает и блокирует конечные объекты, добавлены к
блоку автоматически.
Следующий пример создает новую запись таблицы блоков по имени ASDK-BLOCK-WITH-ATTR и добавляет
это к таблице блоков. Затем это создает примитив круга и добавляет это к новой записи таблицы блоков. Это
создает два примитива определения атрибута (второй - аналог первых) и добавляет в конец их к той же самой
записи таблицы блоков.
void
defineBlockWithAttributes(
AcDbObjectId& blockId, // This is a returned value.
const AcGePoint3d& basePoint,
double textHeight,
double textAngle)
{
int retCode = 0;
AcDbBlockTable *pBlockTable = NULL;
AcDbBlockTableRecord* pBlockRecord = new AcDbBlockTableRecord;
AcDbObjectId entityId;
// Step 1: Set the block name and base point of the
// block definition.
//
pBlockRecord->setName("ASDK-BLOCK-WITH-ATTR");
pBlockRecord->setOrigin(basePoint);
// Open the block table for write.
//
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForWrite);
// Step 2: Add the block table record to block table.
//
pBlockTable->add(blockId, pBlockRecord);
// Step 3: Create a circle entity.
//
AcDbCircle *pCircle = new AcDbCircle;
pCircle->setCenter(basePoint);
pCircle->setRadius(textHeight * 4.0);
75
pCircle->setColorIndex(3);
// Append the circle entity to the block record.
//
pBlockRecord->appendAcDbEntity(entityId, pCircle);
pCircle->close();
// Step 4: Create an attribute definition entity.
//
AcDbAttributeDefinition *pAttdef
= new AcDbAttributeDefinition;
// Set the attribute definition values.
//
pAttdef->setPosition(basePoint);
pAttdef->setHeight(textHeight);
pAttdef->setRotation(textAngle);
pAttdef->setHorizontalMode(AcDb::kTextLeft);
pAttdef->setVerticalMode(AcDb::kTextBase);
pAttdef->setPrompt("Prompt");
pAttdef->setTextString("DEFAULT");
pAttdef->setTag("Tag");
pAttdef->setInvisible(Adesk::kFalse);
pAttdef->setVerifiable(Adesk::kFalse);
pAttdef->setPreset(Adesk::kFalse);
pAttdef->setConstant(Adesk::kFalse);
pAttdef->setFieldLength(25);
// Append the attribute definition to the block.
//
pBlockRecord->appendAcDbEntity(entityId, pAttdef);
// The second attribute definition is a little easier
// because we are cloning the first one.
//
AcDbAttributeDefinition *pAttdef2
= AcDbAttributeDefinition::cast(pAttdef->clone());
// Set the values that are specific to the
// second attribute definition.
//
AcGePoint3d tempPt(basePoint);
tempPt.y -= pAttdef2->height();
pAttdef2->setPosition(tempPt);
pAttdef2->setColorIndex(1); // Red
pAttdef2->setConstant(Adesk::kTrue);
// Append the second attribute definition to the block.
//
pBlockRecord->appendAcDbEntity(entityId, pAttdef2);
pAttdef->close();
pAttdef2->close();
pBlockRecord->close();
pBlockTable->close();
return;
}
Следующий пример создает блок-ссылку, заполняет атрибуты, и добавляет ссылку к базе данных. Это
использует глобальные функции, чтобы получить ввод пользователя. CreateBlockWithAttributes () функция,
показанная в предыдущем разделе используется, чтобы создать блок-ссылку. Этот пример использует запись
таблицы блоков iterator, чтобы шагнуть через определения атрибута и создавать соответствующий атрибут
76
для каждого определения атрибута. Атрибуты со значением установлены от первоначального определения
атрибута, используя setPropertiesFrom () функция.
void
addBlockWithAttributes()
{
// Get an insertion point for the block reference,
// definition, and attribute definition.
//
AcGePoint3d basePoint;
if (acedGetPoint(NULL, "\nEnter insertion point: ",
asDblArray(basePoint)) != RTNORM)
return;
// Get the rotation angle for the attribute definition.
//
double textAngle;
if (acedGetAngle(asDblArray(basePoint),
"\nEnter rotation angle: ", &textAngle) != RTNORM)
return;
// Define the height used for the attribute definition text.
//
double textHeight;
if (acedGetDist(asDblArray(basePoint),
"\nEnter text height: ", &textHeight) != RTNORM)
return;
// Build the block definition to be inserted.
//
AcDbObjectId blockId;
defineBlockWithAttributes(blockId, basePoint,
textHeight, textAngle);
// Step 1: Allocate a block reference object.
//
AcDbBlockReference *pBlkRef = new AcDbBlockReference;
// Step 2: Set up the block reference to the newly
// created block definition.
//
pBlkRef->setBlockTableRecord(blockId);
// Give it the current UCS normal.
//
struct resbuf to, from;
from.restype = RTSHORT;
from.resval.rint = 1; // UCS
to.restype = RTSHORT;
to.resval.rint = 0; // WCS
AcGeVector3d normal(0.0, 0.0, 1.0);
acedTrans(&(normal.x), &from, &to, Adesk::kTrue,
&(normal.x));
// Set the insertion point for the block reference.
//
pBlkRef->setPosition(basePoint);
// Indicate the LCS 0.0 angle, not necessarily the UCS 0.0 angle.
//
pBlkRef->setRotation(0.0);
pBlkRef->setNormal(normal);
// Step 3: Open the current database’s model space
// block Table Record.
//
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
// Append the block reference to the model space
// block Table Record.
//
AcDbObjectId newEntId;
pBlockTableRecord->appendAcDbEntity(newEntId, pBlkRef);
pBlockTableRecord->close();
// Step 4: Open the block definition for read.
//
AcDbBlockTableRecord *pBlockDef;
acdbOpenObject(pBlockDef, blockId, AcDb::kForRead);
// Set up a block table record iterator to iterate
// over the attribute definitions.
//
AcDbBlockTableRecordIterator *pIterator;
77
pBlockDef->newIterator(pIterator);
AcDbEntity *pEnt;
AcDbAttributeDefinition *pAttdef;
for (pIterator->start(); !pIterator->done(); pIterator->step())
{
// Get the next entity.
//
pIterator->getEntity(pEnt, AcDb::kForRead);
// Make sure the entity is an attribute definition
// and not a constant.
//
pAttdef = AcDbAttributeDefinition::cast(pEnt);
if (pAttdef != NULL && !pAttdef->isConstant()) {
// We have a non-constant attribute definition,
// so build an attribute entity.
//
AcDbAttribute *pAtt = new AcDbAttribute();
pAtt->setPropertiesFrom(pAttdef);
pAtt->setInvisible(pAttdef->isInvisible());
// Translate the attribute by block reference.
// To be really correct, the entire block
// reference transform should be applied here.
//
basePoint = pAttdef->position();
basePoint += pBlkRef->position().asVector();
pAtt->setPosition(basePoint);
pAtt->setHeight(pAttdef->height());
pAtt->setRotation(pAttdef->rotation());
pAtt->setTag("Tag");
pAtt->setFieldLength(25);
char *pStr = pAttdef->tag();
pAtt->setTag(pStr);
free(pStr);
pAtt->setFieldLength(pAttdef->fieldLength());
// The database column value should be displayed.
// INSERT prompts for this.
//
pAtt->setTextString("Assigned Attribute Value");
AcDbObjectId attId;
pBlkRef->appendAttribute(attId, pAtt);
pAtt->close();
}
pEnt->close(); // use pEnt... pAttdef might be NULL
}
delete pIterator;
pBlockDef->close();
pBlkRef->close();
}
void
printAll()
{
int rc;
char blkName[50];
rc = acedGetString(Adesk::kTrue,
"Enter Block Name <CR for current space>: ",
blkName);
if (rc != RTNORM)
return;
if (blkName[0] == ’\0’) {
if (acdbHostApplicationServices()->workingDatabase()
->tilemode() == Adesk::kFalse) {
struct resbuf rb;
acedGetVar("cvport", &rb);
if (rb.resval.rint == 1) {
strcpy(blkName, ACDB_PAPER_SPACE);
} else {
strcpy(blkName, ACDB_MODEL_SPACE);
}
78
} else {
strcpy(blkName, ACDB_MODEL_SPACE);
}
}
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(blkName, pBlockTableRecord,
AcDb::kForRead);
pBlockTable->close();
AcDbBlockTableRecordIterator *pBlockIterator;
pBlockTableRecord->newIterator(pBlockIterator);
for (; !pBlockIterator->done(); pBlockIterator->step())
{
AcDbEntity *pEntity;
pBlockIterator->getEntity(pEntity, AcDb::kForRead);
AcDbHandle objHandle;
pEntity->getAcDbHandle(objHandle);
char handleStr[20];
objHandle.getIntoAsciiBuffer(handleStr);
const char *pCname = pEntity->isA()->name();
acutPrintf("Object Id %lx, handle %s, class %s.\n",
pEntity->objectId(), handleStr, pCname);
pEntity->close();
}
delete pBlockIterator;
pBlockTableRecord->close();
acutPrintf("\n");
}
Сложные примитивы
Этот раздел обеспечивает примеры, показывающие, как создавать и выполнить итерации через сложные
примитивы.
void
createPolyline()
{
// Set four vertex locations for the pline.
//
AcGePoint3dArray ptArr;
ptArr.setLogicalLength(4);
for (int i = 0; i < 4; i++) {
ptArr[i].set((double)(i/2), (double)(i%2), 0.0);
}
// Dynamically allocate an AcDb2dPolyline object,
// given four vertex elements whose locations are supplied
// in ptArr. The polyline has no elevation, and is
// explicitly set as closed. The polyline is simple;
// that is, not curve fit or a spline. By default, the
// widths are all 0.0 and there are no bulge factors.
//
AcDb2dPolyline *pNewPline = new AcDb2dPolyline(
AcDb::k2dSimplePoly, ptArr, 0.0, Adesk::kTrue);
pNewPline->setColorIndex(3);
// Get a pointer to a Block Table object.
//
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
// Get a pointer to the MODEL_SPACE BlockTableRecord.
//
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
// Append the pline object to the database and
79
// obtain its object ID.
//
AcDbObjectId plineObjId;
pBlockTableRecord->appendAcDbEntity(plineObjId,
pNewPline);
pBlockTableRecord->close();
// Make the pline object reside on layer "0".
//
pNewPline->setLayer("0");
pNewPline->close();
}
В AutoCAD, плоские примитивы имеют ECS; трехмерные примитивы делают нет. Примитивы AutoCAD,
которые могут возвращать матрицу нетождеств для их getEcs () функция:
Измерения
Текст
Круги
Дуги
2-ые ломаные линии
Блочные вставки
80
Точки
Следы
Solids
Формы
определения Атрибута
Атрибуты
AcDb2dPolylineVertex
AcDb2dPolyline имеет как повышение и ряд X, Y точки класса AcDb2dPolylineVertex. Позиция () и setPosition ()
функции AcDb2dPolylineVertex определяет трехмерные местоположения в ECS. Координата Z прошла в к
setPosition () функция сохранена в примитиве и возвращена позицией () функция, но иначе игнорируется. Это
не затрагивает повышение ломаной линии.
AcDb2dPolyline класс обеспечивает vertexPosition () функцией, которая возвращается, значение Мировой
системы координат для вершины прошло в. Единственный способ изменять{*заменять*} повышение ломаной
линии использует AcDb2dPolyline:: setElevation () функция.
Функции Кривой
Абстрактный класс AcDbCurve обеспечивает множество функций для действия на кривых, включая функции
для проектирования, распространения{*продления*}, и кривых смещения, также как набора функций для
запроса параметров кривой. Кривые могут быть определены или в пространстве{*пробеле*} параметра или в
Декартовом координатном пространстве. Трехмерная кривая - функция одного параметра (f (t)), в то время как
трехмерная поверхность - функция двух параметров (f (u, v)). Конверсионные функции позволяют Вам
конвертировать{*преобразовывать*} данные от его представления параметра до точек в Декартовой системе
координат.
Сплайны, например, являются лучшими представленными в пространстве{*пробеле*} параметра. Чтобы
разбивать сплайн на три равных части, Вы сначала находите параметры, которые соответствуют точкам
сплайна и затем работают на сплайне в пространстве{*пробеле*} параметра.
Кривые могут использоваться как границы вырезки, границы продления, и как объекты конструкции для
создания сложных трехмерных примитивов.
Вы можете проектировать кривую на план в данном направлении, как показано в следующем примере.
81
Соединение Гиперсвязей с примитивами
ObjectARX позволяет Вам связывать гиперсвязи с примитивами, используя классы AcDbHyperlink,
AcDbHyperlinkCollection, и AcDbEntityHyperlinkPE. Гиперсвязь может быть URL или адрес не-сети типа
местного файла. Вы можете прикреплять, рассматривать, редактировать, и перечислять гиперсвязи в
пределах вашего приложения.
Краткий обзор классов гиперсвязи следует, но для законченной информации относительно классов и их
методов, см. ObjectARX Ссылку.
AcDbHyperlink Класс
Объект AcDbHyperlink содержит имя гиперсвязи (например, http://www.autodesk.com), подместоположение в
пределах той связи{*ссылки*}, описание гиперсвязи или дружественное имя (“ Нажимает в этом месте для
Autodesk ”), и строки дисплея для гиперсвязи. Для AutoCAD, подместоположение - названное
представление{*вид*}, в то время как в приложении электронной таблицы, например, подместоположение
могло бы быть ячейка или группа ячеек. Строка дисплея - обычно тот же самый как описание гиперсвязи.
Если описание нулевое{*пустое*}, имя гиперсвязи и подместоположение используется вместо этого, в “ имя -
подместоположение ” формат.
Гиперсвязи могут также иметь уровни вложенности. Уровень вложенности только представляет интерес когда
имеющий дело с коллекциями гиперсвязи, связанными с примитивом в пределах блока, или с коллекциями,
связанными с примитивом ВСТАВКИ.
AcDbHyperlinkCollection Класс
Этот класс - коллекция объектов AcDbHyperlink, и имеет разнообразие методов для добавления и удаления
тех объектов. AcDbHyperlinkCollection удаляет его содержание, когда они удалены, и когда объект самой
коллекции удален. Гиперсвязи в коллекции пронумерованы от нуля.
AcDbEntityHyperlinkPE Класс
Методы AcDbEntityHyperlinkPE класса позволяют Вам устанавливать, получать, и считать гиперсвязи,
связанные с примитивом.
Пример Гиперсвязи
Следующая функция перечисляет гиперсвязи, связанные с примитивом и позволяет новым гиперсвязям быть
добавленной в их месте. (Проверка ошибок не показывается.)
void AddHyperlink()
{
ads_name en;
ads_point pt;
AcDbEntity * pEnt;
AcDbObjectId pEntId;
// Prompt user to select entity.
acedEntSel("\nSelect an Entity: ", en, pt);
// Get Object id.
acdbGetObjectId(pEntId, en);
// Open object for write.
acdbOpenObject(pEnt, pEntId, AcDb::kForWrite);
// The hyperlink collection object is created inside
// of getHyperlinkCollection
// below. It is our responsibility to delete it.
AcDbHyperlinkCollection * pcHCL = NULL;
// Get the hyperlink collection associated with the entity.
ACRX_X_CALL(pEnt, AcDbEntityHyperlinkPE)->
getHyperlinkCollection(pEnt, pcHCL, false, true);
// If a hyperlink exists already, say so.
if (pcHCL->count() != 0)
{
AcDbHyperlink * pcHO;
acutPrintf("\nThe following hyperlink info already exists
on this entity:");
// Iterate through collection and print existing hyperlinks.
int i = 0;
for (i = 0; i < pcHCL->count(); i++)
{
// Get point to current hyperlink object.
pcHO = pcHCL->item(i);
acutPrintf("\nHyperlink name: %s", pcHO->name());
acutPrintf("\nHyperlink location: %s",
pcHO->subLocation());
acutPrintf("\nHyperlink description: %s",
82
pcHO->description());
}
acutPrintf("\n** All will be replaced.**");
// Remove existing hyperlinks from collection.
// RemoveAt will delete objects too.
for (i = pcHCL->count() - 1; i >= 0; i--)
{
pcHCL->removeAt(i);
}
}
// Get new hyperlinks for this entity.
for (;;)
{
acutPrintf("\nEnter null name, location, and description to
terminate input requests.");
// Prompt user for name and description.
char sName[100], sLocation[100], sDescription[100];
if (acedGetString(TRUE, "\nEnter hyperlink name: ", sName) != RTNORM)
acutPrintf("Invalid input\n");
if (acedGetString(TRUE, "\nEnter hyperlink location: ", sLocation) != RTNORM)
acutPrintf("Invalid input\n");
if (acedGetString(TRUE, "\nEnter hyperlink description: ", sDescription) != RTNORM)
acutPrintf("Invalid input\n");
// Add hyperlink or exit prompting.
if (strcmp(sName, "") || strcmp(sLocation, "") || strcmp(sDescription, ""))
pcHCL->addTail(sName, sDescription, sLocation);
else
break;
}
// Add these hyperlinks to the selected entity (opened above).
ACRX_X_CALL(pEnt, AcDbEntityHyperlinkPE)->
setHyperlinkCollection(pEnt, pcHCL);
// Delete the collection. The collection will delete all its
// contained hyperlink objects.
delete pcHCL;
// Close the object.
pEnt->close();
}
83
Словари обеспечивают подобный механизм для сохранения и восстановления{*поиска*} объектов со
связанными клавишами{*ключами*} имени. База данных AutoCAD создает названный объектный словарь
всякий раз, когда это создает новый рисунок. Названный объектный словарь может рассматриваться как
главное “оглавление” для структур объекта небытия в рисунке. Этот словарь, по умолчанию, содержит четыре
словаря: словарь ГРУППЫ, MLINE словарь стиля, словарь размещения, и графический стиль называет
словарь. Вы можете создавать любое число дополнительных объектов и добавлять их к названному
объектному словарю. Однако, лучшая практика должна добавить один объект непосредственно к названному
объектному словарю и иметь тот объект, в свою очередь имеют другие объекты, связанные с вашим
приложением. Как правило, объект обладания - контейнерный класс типа словаря. Используйте ваш
назначенный Зарегистрированный Символ Разработчика с четырьмя символами для имени этого класса.
Объект AcDbDictionary может содержать любой тип AcDbObject, включая другие словари. Объект словаря не
исполняет контроль соответствия типов входов. Однако, MLINE словарь стиля должен содержать только
образцы класса AcDbMlineStyle, и словарь ГРУППЫ должен содержать только образцы AcDbGroup.
Приложение может требовать определенного печатания для входов в словаре, который это создает и
обслуживает{*поддерживает*}.
Иерархия классов для таблиц идентификаторов, записей таблицы идентификаторов, словарей, и iterators
следующие.
ПРЕДУПРЕЖДЕНИЕ! Стирание словарей или входов словаря (см. “ Обязательные Объекты Базы данных ” на
странице 22) вероятно, заставит AutoCAD или другие приложения терпеть неудачу.
Другое важное различие - те записи таблицы идентификаторов, сохраняют их связанное имя поиска в поле на
их определении класса. Словари, с другой стороны, сохраняют клавишу{*ключ*} имени как часть словаря,
независимого от объекта, это связано с, как показано в ниже.
Symbol Table -------> Symbol table record <name> <other class-specific members>
Dictionary <name> -------> Object <class-specific fields>
Таблицы идентификаторов
Имена, используемые в записях таблицы идентификаторов и в словарях должны следовать за этими
правилами:
Имена может быть любая длина в ObjectARX, но имена символа, введенные пользователями в
AutoCAD ограничены 255 символами.
AutoCAD сохраняет регистр имен, но не использует регистр на сравнениях. Например, AutoCAD
полагает ", что “этаж" будет тем же самым символом как “ЭТАЖ”.
Имена может быть составлен из всех символов, позволенных в именах файла Windows NT, кроме
запятой (,), backquote (‘), точка с запятой (;), и знак "=" (=).
База данных AutoCAD содержит следующие таблицы идентификаторов (в круглых скобках - имя класса и
команда AutoCAD, используемая для добавления входов):
N Таблица блоков (AcDbBlockTable; BLOCK)
N таблица Уровня (AcDbLayerTable; LAYER)
N Текстовая таблица стиля (AcDbTextStyleTable; STYLE)
N Linetype таблица (AcDbLinetypeTable; LTYPE)
N таблица Представления{*вида*} (AcDbViewTable; VIEW)
N таблица ВЕРХНИХ РЕГИСТРОВ (AcDbUCSTable; UCS)
84
N таблица Области просмотра (AcDbViewportTable; VPORT)
N таблица приложений Registered (AcDbRegAppTable)
N таблица стилей Измерения (AcDbDimStyleTable; DIMSTYLE)
Acad::ErrorStatus
AcDb##BASE_NAME##Table::getAt(const char* pEntryName,
AcDb::OpenMode mode,
AcDb##BASE_NAME##TableRecord*&
pRecord,
Adesk::Boolean openErasedRecord =
Adesk::kFalse) const;
или
Acad::ErrorStatus
AcDb##BASE_NAME##Table::getAt(const char* pEntryName,
AcDbObjectId& recordId,
Adesk::Boolean getErasedRecord =
Adesk::kFalse) const;
Эта первая версия этой функции возвращает указатель на открытую запись в pRecord, если запись
соответствия найдена, и операция открытия (с указанным режимом) преуспевает. Если openErasedRecord -
kTrue, функция возвращает объект, даже если это было стерто. Если openErasedRecord - kFalse, функция
возвращает указатель NULL и состояние ошибки eWasErased для стертых объектов.
Вторая версия getAt () функция возвращает AcDbObjectId записи, указанной по имени в значении recordId,
если запись соответствия найдена.
Если getErasedRecord - kTrue, функция возвращает объект соответствия, даже если это было стерто. Объект
не открыт.
Как только Вы получили запись и открыли это, Вы можете получить и устанавливать различные значения
члена. Для определенного класса записи таблицы идентификаторов для законченного списка компонентных
функций класса, см. ObjectARX Ссылку.
Другие важные функции, обеспеченные всеми классами таблицы идентификаторов -, has() и add() функции.
См. пример в “ Создание и Изменение Записи Таблицы Уровня ” на странице 150.
Сигнатура для has()
Adesk::Boolean
AcDb##BASE_NAME##Table::has(const char* pName) const;
has() возвращает kTrue, если таблица содержит запись с именем, которое соответствует pName.
add() имеет следующие сигнатуры:
Acad::ErrorStatus
AcDb##BASE_NAME##Table::add(AcDb##BASE_NAME##TableRecord*
pRecord);
Acad::ErrorStatus
AcDb##BASE_NAME##Table::add(AcDbObjectId& recordId,
AcDb##BASE_NAME##TableRecord*
pRecord);
Эта функция добавляет запись, указанную pRecord, и к базе данных, содержащей таблицу и таблицу
непосредственно. Если добавления преуспевают, и параметр pId - не-NULL, это установлено в AcDbObjectId
записи в базе данных.
Таблица блоков
Примитивы в базе данных типично принадлежат записи таблицы блоков. Таблица блоков содержит три записи
по умолчанию, *MODEL_SPACE, *PAPER_SPACE, и *PAPER_SPACE0, которые соответствуют трем
начальным пространствам рисунка, которые могут быть отредактированы непосредственно пользователями
AutoCAD. Для примеров добавления примитивов к записи таблицы блоков пространства модели, см. главу 2, “
Учебник для начинающих Базы данных, ” и глава 6, “примитивы”.
*PAPER_SPACE и записи *PAPER_SPACE0 соответствуют двум предопределенным размещениям
пространства листа в AutoCAD. Вы можете добавлять, изменять, и удалять размещения пространства листа.
Новые записи таблицы блоков созданы, когда пользователь выпускает команду BLOCK или команду INSERT,
чтобы вставить внешний рисунок. Новые записи таблицы блоков также созданы с acdbEntMake () функция.
85
БЛОК? Списки команд содержание таблицы блоков, за исключением *MODEL_SPACE и записей
*PAPER_SPACE. См. главу 6, “ примитивы, ” для примеров создания блок-ссылки и записи таблицы блоков.
(Блочная ссылка - примитив, который обращается{*относится*} к данной записи таблицы блоков.)
Таблица Уровня
Таблица уровня содержит один уровень, уровень 0, по умолчанию. Пользователь добавляет уровни к этой
таблице с командой LAYER.
Свойства Уровня
AcDbLayerTableRecord класс содержит функции члена для определения множества свойств уровня, которые
затрагивают дисплей их связанных примитивов.
Все примитивы должны обратиться{*отнестись*} к правильной{*допустимой*} записи таблицы уровня.
Руководство программиста AutoCAD обеспечивает детальное описание свойств уровня.
Следующие разделы перечисляют функции члена для установки и запроса свойств уровня.
void AcDbLayerTableRecord::setIsFrozen(Adesk::Boolean);
Adesk::Boolean
AcDbLayerTableRecord::isFrozen() const;
On/Of (Вкл\выкл)
Когда уровень ВЫКЛЮЧЕН, графический не отображены.
void AcDbLayerTableRecord::setIsOff(Adesk::Boolean);
Adesk::Boolean
AcDbLayerTableRecord::isOff() const;
void AcDbLayerTableRecord::setVPDFLT(Adesk::Boolean);
Adesk::Boolean
AcDbLayerTableRecord::VPDFLT() const;
void AcDbLayerTableRecord::setIsLocked(Adesk::Boolean);
Adesk::Boolean
AcDbLayerTableRecord::isLocked() const;
Color (Цвет)
Цвет, установленный setColor () функция используется, когда цвет примитива - BYLAYER.
AcCmColor
AcDbLayerTableRecord::color() const;
Linetype
Linetype, установленный setLinetypeObjectId () функция используется, когда linetype примитива - BYLAYER.
void AcDbLayerTableRecord::setLinetypeObjectId(AcDbObjectId);
AcDbObjectId
AcDbLayerTableRecord::linetypeObjectId() const;
Чтобы устанавливать linetype для уровня, этот пример открывает linetype таблицу для чтения и получает
объект ID записи linetype желательный linetype (здесь, “DASHED” - “ПОДЧЕРКНУТЫЙ ШТРИХОВОЙ
86
ЛИНИЕЙ”). Как только это имеет объект ID для linetype, это закрывает linetype таблицу и устанавливает
linetype для новой записи таблицы уровня. Этот пример использует добавляющийся () функцию, чтобы
добавить запись таблицы уровня на таблицу уровня. Наконец, это закрывает запись таблицы уровня и
таблицу уровня непосредственно.
void
addLayer()
{
AcDbLayerTable *pLayerTbl;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLayerTbl, AcDb::kForWrite);
if (!pLayerTbl->has("ASDK_TESTLAYER")) {
AcDbLayerTableRecord *pLayerTblRcd
= new AcDbLayerTableRecord;
pLayerTblRcd->setName("ASDK_TESTLAYER");
pLayerTblRcd->setIsFrozen(0);// layer to THAWED
pLayerTblRcd->setIsOff(0); // layer to ON
pLayerTblRcd->setVPDFLT(0); // viewport default
pLayerTblRcd->setIsLocked(0);// un-locked
AcCmColor color;
color.setColorIndex(1); // set color to red
pLayerTblRcd->setColor(color);
// For linetype, we need to provide the object ID of
// the linetype record for the linetype we want to
// use. First, we need to get the object ID.
//
AcDbLinetypeTable *pLinetypeTbl;
AcDbObjectId ltId;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLinetypeTbl, AcDb::kForRead);
if ((pLinetypeTbl->getAt("DASHED", ltId))
!= Acad::eOk)
{
acutPrintf("\nUnable to find DASHED"
" linetype. Using CONTINUOUS");
// CONTINUOUS is in every drawing, so use it.
//
pLinetypeTbl->getAt("CONTINUOUS", ltId);
}
pLinetypeTbl->close();
pLayerTblRcd->setLinetypeObjectId(ltId);
pLayerTbl->add(pLayerTblRcd);
pLayerTblRcd->close();
pLayerTbl->close();
} else {
pLayerTbl->close();
acutPrintf("\nlayer already exists");
}
}
Iterators
Каждая таблица идентификаторов имеет передачу iterator, что Вы можете создавать с
AcDb##BASE_NAME##Table::newIterator () функция.
Acad::ErrorStatus
AcDb##BASE_NAME##Table::newIterator(
AcDb##BASE_NAME##TableIterator*& pIterator,
Adesk::Boolean atBeginning = Adesk::kTrue,
Adesk::Boolean skipErased = Adesk::kTrue) const;
NewIterator () функция создает объект, который может использоваться, чтобы шагнуть через содержание
таблицы и заставляет pIterator указывать на iterator объект. Если atBeginning - kTrue, запуски iterator в начале
таблицы; если kFalse, это начинается в конце таблицы. Если skipErased параметр - kTrue, iterator
позиционирован первоначально в первый (или последний{*прошлый*}) нестертая запись; если kFalse, это
позиционировано в первый (или последний{*прошлый*}) запись, независимо от того, было ли это стерто. Для
описания функций, доступных для каждого iterator класса, см. ObjectARX Ссылку.
Когда Вы создаете новый iterator, Вы также ответствены за удаление этого. Таблица идентификаторов не
должна быть закрыта, пока все iterators, который это создало, не были удалены.
В дополнение к таблицам идентификаторов, запись таблицы блоков имеет iterator, который работает на
примитивах, которые это имеет. AcDbBlockTableRecord класс возвращает объект класса
AcDbBlockTableRecordIterator, когда Вы спрашиваете это относительно нового iterator. Этот iterator дает
возможность Вам шагнуть через примитивы, содержащиеся в записи таблицы блоков и искать специфические
примитивы.
87
Выполнение итераций по Таблицам
Код в следующем примере создает iterator, который идет через записи таблицы идентификаторов в linetype
таблице. Это получает каждую запись, открывает это для чтения, получает имя linetype, закрывает запись, и
затем печатает имя linetype. В конец, программа удаляет iterator.
void
iterateLinetypes()
{
AcDbLinetypeTable *pLinetypeTbl;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLinetypeTbl, AcDb::kForRead);
// Create a new iterator that starts at table
// beginning and skips deleted.
//
AcDbLinetypeTableIterator *pLtIterator;
pLinetypeTbl->newIterator(pLtIterator);
// Walk the table, getting every table record and
// printing the linetype name.
//
AcDbLinetypeTableRecord *pLtTableRcd;
char *pLtName;
for (; !pLtIterator->done(); pLtIterator->step()) {
pLtIterator->getRecord(pLtTableRcd, AcDb::kForRead);
pLtTableRcd->getName(pLtName);
pLtTableRcd->close();
acutPrintf("\nLinetype name is: %s", pLtName);
free(pLtName);
}
delete pLtIterator;
pLinetypeTbl->close();
}
Словари
Чтобы создавать новый словарь, Вы должны создать образец AcDbDictionary, добавлять это к базе данных, и
регистрировать это с ее объектом владельца. Используйте setAt () функция AcDbDictionary, чтобы добавить
объекты к словарю и базе данных.
Сигнатура этой функции
Acad::ErrorStatus
AcDbDictionary::setAt(const char* pSrchKey,
AcDbObject* pNewValue,
AcDbObjectId& retObjId);
SetAt () функция добавляет новый вход, указанный newValue к словарю. Если вход уже существует, это
заменено новым значением. Имя объекта определено srchKey. Объект ID входа возвращен в retObjId.
Когда Вы добавляете вход в словарь, словарь автоматически присоединяет{*придает*} реактор к входу. Если
объект стерт, словарь уведомлен и удаляет это из словаря.
Используйте AcDbGroup:: newIterator () функция, чтобы получить iterator и шаг через примитивы в
группе. AcDbGroup класс также обеспечивает функции для добавления в конец и prepending
примитивов к группе, вставка примитивов по специфическому индексу в группе, удаление
примитивов, и передачи примитивов от одной позиции в группе к другому. См. AcDbGroup в
ObjectARX Ссылке.
Вы можете также назначать свойства на всех членов группы, использующей setColor (), setLayer (),
setLinetype (), setVisibility (), и setHighlight () функции AcDbGroup класса. Эти операции имеют тот же
самый эффект как открытие каждого примитива в группе и установке ее свойства
непосредственно.
Группы должны всегда сохраняться в словаре ГРУППЫ, который может быть получен следующим образом:
AcDbDictionary* pGrpDict =
88
acdbHostApplicationServices()->working Database()->
getGroupDictionary(pGroupDict, AcDb::kForWrite);
Альтернативный способ получить словарь ГРУППЫ состоит в том, чтобы искать “ACAD_GROUP” в словаре
имен объектов.
Следующие функции - часть приложения, что первые подсказки пользователь, чтобы выбрать
некоторые примитивы, которые помещены в группу по имени “ASDK_GROUPTEST”. Тогда это
вызывает функцию removeAllButLines () чтобы выполнить итерации по группе и удалять все
примитивы, которые - не линии. Наконец, это изменяет{*заменяет*} остающиеся примитивы в
группе к красному.
void
groups()
{
AcDbGroup *pGroup = new AcDbGroup("grouptest");
AcDbDictionary *pGroupDict;
acdbHostApplicationServices()->workingDatabase()
->getGroupDictionary(pGroupDict, AcDb::kForWrite);
AcDbObjectId groupId;
pGroupDict->setAt("ASDK_GROUPTEST", pGroup, groupId);
pGroupDict->close();
pGroup->close();
makeGroup(groupId);
removeAllButLines(groupId);
}
89
// to be removed be closed, so close it now.
//
pObj->close();
pGroup->remove(pIter->objectId());
} else {
pObj->close();
}
}
delete pIter;
// Now change the color of all the entities in the group
// to red (AutoCAD color index number 1).
//
pGroup->setColorIndex(1);
pGroup->close();
}
Словарь Размещения
Словарь размещения - заданный по умолчанию словарь в пределах названного объектного
словаря, который содержит объекты класса AcDbLayout. AcDbLayout объектно-ориентированные
памяти характеристики размещения пространства листа, включая графические параметры
настройки. Каждый объект AcDbLayout также содержит объект ID связанной записи таблицы
блоков, которая сохраняет примитивы, связанные с размещением.
90
Создание Словаря
Следующий пример создает новый словарь (ASDK_DICT) и добавляет это к словари имен
объектов. Тогда это создает два новых объекта класса пользователя AsdkMyClass (полученный из
AcDbObject) и добавляет их к словарю, используя setAt () функция.
ОБРАТИТЕ ВНИМАНИЕ, что Вы должны закрыть объекты после добавления их с setAt () функция.
91
Выполнение итераций по Входам Словаря
Iterator класс для словарей - AcDbDictionaryIterator. Следующая выборка кода получает словарь
(ASDK_DICT) от названного объектного словаря.
Это тогда использует словарь iterator, чтобы шагнуть через входы словаря и печатать значение сохраненного
целого числа. Наконец, это удаляет iterator и закрывает словарь.
void
iterateDictionary()
{
AcDbDictionary *pNamedobj;
acdbHostApplicationServices()->workingDatabase()
->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead);
// Get a pointer to the ASDK_DICT dictionary.
//
AcDbDictionary *pDict;
pNamedobj->getAt("ASDK_DICT", (AcDbObject*&)pDict,
AcDb::kForRead);
pNamedobj->close();
// Get an iterator for the ASDK_DICT dictionary.
//
AcDbDictionaryIterator* pDictIter = pDict->newIterator();
AsdkMyClass *pMyCl;
Adesk::Int16 val;
for (; !pDictIter->done(); pDictIter->next()) {
// Get the current record, open it for read, and
// print its data.
//
pDictIter->getObject((AcDbObject*&)pMyCl,
AcDb::kForRead);
pMyCl->getData(val);
pMyCl->close();
acutPrintf("\nintval is: %d", val);
}
delete pDictIter;
pDict->close();
}
Размещения
AutoCAD первоначально содержит три размещения: размещение пространства модели и два размещения
пространства листа. К этим размещениям можно обращаться позициями табуляции внизу окна рисунка в
AutoCAD. Позиции табуляции первоначально названы Моделью, Layout1, и Layout2.
Позиция табуляции Model - заданная по умолчанию позиция табуляции и представляет пространство модели,
в котором Вы вообще создаете ваш рисунок. Позиции табуляции Layout1 и Layout2 представляют
пространство листа и вообще используются для размещения вашего рисунка для печати. Размещения
пространства листа отображают бумажное изображение{*образ*}, которое показывает печатаемой границе
для конфигурированного устройства печати.
Рекомендуется, чтобы Вы использовали размещения пространства листа для подготовки
конечных{*заключительных*} рисунков для вывода, но печать может быть выполнена от любого размещения,
включая размещение пространства модели. Для получения дополнительной информации при использовании
размещений в AutoCAD, см. Руководство программиста AutoCAD.
92
Объекты Размещения
Информация относительно размещений сохранена в образцах AcDbLayout класса. Объект размещения
содержит печать и информацию параметров настройки составления графика, необходимую, чтобы печатать
желательную часть рисунка. Например, объект размещения содержит графическое устройство, размер
носителей, графическую область, и графическое вращение, также как несколько других атрибутов, что
справка определяет область, которая будет напечатана.
AcDbLayout объекты сохранены в ACAD_LAYOUT словаре в пределах словари имен объектов базы данных.
Имеется один объект AcDbLayout в размещение пространства листа, также как сингл AcDbLayout для
пространства модели. Каждый объект AcDbLayout содержит объект ID его связанного AcDbBlockTableRecord.
Это заставит это облегчить, чтобы найти запись таблицы блоков, в которой фактическая геометрия
размещения постоянно находится. Если AcDbBlockTableRecord представляет размещение, то это содержит
объект ID его связанного объекта AcDbLayout.
Большинство графической информации для объектов размещения сохранено в AcDbPlotSettings, базовый
класс AcDbLayout. Вы можете создавать названные графические параметры настройки и использовать их,
чтобы инициализировать другие объекты AcDbLayout. Это позволяет Вам экспортировать и импортировать
графические параметры настройки от одного размещения до другого. Эти названные графические параметры
настройки сохранены в образцах AcDbPlotSettings класса. Имеется один объект AcDbPlotSettings для каждой
названной установки графика, и они сохранены в ACAD_PLOTSETTINGS словаре в пределах словари имен
объектов.
ОБРАТИТЕ ВНИМАНИЕ, что не имеется никакого прямого подключения{*связи*} между объектами AcDbLayout
в ACAD_LAYOUT словаре и объектах AcDbPlotSettings в ACAD_PLOTSETTINGS словаре.
Менеджер Размещения
Вы можете управлять объектами AcDbLayout, используя AcApLayoutManager класс.
AcApLayoutManager класс позволяет Вам
Создают размещения
Удаляют размещения
Переименовывают размещения
Копия и размещения аналога
Набор текущее размещение
Находят специфическое размещение
Набор графические характеристики размещения
Имеется один образец менеджера размещения в приложение. Менеджер размещения всегда работает на
текущем размещении.
Xrecords
Xrecords дают возможность Вам добавить произвольные, специфические для приложения данные. Поскольку
они - альтернатива к определению вашего собственного объектного класса, они особенно полезны для
программистов AutoLISP. Xrecord - образец класса AcDbxrecord, который является подклассом AcDbObject.
Xrecord государство{*состояние*} определен как содержание resbuf цепочки, которая является списком групп
данных, каждая из которых в свою очередь содержит код группы DXF плюс связанные данные. Значение кода
группы определяет связанный тип данных. Коды Группы для xrecords находятся в диапазоне от 1 до 369.
Следующий раздел описывает доступную группу DXF коды.
Не имеется никакого свойственного предела размера на сумму данных, которые Вы можете сохранять в
record. Xrecords может принадлежать любому другому объекту, включая словарь расширения{*продления*}
любого объекта, словари имен объектов, любого другого словаря, или другого xrecords.
Никакое уведомление не послано, когда xrecord изменяется. Если приложение должно знать, когда объект,
имеющий xrecord изменился, приложение будет должно послать его собственное уведомление.
AcDbXrecord класс обеспечивает две функции члена для установки и получения resbuf цепочками,
setfromRbChain () и rbChain () функциями:
Acad::ErrorStatus
AcDbXrecord::setFromRbChain(
resbuf& pRb,
AcDbDatabase* auxDb=NULL);
Acad::ErrorStatus
AcDbXrecord::rbChain(
resbuf** ppRb,
AcDbDatabase* auxDb=NULL) const;
93
Диапазоны кодов DXF-групп для xrecords
From To DataType
1 4 Text
6 9 Text
10 17 Point or vector (3 reals)
38 59 Real
60 79 16-bit integer
90 99 32-bit integer
102 102 Control string “{“ or “}”
140 149 real
170 179 16-bit integer
210 219 Real
270 279 16-bit integer
280 289 8-bit integer
300 309 Text
310 319 Binary chunk
320 329 Handle
330 339 Soft pointer ID
340 349 Hard pointer ID
350 359 Soft ownership ID
360 369 Hard ownership ID
Для описания жестких и мягких владельцев и указателей, см. главу 12, “ Происходящий от AcDbObject. ”
Примеры
Следующие ObjectARX примеры состоят из двух функций: createXrecord () и listXrecord (). Первая функция
добавляет новый xrecord к словарю, добавляет словарь к словари имен объектов, и затем добавляет данные к
xrecord. ListXrecord () функция открывает xrecord, получает его список данных, и посылает список, который
будет напечатан.
void
createXrecord()
{
AcDbDictionary *pNamedobj, *pDict;
acdbHostApplicationServices()->workingDatabase()
->getNamedObjectsDictionary(pNamedobj, AcDb::kForWrite);
// Check to see if the dictionary we want to create is
// already present. If not, then create it and add
// it to the named object dictionary.
//
if (pNamedobj->getAt("ASDK_DICT", (AcDbObject*&) pDict,
AcDb::kForWrite) == Acad::eKeyNotFound)
{
pDict = new AcDbDictionary;
AcDbObjectId DictId;
pNamedobj->setAt("ASDK_DICT", pDict, DictId);
}
pNamedobj->close();
// Add a new xrecord to the ASDK_DICT dictionary.
//
AcDbXrecord *pXrec = new AcDbXrecord;
AcDbObjectId xrecObjId;
pDict->setAt("XREC1", pXrec, xrecObjId);
pDict->close();
// Create a resbuf list to add to the xrecord.
//
struct resbuf *pHead;
ads_point testpt = {1.0, 2.0, 0.0};
pHead = acutBuildList(AcDb::kDxfText,
"This is a test Xrecord list",
AcDb::kDxfXCoord, testpt,
AcDb::kDxfReal, 3.14159,
AcDb::kDxfAngle, 3.14159,
AcDb::kDxfColor, 1,
AcDb::kDxfInt16, 180,
0);
// Add the data list to the xrecord. Notice that this
// member function takes a reference to resbuf, NOT a
// pointer to resbuf, so you must dereference the
// pointer before sending it.
//
pXrec->setFromRbChain(*pHead);
94
acutRelRb(pHead);
pXrec->close();
}
Введение
Приложения ObjectArx могут быть созданы, чтобы воспользоваться преимуществом Microsoft
Фундаментальный класс (MFC) библиотека. Эта глава обсуждает, как формировать ваш
Приложения ObjectArx, чтобы использовать MFC и как встроенный AutoCAD
MFC система может использоваться, чтобы создать диалоги, которые ведут себя и работают
AutoCAD.
95
MFC и Немодальные Диалоговые окна
Так как AutoCAD пытается забирать центр от всех его дочерних окон, немодальные диалоги имеют
специальное требование. Равномерно, немодальный диалог получит сообщение окна
WM_ACAD_KEEPFOCUS, которое определено в adscodes.h как 1001. Когда ваш диалог получает это
сообщение, это возвратило бы ИСТИНУ, если это сохранило центр. Если ответ на это сообщение ЛОЖНЫЙ
(который является также значением по умолчанию), то ваше диалоговое окно будет терять центр, как только
пользователь перемещает указатель от окна поля диалога.
Вы можете делать это с картой сообщения поля диалога, и ON_MESSAGE () объявление типа
В этом примере, диалоговый класс приложения - HelloDlg, который получен из CDialog. Когда Вы добавляете
этот вход в карту сообщения, Вы должны также записать функцию обработчика для сообщения.
Предположите, что Вы написали функцию, вызвал keepTheFocus(), который возвращает ИСТИНУ, если ваш
диалог хочет сохранить фокус ввода и ЛОЖЬ, если диалог желает выдавать фокус AutoCAD. Обработчик
сообщения примера обеспечивается здесь:
Управление ресурсами
Управление ресурсами - важное соображение{*рассмотрение*} при проектировании Приложения ObjectArx,
которое использует MFC библиотеку, общедоступную с AutoCAD и другими приложениями.
Вы должны вставить ваше состояние модуля (использование CDynaLinkLibrary) в цепочку, которую MFC
исследует, когда это исполняет операции типа расположения ресурса.
Однако, строго рекомендуется, чтобы Вы явно управляли ресурсами вашего приложения так, чтобы они не
нашлись в противоречии с другими ресурсами от AutoCAD или других Приложений ObjectArx.
Явно устанавливать ресурсы
1 Перед взятием любых шагов, которые вызвали бы MFC, чтобы искать ваш ресурс, вызывают функцию AFX
AfxSetResourceHandle() чтобы установить заказной ресурс как системное значение по умолчанию.
2 Перед установкой системного ресурса к вашему ресурсу, вызовите AfxGetResourceHandle() чтобы получить
текущий системный ресурс.
3 Немедленно после выполнения любых функций, которые требуют, заказной ресурс, системный ресурс
должен быть сброшен к маркеру{*дескриптору*} ресурса, предварительно сохраненному.
Запрос функций API AutoCAD (или при вызове команд AutoCAD) внутри диалога командует обработчиком,
который нуждается в ресурсах AutoCAD, типа acedGetFileD (), задерживает ресурс к AutoCAD перед запросом
функций.
Восстановите ваш прикладной ресурс впоследствии. (Используйте acedGetAcadResourceInstance () чтобы
получить маркер{*дескриптор*} ресурса AutoCAD.)
96
CAcExtensionModule Класс
ObjectARX SDK обеспечивает два простых класса C++, которые могут использоваться, чтобы делать
управление ресурсами проще. CACEXTENSIONMODULE класс обслуживает две цели —, это обеспечивает
метку - заполнитель для структуры AFX_EXTENSION_MODULE (обычно имел обыкновение инициализировать
или заканчивать MFC расширение{*продление*} DLL) и прослеживает двух проводников{*средств доступа*}
ресурса для DLL. Проводники{*средства доступа*} ресурса - модуль
Ресурсы (которые являются обычно DLL непосредственно, но могут быть установлены в некоторый другой
модуль) и заданные по умолчанию ресурсы (обычно ведущее приложение, но - фактически
проводник{*средство доступа*} в настоящее время активные, когда AttachInstance () вызван{*назван*}).
CAcExtensionModule прослеживает их, чтобы упростить переключение MFC поиск ресурса между значением
по умолчанию и модулем. DLL должен создать один образец этого класса и обеспечивать выполнение для
класса.
CAcModuleResourceOverride Класс
Используйте образец этого класса, чтобы переключить между средствами доступа ресурса. Когда объект
создан, новое средство доступа ресурса переключится в. После разрушения, первоначальное средство
доступа ресурса будет восстановлено. Следующий код обеспечивает пример:
Пусто MyFunc ()
{
CAcModuleResourceOverride myResources;
}
После входа в эту функцию ресурсы модуля будут выбраны. Когда функциональные возвращения, заданные
по умолчанию ресурсы будут восстановлены. Перегрузка ресурса может использоваться способом из трех
путей:
Используют заданный по умолчанию конструктор (никакие параметры) чтобы переключить к ресурсам
модуля. Заданные по умолчанию ресурсы будут восстановлены деструктором. Ресурсы модуля по
умолчанию - поддерживаемые CAcExtensionModule DLL'S.
Передают NULL (или 0) конструктору. Ресурсы DLL'S будут выбраны и ресурсы, которые были, в
действительности будет восстановлен, когда объект перегрузки разрушен.
Передают дескриптор не-NULL к конструктору. Ресурсы связанного модуля будут выбраны и ресурсы,
которые были, в действительности будет восстановлен, когда объект перегрузки разрушен.
AC_IMPLEMENT_EXTENSION_MODULE(theArxDLL);
HINSTANCE _hdllInstance = NULL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
theArxDLL.AttachInstance(hInstance);
hdllInstance = hInstance;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
theArxDLL.DetachInstance();
}
return 1; // ok
}
97
разработчикам использовать те же самые UI функциональные возможности, найденные в AutoCAD. MFC
разработчики может без швов использовать эти классы. Перечислены ниже основные области добавленных
функциональных возможностей, обеспеченных AdUi и AcUi.
Чтобы использовать AdUi в приложении MFC-based, исходные файлы C++ проекта должны включить adui.h, и
проект должен связать adui15.lib (adui15.dll библиотека импорта).
Чтобы использовать AcUi в MFC-ОСНОВАННОМ приложении AutoCAD, исходные файлы C++ проекта должны
включить adui.h, тогда acui.h, и проект должен связать acui15.lib и adui15.lib. AutoCAD вызывает подпрограмму
инициализации библиотеки, InitAcUiDLL (), который также обрабатывает AdUi инициализацию (через
InitAdUiDLL () запрос); поэтому ваша прикладная потребность не повторно инициализирует AcUi или AdUi.
ПРЕДУПРЕЖДЕНИЕ! Хотя adui15.dll может быть вызван от приложений MFC-based других чем AutoCAD (или
другие программы Autodesk), предназначенное использование библиотеки - Autodesk и третьими лицами явно
для создания программного обеспечения, чтобы работать исключительно с AutoCAD, или другими изделиями
Autodesk. Использование этого DLL для не- AutoCADа, автономные программы не разрешаются согласно
лицензионному соглашению AutoCAD.
Иерархия Классов
Следующее - поддержанные классы в AdUi и AcUi библиотеках. Имеется подарок{*настоящее*} классов в
файлах заголовка, которые не показываются и - для внутреннего использования только и не поддержаны для
использования с ObjectARX.
98
AdUi Передача сообщений
AdUi библиотека использует внутреннюю схему передачи сообщений облегчить связь между объектами.
Типично это вовлекает контейнер (типа диалога) отвечающий на уведомление от содержащегося окна (типа
управления).
Расширенные приложения могут приспосабливать встроенную систему к их потребностям, или добавлять
AdUi поддержку передачи сообщений к другому CWND полученные классы.
99
CAcUiTabMainDialog представляет основной контейнерный диалог в AutoCAD табулированный диалог.
CAcUiTabMainDialog и CACUITABMAINDIALOG используются на месте CPROPERTYSHEET и
CPROPERTYPAGE, чтобы создать табулированные диалоги в AutoCAD.
CAcUiTabChildDialog Класс
CAcUiTabChildDialog представляет позицию табуляции в табулированном диалоге.
CAcUiTabMainDialog и CACUITABCHILDDIALOG используются на месте CPROPERTYSHEET и
CPROPERTYPAGE, чтобы создать табулированные диалоги в AutoCAD. Каждая позиция табуляции
в AutoCAD табулировала диалог - CACUITABCHILDDIALOG.
CAcUiAlertDialog Класс
CAdUiAlertDialog представляет аварийный диалог с тремя кнопками. Одна кнопка - кнопка CANCEL,
и другие два текста командной кнопки установлены программистом. Это - аварийный диалог
общего назначения.
CAcUiFileDialog Класс
CAcUiFileDialog обеспечивает Определенное автохамом образование из CADUIFILEDIALOG.
100
CAcUiEdit обеспечивает Определенное автохамом образование из CADUIEDIT.
CAcUiAngleEdit Класс
CAcUiAngleEdit получен из CACUIEDIT и обеспечивает специализированный конструктор, чтобы
гарантировать, что бит стиля AC_ES_ANGLE всегда устанавливается в маске стиля. Объекты этого
класса предназначены для использования в редактировании угловых / вращательных данных,
определенных к параметрам настройки AutoCAD.
CAcUiNumericEdit Класс
CAcUiNumericEdit получен из CACUIEDIT и обеспечивает специализированный конструктор, чтобы
гарантировать, что бит стиля AC_ES_NUMERIC всегда устанавливается в маске стиля. Объекты
этого класса предназначены для использования в редактировании числовых данных (типа
расстояния) определенный к параметрам настройки AutoCAD.
CAcUiStringEdit Класс
CAcUiStringEdit получен из CACUIEDIT и обеспечивает специализированный конструктор, чтобы
гарантировать, что бит стиля AC_ES_STRING всегда устанавливается в маске стиля. Любой ввод
приемлем.
CAcUiSymbolEdit Класс
CAcUiSymbolEdit получен из CACUIEDIT и обеспечивает специализированный конструктор, чтобы
гарантировать, что бит стиля AC_ES_SYMBOL всегда устанавливается в маске стиля. Объекты
этого класса предназначены для использования в редактировании правильных{*допустимых*}
названий{*имен*} символа AutoCAD.
CAdUiListBox Класс
CAdUiListBox специализирует MFC CListBox, чтобы обеспечить управление, которое поддерживает
AdUi передачу сообщений. Класс может использоваться, где-нибудь CLISTBOX может
использоваться. Так как это обеспечивает дополнительную контейнерно - побочную поддержку для
AdUi зарегистрированными сообщениями, удобно использовать CADUIBASEDIALOG (или
полученный класс) с CADUILISTBOX (или полученный класс) средство управления.
CAdUiListBox обеспечивает особенности, которые позволяют классу использоваться, чтобы
подклассифицировать список, включенный в поле со списком. Когда используется совместно с
CADUICOMBOBOX, список способен проследить поле со списком и, в случае владельца -
тянущегося управления, или рисунок делегата к полю со списком или обеспечивать его
собственные подпрограммы рисунка.
CAdUiListCtrl Класс
CAdUiListCtrl получен из CLISTCTRL класса, чтобы обеспечить средство управления списка. Этот
класс обеспечивает поддержку для окон совета{*предупреждения*} за обрезанные текстовые
элементы{*пункты*} (TextTips).
TextTips будет появляться за обрезанные элементы{*пункты*} заголовка для средства управления списка в
представлении{*виде*} сообщения, и для индивидуума обрезанные текстовые элементы{*пункты*} в столбцах
в теле управления списка. Нарисованное пользователем средство управления поддержано.
CAdUiHeaderCtrl
CAdUiHeaderCtrl специализирует CHEADERCTRL. Наиболее часто, CAdUiHeaderCtrl представляет
подклассифицируемый заголовок, содержащийся в управлении списка (CAdUiListCtrl).
Вы не должны подклассифицировать управление заголовка, чтобы получить поддержку TextTip для
заголовков столбца в управлении списка (обеспеченные автоматически в CADUILISTCTRL).
101
CACUIANGLECOMBOBOX конструктор автоматически создает CACUINUMERICEDIT, чтобы
подклассифицировать окно редактирования управления. Это учитывает проверку правильности
чисел{*номеров*}, определенных к параметрам настройки AutoCAD.
CAcUiStringComboBox Класс
CACUISTRINGCOMBOBOX конструктор автоматически создает CACUISTRINGEDIT, чтобы
подклассифицировать окно редактирования управления. Любой ввод приемлем.
CAcUiSymbolComboBox Класс
CACUISYMBOLCOMBOBOX конструктор автоматически создает CACUISYMBOLEDIT, чтобы
подклассифицировать окно редактирования управления. Правильные{*допустимые*}
названия{*имена*} символа AutoCAD - приемлемый ввод.
102
и Option2 отображает “ByBlock”. Каждый элемент{*пункт*} обслуживает{*поддерживает*} груз,
который передает AcDb элемента{*пункта*}:: kLnWtxxx значение.
CAcUiPlotStyleTablesComboBox Класс
CAcUiPlotStyleTablesComboBox специализирует CACUIMRUCOMBOBOX для графического выбора
таблицы стиля. Управление отображает графические названия{*имена*} таблицы стиля согласно
текущему графическому режиму стиля (цветное - зависимый режим или названные графические
стили). MRU функциональные возможности поля со списком не используются. Точечный рисунок,
указывающий внедренную адресную таблицу отображен в названном графическом режиме стиля
для тех таблиц, которые имеют внедренную адресную таблицу.
CAcUiPlotStyleNamesComboBox Класс
CAcUiPlotStyleNamesComboBox специализирует CACUIMRUCOMBOBOX для графического выбора
имени стиля. MRU функциональные возможности combo не используются, и “ByLayer”, “ByBlock”, и
“ Другой ... ” элементы{*пункты*} может быть условно отображен. Если подарок{*настоящее*}, “
Другой ... ” элемент{*пункт*} может вызывать или Назначающийся Графический диалог Стиля, или
Поток Набора Составляет график диалога Стиля.
CAcUiMRUListBox Класс
CAcUiMRUListBox происходит от CACUILISTBOX. Я t я s, используемый CACUIMRUCOMBOBOX,
чтобы подклассифицировать список управления (ComboLBox) и обеспечиваю поддержку DrawTip.
Расширенные приложения, которые используют специализированный MRU поля со списком, могут были
должны получить специальные списки MRU, чтобы отобразить DrawTips правильно.
103
CAcUiSelectButton специализирует CACUIPICKBUTTON. Это обеспечивает кнопку, которая
отображает стандартный точечный рисунок кнопки выбора.
Module-name:dialog-name
Например
104
Распространение AutoCAD Встроенные Диалоги Позиции табуляции
Мастер Класса Использования или некоторые другие средства, чтобы создать вашу позицию
табуляции, подклассифицируемую от CDIALOG. В свойствах для диалога, измените{*замените*}
стиль диалога, чтобы “всплыть” и границу к “изменению размеров”. Осуществьте перегрузку для
PostNcDestroy (). Замените все возникновения CDIALOG с CACUITABEXTENSION во всех исходных
файлах для диалога. В PostNcDestroy () для расширения{*продления*} позиции табуляции удаляют
объект позиции табуляции, который был распределен (см. пример ниже).
В вашем AcRx:: kInitAppMsg обработчик в acrxEntryPoint () добавляют запрос к
acedRegisterExtendedTab ("MYAPPNAME.ARX", "DIALOGNAME"), где MYAPPNAME - основное имя
файла вашего приложения, и DIALOGNAME - изданное имя расширяемого табулированного
диалога, к которому Вы желаете добавить.
Осуществьте AcRx:: kInitDialogMsg обработчик в acrxEntryPoint () и добавьте позицию табуляции
там. (Пусто *) appId параметр к acrxEntryPoint () - указатель CAcUiTabExtensionManager.
Используйте функцию GetDialogName члена () для CACUITABEXTENSIONMANAGER, чтобы
получить имя инициализируемого диалога и, если приложение хочет добавить к этому диалогу,
назовите AddTab () функцией члена CACUITABEXTENSIONMANAGER, чтобы добавить позицию
табуляции. Один параметр к этой функции - указатель на предварительно распределенный объект
CAcUiTabExtension. Если диалог изменяемого размера, и Вы хотите некоторых из вашего средства
управления, чтобы изменять размеры, добавить что изменение размеров кода после запроса к
AddTab ().
Например
void initApp()
{
InitMFC();
// Do other initialization tasks here.
acedRegCmds->addCommand(
"MYARXAPP",
"MYARXAPP",
"MYARXAPP",
ACRX_CMD_MODAL,
&MyArxAppCreate);
// Here is where we register the fact that we want to add
// a tab to the PREFERENCES dialog.
acedRegisterExtendedTab("MYARXAPP.ARX", "PREFERENCES");
}
105
pTab1->StretchControlXY(IDC_EDIT1, 100, 100);
}
void CMyTab1::PostNcDestroy()
// Override to delete added tab.
{
delete pTab1;
pTab1 = NULL;
CAcUiTabExtension::PostNcDestroy();
}
void dialogCreate()
{
acutPrintf("\nAcUi Dialog Sample");
}
// Entry point
//
extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* appId)
{
switch( msg )
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(appId);
106
acrxDynamicLinker->registerAppMDIAware(appId);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
case AcRx::kInitDialogMsg:
break;
default:
break;
}
return AcRx::kRetOK;
}
#include "AsdkAcUiSample.h"
#include "AcExtensionModule.h"
Вы будете также должны добавить ObjectARX библиотеки к проектному файлу, заменять .dll расширение к
.arx, и изменять .def файл надлежащим экспортом. Тогда Вы должны быть способны компилировать и
загрузить приложение.
107
8 Теперь мы изменим{*заменим*} типы, чтобы использовать средство управления AcUi. Начало, открывая
AsdkAcUiDialogSample.h файл. Измените{*замените*} список управления, чтобы быть следующим:
CAcUiSymbolComboBox m_ctrlRegAppComboBox;
CacUiListBox m_ctrlBlockListBox;
CAcUiPickButton m_ctrlPickButton;
CacUiPickButton m_ctrlAngleButton;
CacUiAngleEdit m_ctrlAngleEdit;
CAcUiNumericEdit m_ctrlXPtEdit;
CAcUiNumericEdit m_ctrlYPtEdit;
CAcUiNumericEdit m_ctrlZPtEdit;
9 Также добавляют пару полей, чтобы проследить точку и угловые значения и некоторые функции помощника.
Они должны быть добавлены к общественному разделу класса:
AcGePoint3d m_ptValue;
double m_dAngle;
void DisplayPoint();
bool ValidatePoint();
void DisplayAngle();
bool ValidateAngle();
void DisplayBlocks();
void DisplayRegApps();
AsdkAcUiDialogSample::AsdkAcUiDialogSample
(CWnd* pParent /*=NULL*/)
: CAcUiDialog(AsdkAcUiDialogSample::IDD, pParent)
Message handlers
Handler Function Resource ID Message
OnButtonAngle IDC_BUTTON_ANGLE BN_CLICKED
OnButtonPoint IDC_BUTTON_POINT BN_CLICKED
OnOk IDOK BN_CLICKED
OnKillfocusComboRegapps IDC_COMBO_REGAPPS CBN_KILLFOCUS
OnKillfocusEditAngle IDC_EDIT_ANGLE EN_KILLFOCUS
OnKillfocusEditXpt IDC_EDIT_XPOINT EN_KILLFOCUS
OnKillfocusEditYpt IDC_EDIT_YPOINT EN_KILLFOCUS
OnKillfocusEditZpt IDC_EDIT_ZPOINT EN_KILLFOCUS
// Utility functions
void AsdkAcUiDialogSample::DisplayPoint()
{
m_ctrlXPtEdit.SetWindowText(m_strXPt);
m_ctrlXPtEdit.Convert();
m_ctrlYPtEdit.SetWindowText(m_strYPt);
m_ctrlYPtEdit.Convert();
m_ctrlZPtEdit.SetWindowText(m_strZPt);
m_ctrlZPtEdit.Convert();
}
108
bool AsdkAcUiDialogSample::ValidatePoint()
{
if (!m_ctrlXPtEdit.Validate())
return false;
if (!m_ctrlYPtEdit.Validate())
return false;
if (!m_ctrlZPtEdit.Validate())
return false;
return true;
}
void AsdkAcUiDialogSample::DisplayAngle()
{
m_ctrlAngleEdit.SetWindowText(m_strAngle);
m_ctrlAngleEdit.Convert();
}
bool AsdkAcUiDialogSample::ValidateAngle()
{
if (!m_ctrlAngleEdit.Validate())
return false;
return true;
}
2 Теперь добавляют некоторые сервисные функции, чтобы выполнить итерации более чем двух таблиц
идентификаторов и отображать названия{*имена*} в двух различных списках:
void AsdkAcUiDialogSample::DisplayBlocks()
{
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
// Iterate through the block table and display
// the names in the list box.
//
char *pName;
AcDbBlockTableIterator *pBTItr;
if (pBlockTable->newIterator(pBTItr) == Acad::eOk) {
while (!pBTItr->done()) {
AcDbBlockTableRecord *pRecord;
if (pBTItr->getRecord(pRecord, AcDb::kForRead)
== Acad::eOk) {
pRecord->getName(pName);
m_ctrlBlockListBox.InsertString(-1, pName);
pRecord->close();
}
pBTItr->step();
}
}
pBlockTable->close();
}
void AsdkAcUiDialogSample::DisplayRegApps()
{
AcDbRegAppTable *pRegAppTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pRegAppTable, AcDb::kForRead);
// Iterate through the reg app table and display the
// names in the list box.
//
char *pName;
AcDbRegAppTableIterator *pItr;
if (pRegAppTable->newIterator(pItr) == Acad::eOk) {
while (!pItr->done()) {
AcDbRegAppTableRecord *pRecord;
if (pItr->getRecord(pRecord, AcDb::kForRead)
== Acad::eOk) {
pRecord->getName(pName);
m_ctrlRegAppComboBox.InsertString(-1, pName);
pRecord->close();
}
pItr->step();
}
}
pRegAppTable->close();
}
109
3 Добавляют объявления для функций и переменных к определению класса файл заголовка:
void DisplayPoint();
bool ValidatePoint();
void DisplayAngle();
bool ValidateAngle();
void DisplayBlocks();
void DisplayRegApps();
CString m_strAngle;
CString m_strXPt;
CString m_strYPt;
CString m_strZPt;
4 Затем - обработчики кнопки для выбора точки и угла, используя редактора AutoCAD. Обратите внимание,
как BeginEditorCommand (), CompleteEditorCommand (), и CancelEditorCommand () функции используются,
чтобы скрыть диалог, позволять запрос к acedGetPoint и acedGetAngle, и наконец или отменять или
восстанавливать изображение диалога, основанного на как выбранный пользователь:
void AsdkAcUiDialogSample::OnButtonAngle()
{
// Hide the dialog and give control to the editor
//
BeginEditorCommand();
// Set up the default point for picking an angle
// based on the m_strXPt, m_strYPt, and m_strZPt values
//
ads_point pt;
acdbDisToF(m_strXPt, -1, &pt[X]);
acdbDisToF(m_strYPt, -1, &pt[Y]);
acdbDisToF(m_strZPt, -1, &pt[Z]);
double angle;
// Get a point from the user
//
if (acedGetAngle(pt, "\nPick an angle: ", &angle) == RTNORM) {
// If we got an angle, go back to the dialog
//
CompleteEditorCommand();
// Convert the acquired radian value to degrees since the
// AcUi control can convert that to the other formats.
//
m_strAngle.Format("%g", angle*(180.0/PI));
DisplayAngle();
} else {
// otherwise cancel the command (including the dialog)
//
CancelEditorCommand();
}
}
void AsdkAcUiDialogSample::OnKillfocusEditAngle()
{
110
// Get and update text the user typed in.
//
m_ctrlAngleEdit.Convert();
m_ctrlAngleEdit.GetWindowText(m_strAngle);
}
void AsdkAcUiDialogSample::OnKillfocusEditXpt()
{
// Get and update text the user typed in.
//
m_ctrlXPtEdit.Convert();
m_ctrlXPtEdit.GetWindowText(m_strXPt);
}
void AsdkAcUiDialogSample::OnKillfocusEditYpt()
{
// Get and update text the user typed in.
//
m_ctrlYPtEdit.Convert();
m_ctrlYPtEdit.GetWindowText(m_strYPt);
}
void AsdkAcUiDialogSample::OnKillfocusEditZpt()
{
// Get and update text the user typed in.
//
m_ctrlZPtEdit.Convert();
m_ctrlZPtEdit.GetWindowText(m_strZPt);
}
6 обработчик поля со списком позволяет пользователю напечатывать строку и затем регистрировать это как
прикладное имя. Это действительно не имеет смысл для приложения, но это показывает использованию поля
со списком:
void AsdkAcUiDialogSample::OnKillfocusComboRegapps()
{
CString strFromEdit;
m_ctrlRegAppComboBox.GetWindowText(strFromEdit);
if (m_ctrlRegAppComboBox.FindString(-1, strFromEdit) == CB_ERR)
if (acdbRegApp(strFromEdit) == RTNORM)
m_ctrlRegAppComboBox.AddString(strFromEdit);
}
7, чтобы делать некоторую проверку правильности данных, мы обрабатываем это в OnOk () обработчик. Это,
конечно, может быть сделано в любое время. Также обратите внимание, что OnOk () обработчик сохраняет
данные в параметр пользователя (системный реестр), используя SetDialogData () функция:
void AsdkAcUiDialogSample::OnOK()
{
if (!ValidatePoint()) {
AfxMessageBox("Sorry, Point out of desired range.");
m_ctrlXPtEdit.SetFocus();
return;
}
if (!ValidateAngle()) {
AfxMessageBox("Sorry, Angle out of desired range.”);
m_ctrlAngleEdit.SetFocus();
return;
}
// Store the data into the registry
//
SetDialogData("ANGLE", m_strAngle);
SetDialogData("POINTX", m_strXPt);
SetDialogData("POINTY", m_strYPt);
SetDialogData("POINTZ", m_strZPt);
CAcUiDialog::OnOK();
}
BOOL AsdkAcUiDialogSample::OnInitDialog()
{
// Set the dialog name for registry lookup and storage
//
SetDialogName("AsdkAcUiSample:AsdkAcUiDialog");
111
CAcUiDialog::OnInitDialog();
DLGCTLINFOdlgSizeInfo[]= {
{ IDC_STATIC_GROUP1, ELASTICX, 20 },
{ IDC_STATIC_GROUP1, ELASTICY, 100 },
{ IDC_EDIT_XPT,ELASTICX, 20 },
{ IDC_EDIT_YPT,ELASTICX, 20 },
{ IDC_EDIT_ZPT,ELASTICX, 20 },
{ IDC_EDIT_ANGLE, ELASTICX, 20 },
{ IDC_STATIC_GROUP2, MOVEX, 20 },
{ IDC_STATIC_GROUP2, ELASTICY, 100 },
{ IDC_STATIC_GROUP2, ELASTICX, 80 },
{ IDC_LIST_BLOCKS, MOVEX, 20 },
{ IDC_LIST_BLOCKS, ELASTICY, 100 },
{ IDC_STATIC_TEXT2,MOVEX, 20 },
{ IDC_STATIC_TEXT2,MOVEY, 100 },
{ IDC_LIST_BLOCKS, ELASTICX, 80 },
{ IDC_STATIC_TEXT2,ELASTICX, 80 },
{ IDC_STATIC_GROUP3, MOVEY, 100 },
{ IDC_STATIC_GROUP3, ELASTICX, 20 },
{ IDC_COMBO_REGAPPS, MOVEY, 100 },
{ IDC_COMBO_REGAPPS, ELASTICX, 20 },
{ IDC_STATIC_TEXT3,MOVEY, 100 },
{ IDC_STATIC_TEXT3,ELASTICX, 20 },
{ IDOK,MOVEX, 100 },
{ IDCANCEL, MOVEX, 100 },
};
const DWORD numberofentries =
sizeof dlgSizeInfo / sizeof DLGCTLINFO;
SetControlProperty(dlgSizeInfo, numberofentries);
// Must be within a 100-unit cube centered about 0,0,0.
//
m_ctrlXPtEdit.SetRange(-50.0, 50.0);
m_ctrlYPtEdit.SetRange(-50.0, 50.0);
m_ctrlZPtEdit.SetRange(-50.0, 50.0);
// Must be between 0 and 90 degrees.
//
m_ctrlAngleEdit.SetRange(0.0, 90.0 /*(PI/2.0)*/);
// Assign a title for the dialog.
//
SetWindowText("AcUiDialog Sample");
// Load the default bitmaps.
//
m_ctrlPickButton.AutoLoad();
m_ctrlAngleButton.AutoLoad();
// Get and display the preserved data from the registry.
//
if (!GetDialogData("ANGLE", m_strAngle))
m_strAngle = "0.0";
if (!GetDialogData("POINTX", m_strXPt))
m_strXPt = "0.0";
if (!GetDialogData("POINTY", m_strYPt))
m_strYPt = "0.0";
if (!GetDialogData("POINTZ", m_strZPt))
m_strZPt = "0.0";
DisplayPoint();
DisplayAngle();
DisplayBlocks();
DisplayRegApps();
return TRUE; // return TRUE unless you set the focus to a control
}
112
Набор Выборов и имена Примитива
Большинство функций ObjectARX, которые обрабатывают наборы выбора и примитивы,
идентифицирует{*выделяет*} набор или примитив его именем, которое является парой longs, назначенного и
поддерживаемого AutoCAD. В ObjectARX, названия{*имена*} наборов выбора и примитивов имеют
соответствующий тип ads_name.
Прежде, чем это может управлять набором выборов или примитивом, приложение ObjectARX должно
получить текущее имя набора или примитива, вызывая одну из библиотечных функций, который возвращает
набор выборов или имя примитива.
ОБРАТИТЕ ВНИМАНИЕ на набор Выборов, и названия{*имена*} примитива энергозависимы; они
применяются только, в то время как Вы работаете над рисунком к AutoCAD, и они потеряны при выходе от
AutoCAD или переключения к другому рисунку.
Для наборов выбора, которые также применяются только к текущему сеансу, энергозависимость
названий{*имен*} не излагает никакую проблему, но для примитивов, которые сохранены в базе данных
рисунка, это делает. Приложение, которое должно обратиться{*отнестись*} в разное время к тем же самым
примитивам в том же самом рисунке (или рисунки), может использовать маркеры{*дескрипторы*} примитива,
описанные в “ Маркеры{*дескрипторы*} Примитива и Их Использования ” на странице 216.
int
acedSSGet (
const char *str,
const void *pt1,
const void *pt2,
const struct resbuf *entmask,
ads_name ss);
Первый параметр к acedSSGet () - строка, которая описывает которые опции выбора использовать, как
получено в итоге в следующей таблице.
Следующие два параметра определяют значения точки для уместных опций. (Они должны быть NULL, если
они не применяются.) Если четвертый параметр, entmask, - не NULL, это указывает на список значений поля
примитива, используемых в фильтрации. Пятый параметр, ss, идентифицирует имя набора выбора.
113
Следующий код показывает представителю, вызывает к acedSSGet (). Как acutBuildList () запрос
иллюстрирует, для “CP” опций многоугольника, и “ПОДГОТОВКА ТЕКСТОВ” (но не для “F”), acedSSGet ()
автоматически закрывает список точек. Вы не должны формировать список, который определяет конечную
точку, идентичную первому.
Дополнение acedSSGet () - acedSSFree (), который выпускает набор выборов, как только приложение
закончило использовать это. Набор выборов определен по имени. Следующий кодовый фрагмент использует
ads_name объявление от предыдущего примера.
acedSSFree(ssname);
ПРИМЕЧАНИЕ AutoCAD не может иметь больше чем 128 наборов выбора, открытые сразу. Этот предел
включает наборы выбора, открытые всего одновременно выполняющиеся приложения ObjectARX и AutoLISP.
Предел может быть отличен на вашей системе. Если предел достигнут, AutoCAD отказывается создавать
большее количество наборов выбора. Одновременно управление большим количеством наборов выбора не
рекомендуется. Вместо этого, сохраните разумное число наборов, открытых в любое данное время, и
вызовите acedSSFree () чтобы освободить неиспользованные наборы выбора как можно скорее. В отличие от
AutoLISP, ObjectARX среда не имеет никакой автоматической сборки "мусора", чтобы освободить наборы
выбора после того, как они использовались. Приложение должно всегда освобождать его открытые наборы
выбора, когда это получает kUnloadDwgMsg, kEndMsg, или kQuitMsg сообщение.
114
Вы можете использовать фильтр вместе с любой из опций выбора. Опция “X” говорит, что создала набор
выборов, используя только фильтрация; как в предыдущих версиях AutoCAD, если Вы используете, опция “X”,
acedSSGet () просматривает полную базу данных рисунка.
ОБРАТИТЕ ВНИМАНИЕ, определена ли только фильтрация (“X”) но entmask параметр - NULL, acedSSGet ()
выбирает все примитивы в базе данных.
Entmask параметр должен быть список буфера результата. Каждый буфер определяет свойство, чтобы
проверить{*отметить*} и значение, которое составляет соответствие; restype поле буфера - код группы DXF,
который указывает вид свойства, чтобы смотреть для, и его resval поле определяет значение, чтобы
соответствовать{*согласовать*}.
Следующее - некоторые примеры.
ОБРАТИТЕ ВНИМАНИЕ resval, указанный в каждом буфере должен иметь соответствующий тип.
Например, типы имени - строки (resval.rstring); повышение и толщина - с двойной точностью с плавающей
точкой значения (resval.rreal); цвет, признаки - следуйте, и пометьте значения - короткие целые числа
(resval.rint); векторы вытеснения - трехмерные точки (resval.rpoint); и т.д.
Если entmask определяет больше чем одно свойство, примитив включен в выбор, устанавливают только, если
это соответствует всем указанным условиям{*состояниям*}, как показано в следующем примере:
Примитив проверен против всех полей, указанных в списке фильтрации, если список не содержит
относительные или условные операторы, как описано в “ Относительные Испытания ” на странице 207 и “
Фильтрация Условного выражения ” на странице 208.
115
strcpy(sbuf1, "LINE");
eb1.resval.rstring = sbuf1; // Entity type is line.
eb1.rbnext = NULL;
eb1.restype = 8; // Layer
strcpy(sbuf1, "FLOOR9");
eb1.resval.rstring = sbuf1; // Layer name
eb1.rbnext = NULL;
// Select all the entities within the window that are also on the layer FLOOR9.
acedSSGet("W", pt1, pt2, &eb1, ssname1);
ОБРАТИТЕ ВНИМАНИЕ, что значение некоторых кодов группы может отличиться от примитива до примитива,
и не, все коды группы присутствуют во всех примитивах. Если специфический код группы определен в
фильтре, примитивы, которые не содержат тот код группы, исключены из наборов выбора, которые
acedSSGet () возвращается.
Если больше чем одно прикладное имя включены в список, acedSSGet () включает примитив в
выбор, устанавливают только, если это расширило{*продлило*} данные для всех указанных
приложений. Например, следующий код выбирает круги расширенными{*продленными*} данными,
зарегистрированными к “APP1” и “APP2”.
116
eb1.resval.rstring = sbuf1; // Circle
eb1.rbnext = &eb2;
strcpy(sbuf2, "APP[12]");
Относительные Испытания
Если Вы не определяете иначе, имеется подразумеваемый ", “равняется" испытанию между примитивом и
каждым элементом{*пунктом*} в списке фильтра. Для числовых групп (целые числа, реальные значения,
точки, и векторы), Вы можете определить другие отношения включением относительных операторов в списке
фильтра. Относительные операторы пропускают как специальные -4 группа, чей значение - строка, которая
указывает испытание, которое нужно применить к следующей группе в списке фильтра.
Следующий типовой код выбирает все круги, чей радиус больший чем или равняются 2.0:
Условная Фильтрация
Относительные операторы, только описанные - двоичные операторы. Вы можете также проверять группы,
создавая вложенные выражения Boolean те операторы условного выражения использования. Условные
операторы также определены -4 группами, но они должны быть соединены.
Следующий типовой код выбирает все круги в рисунке к радиусу 1.0 и всем линиям на уровне “ABC”.
117
eb1 = acutBuildList(-4, "<or",-4, "<and", RTDXF0,
"CIRCLE", 40, 1.0, -4, "and>", -4, "<and", RTDXF0,
"LINE", 8, "ABC", -4, "and>", -4, "or>", 0);
acedSSGet("X", NULL, NULL, &eb1, ssname1);
К выделите всё кругам, которые расширили{*продлили*} данные, зарегистрированные или на “APP1” или
“APP2”, но не оба, Вы могли использовать следующий код.
eb1 = acutBuildList(-4, "<xor", -3, "APP1", -3, "APP2", -4, "xor>", 0);
acedSSGet("X", NULL, NULL, &eb1, ssname1);
ОБРАТИТЕ ВНИМАНИЕ На acedSSAdd () функция может также использоваться, чтобы создать новый набор
выборов, как показано в следующем примере. Как с acedSSGet (), acedSSAdd () создает новый выбор,
устанавливают только, если это возвращает RTNORM.
Следующий типовой кодовый фрагмент создает набор выборов, который включает первые и последние
примитивы в текущий рисунок.
Пример выполняется правильно, даже если имеется только один примитив в базе данных (когда и
acdbEntNext () и acdbEntLast () устанавливают их параметры в то же самое имя примитива). Если acedSSAdd
() пропускают имя примитива, который является уже в наборе выборов, это игнорирует запрос и не сообщает
о ошибке.
Поскольку пример также иллюстрирует, вторые и третьи параметры к acedSSAdd () можно пропускать как то
же самое имя набора выбора. То есть если запрос успешен, набор выборов, названный обоими параметрами
содержит дополнительного члена после acedSSAdd () возвращения (если указанный примитив не был уже в
наборе выборов).
Следующий запрос удаляет примитив, с которым выбором установленный был создан в предыдущем
примере.
Если имеются больше чем один примитив в рисунке (то есть если fname и lname не равны), выбор
устанавливает ourset, теперь содержит только lname, последний{*прошлый*} примитив в рисунке.
Функция acedSSLength () возвращает число примитивов в наборе выборов, и acedSSMemb ()
испытания,является ли специфический примитив членом набора выборов. Наконец, функция acedSSName ()
возвращает имя специфического примитива в наборе выборов, используя индекс в набор (примитивы в
наборе выборов пронумерованы от 0).
118
ОБРАТИТЕ ВНИМАНИЕ, поскольку наборы выбора могут быть весьма большие, len параметр, возвращенный
acedSSLength () должен быть объявлен как длинное целое число. Я параметр, используемый как индекс в
звонит к acedSSName () должен также быть длинное целое число. (В этом контексте, стандартные
компиляторы C правильно преобразуют простое целое число.)
int rc, i, j;
ads_point pt1, pt2;
ads_matrix matrix;
ads_name ssname;
// Initialize pt1 and pt2 here.
rc = acedSSGet("C", pt1, pt2, NULL, ssname);
if (rc == RTNORM) {
// Initialize to identity.
ident_init(matrix);
// Initialize scale factors.
matrix[0][0] = matrix[1][1] = matrix[2][2] = 0.5;
// Initialize translation vector.
matrix[0][T] = 20.0;
matrix[1][T] = 5.0;
rc = acedXformSS(ssname, matrix);
}
Когда Вы вызываете acedDragGen (), Вы должны определить подобную функцию, чтобы позволить
пользователям в интерактивном режиме управлять эффектом преобразования. Объявление функции должно
иметь следующую форму:
Int scnf (ads_point запятая, ads_matrix mt)
Это должно возвратить RTNORM, если это изменило матрицу, RTNONE, если это делало не, или RTERROR,
если это обнаруживает ошибку.
AcedDragGen () функция вызывает функцию scnf, каждый раз пользователь перемещает курсор. Scnf ()
функция устанавливает новое значение матрицы mt.
119
Когда scnf () возвращения с состоянием RTNORM, acedDragGen () применяет новую матрицу к набору
выборов. Если не имеется никакой потребности изменить матрицу (для примера, если scnf () просто
отображает переходные векторы с acedGrVecs ()), scnf () должен возвратить RTNONE. В этом
случае{*регистре*}, acedDragGen () игнорирует mt и не преобразовывает набор выборов.
В следующем примере, функция заставляет матрицу просто двигаться (транслируют) набор выборов без того,
чтобы масштабировать или вращение.
int rc;
ads_name ssname;
ads_point return_pt;
// Prompt the user for a general entity selection:
if (acedSSGet(NULL, NULL, NULL, NULL, ssname) == RTNORM)
rc = acedDragGen(ssname, // The new entities
"Scale the selected objects by dragging", // Prompt
0, // Display normal cursor (crosshairs)
dragsample, // Pointer to the transform function
return_pt); // Set to the specified location
120
Функции Имени Примитива
Чтобы работать на примитиве, ObjectARX-приложение должно получить его имя для использования в
последующем, вызывает{*звонит*} к функциям данных примитива или функциям набора выбора.
Функции acedEntSel (), acedNEntSelP (), и acedNEntSel () возвращение не только имя примитива но и
дополнительная информация для использования приложения. Функции entsel требуют пользователей
AutoCAD (или приложение) чтобы выбрать примитив, определяя точку на графическом экране; все другие
функции имени примитива могут восстановить{*отыскивать*} примитив, даже если это не видимо на экране
или находится на закрепляемом уровне. Подобно acedGetxxx () функции, Вы можете иметь acedEntSel (),
acedNEntSelP (), и acedNEntSel () возвращают ключевое слово вместо точки, предшествуя им с запросом к
acedInitGet ().
Если запрос к acedEntSel (), acedNEntSelP (), или acedNEntSel () возвращает RTERROR, и Вы хотите знать,
определил ли пользователь точку, которая не имела никакого примитива или нажал ли пользователь
ВОЗВРАЩЕНИЕ, Вы можете осматривать значение ERRNO системной переменной. Если пользователь
определил, пустая точка, ERRNO равняется 7 (OL_ENTSELPICK). Если пользователь нажал ВОЗВРАЩЕНИЕ,
ERRNO равняется 52 (OL_ENTSELNULL). (Вы можете использовать символические названия{*имена*}, если
ваша программа включает файл заголовка.)
ПРИМЕЧАНИЕ Вы должно осмотреть ERRNO немедленно после acedEntSel (), acedNEntSelP (), или
acedNEntSel () возвращения. Последующий запрос ObjectARX может изменять{*заменять*} значение ERRNO.
Следующий типовой кодовый фрагмент использует acdbEntNext () чтобы “идти” через базу данных, один
примитив одновременно.
121
ads_name_set(ent0, ent1); // Bump the name.
} while (acdbEntNext(ent1, ent0) == RTNORM);
ПРИМЕЧАНИЕ Вы можете также пройти базу данных, “наталкиваясь” одиночная переменная в acdbEntNext ()
запрос (типа acdbEntNext (ent0, ent0)), но если Вы делаете, значение переменной, больше не определено
однажды цикл концы.
AcdbEntLast () функция отыскивает имя последнего примитива в базе данных. Последний примитив -
наиболее недавно созданный основной примитив, так что acdbEntLast () может быть вызван, чтобы получить
имя примитива, который только что был создан посредством запроса к acedCommand (), acedCmd (), или
acdbEntMake ().
AcedEntSel () функция запрашивает пользователя AutoCAD выбирать примитив, определяя точку на
графическом экране; acedEntSel () возвращает, и имя примитива и значение указанной точки. Некоторые
операции примитива требуют знания точки, которой примитив был выбран. Примеры от набора
существующих команд AutoCAD включают ПЕРЕРЫВ, ВЫРЕЗКУ, ПРОСТИРАЮТСЯ, и OSNAP.
char handle[17];
ads_name e1;
strcpy(handle, "5a2");
if (acdbHandEnt(handle, e1) != RTNORM)
acdbFail("No entity with that handle exists\n");
else
acutPrintf("%ld", e1[0]);
В одном сеансе редактирования частности, этот код мог бы распечатывать 60004722. В другом сеансе
редактирования с тем же самым рисунком, это могло бы печатать полностью отличный номер. Но в обоих
случаях, код обращается к тому же самому примитиву.
AcdbHandEnt () функция имеет дополнительное использование: примитивы, удаленные из базы данных (с
acdbEntDel ()) не очищены, пока Вы не оставляете текущий рисунок (выходя Из AutoCAD или переключая к
другому рисунку). Это означает, что acdbHandEnt () может возвращать названия{*имена*} удаленных
примитивов, которые могут тогда быть восстановлены к рисунку вторым запросом к acdbEntDel ().
ОБРАТИТЕ ВНИМАНИЕ, что расширенные данные могут включать метки примитива, чтобы сохранить
относительные структуры в рисунке. В некоторых обстоятельствах, эти метки требуют трансляции или
обслуживания. См. “ Использование метки в Расширенных Данных ” на странице 240.
ОБРАТИТЕ ВНИМАНИЕ На другое различие между acedNEntSelP () и acedEntSel () - то, что, когда
пользователь отвечает на acedNEntSelP () запрос, выбирая сложный примитив, acedNEntSelP () возвращает
выбранный подпримитив а не, заголовок сложного примитива как acedEntSel () делает. Например, когда
пользователь выбирает ломаную линию, acedNEntSelP () возвращает подпримитив вершины вместо заголовка
ломаной линии. Чтобы восстановить{*отыскивать*} заголовок ломаной линии, приложение должно
использовать acdbEntNext () чтобы идти вперед к Seqend подпримитиву и получать имя заголовка от -2 группы
Seqend подпримитива. Это истинно также, когда пользователь выбирает атрибуты во вложенной блок-ссылке
и когда точка указки определена в acedNEntSelP () запрос.
Координатное Преобразование
Первый из дополнительных параметров, возвращенных acedNEntSelP () - 4x4 матрица преобразования типа
ads_matrix. Эта матрица известна как Модель к Мировой Матрице преобразования. Это дает возможность
приложению преобразовать точки в данные определения примитива (и расширенные{*продленные*} данные,
если это присутствует) от образцовой системы координат примитива (MCS) в Мировую систему координат
(WCS). MCS применяется{*обращается*} только к вложенным примитивам. Начало координат MCS - точка
122
вставки блока, и его ориентация - таковой ВЕРХНИХ РЕГИСТРОВ, который был в действительности, когда
блок был создан.
Если выбранный примитив - не, вложенный примитив, матрица преобразования установлен в единичную
матрицу. Преобразование выражено следующим матричным умножением:
Индивидуальные координаты преобразованной точки получены от уравнений, где М. mn - Модель к Мировой
Матрице преобразования, координирует, (X, Y, Z) - точка данных определения примитива, выраженная в
координатах MCS, и (X ’, Y ’, Z ’) - заканчивающаяся точка данных определения примитива, выраженная в
координатах WCS. См. “ Матрицы Преобразования ” на странице 535.
ПРИМЕЧАНИЕ, чтобы преобразовать вектор скорее чем точка, не добавьте вектор сдвига [М. 03 М. 13 М. 23]
(от четвертого столбца матрицы преобразования).
Следующий типовой код определяет функцию, mcs2wcs (), который исполняет преобразования, описанные
предшествующими уравнениями. Требуется матрица преобразования, возвращенная acedNEntSelP () и
одиночной точкой (возможно от данных определения вложенного примитива), и возвращает
оттранслированную точку.
Если третий параметр к mcs2wcs (), is_pt, установлен в 0 (ЛЖИ), последний{*прошлый*} столбец матрицы
преобразования — вектор сдвига, или смещение — не добавлено к результату. Это дает возможность
функции транслировать вектор также как точку.
X ' = М. 00 X + М. 01 Y + М. 02 Z + М. 03
Y ' = М. 10 X + М. 11 Y + М. 12 Z + М. 13
Z ' = М. 20 X + М. 21 Y + М. 22 Z + М. 23.
ПРИМЕЧАНИЕ, чтобы преобразовать вектор скорее чем точка, не добавьте вектор сдвига [М. 03 М. 13 М. 23]
(от четвертого столбца матрицы преобразования).
Следующий типовой код определяет функцию, mcs2wcs (), который исполняет преобразования, описанные
предшествующими уравнениями. Требуется матрица преобразования, возвращенная acedNEntSelP () и
одиночной точкой (возможно от данных определения вложенного примитива), и возвращает
оттранслированную точку.
Если третий параметр к mcs2wcs (), is_pt, установлен в 0 (ЛЖИ), последний столбец матрицы преобразования
— вектор сдвига, или смещение — не добавлено к результату. Это дает возможность функции транслировать
вектор также как точку.
123
// acdbEntGet() for the selected kind of entity.
.
.
.
mcs2wcs(matrix, defpt, TRUE, wcspt);
AcedNEntSelP () функция также позволяет программе определять точку указки. Pickflag параметр определяет,
действительно ли acedNEntSelP () называется в интерактивном режиме.
В следующем примере, acedNEntSelP () запрос определяет его собственную точку для выбора примитива и не
запрашивает пользователя. Pickflag параметр ИСТИНЕН, чтобы указать, что запрос поставляет{*снабжает*}
его собственному значению точки (также, подсказка - NULL).
ads_point ownpoint;
ownpoint[X] = 2.7; ownpoint[Y] = 1.5; ownpoint[Z] = 0.0;
status = acedNEntSelP(NULL, usrent, ownpt, TRUE, matrix, &containers);
Хотя матричный формат различен, формулы эквивалентны, те для типа ads_matrix, и единственного
изменения{*замены*}, требуемого, чтобы приспособить mcs2wcs () для использования с acedNEntSel ()
должны объявить матричный параметр как массив четырех точек.
1 0 0
0 1 0
0 0 1
0 0 0
Контекстные Данные
Функция acedNEntSelP () обеспечивает параметр для контекстных данных, refstkres. (Это - другая
особенность, не обеспеченная acedEntSel ()). Refstkres параметр - указатель на список связей буферов
результатов, который содержит названия{*имена*} контейнерных блоков примитива. Список
заказывается{*упорядочивает*} от самого низкого до самого высокого. Другими словами, имя в списке - имя
блока, содержащего выбранный примитив, и фамилия в списке - имя блока, который был непосредственно
вставлен в рисунок. Следующий рисунок показывает формат этого списка.
124
Если выбранный примитив entres - не, вложенный примитив, refstkres - указатель NULL. Это - удобный способ
проверить, действительно ли координаты примитива должны быть оттранслированы. (Поскольку xformres
возвращен как единичная матрица для примитивов, которые не вложены, применяя это к координатам таких
примитивов не никакой вред, но стоит некоторое бесполезное время выполнения.)
Используя объявления от предыдущего acedNEntSelP () пример, имя блока, который немедленно содержит
выбранный пользователем примитив, может быть найден следующим кодом (в acedNEntSelP () запрос,
pickflag параметр - FALSE для интерактивного выбора).
Имя наиболее удаленного контейнера (то есть примитив, первоначально вставленный в рисунок) может быть
найдено последовательностью типа следующего:
В следующем примере, текущая система координат - WCS. Использование AutoCAD, создайте блок по имени
КВАДРАТ, состоящий из четырех линий.
Command: line
From point: 1,1
To point: 3,1
To point: 3,3
To point: 1,3
To point: c
Command: block
Block name (or ?): square
Insertion base point: 2,2
Select objects: Select the four lines you just drew
Select objects: ENTER
Command: ucs
Origin/ZAxis/3point/Entity/View/X/Y/Z/Prev/Restore/Save/Del/?/
<World>: z
Rotation angle about Z axis <0>: 45
Command: insert
Block name (or ?): square
Insertion point: 7,0
X scale factor <1> / Corner / XYZ: ENTER
Y scale factor (default=X): ENTER
125
Rotation angle: ENTER
Если ObjectARX-приложение вызывает acedNEntSelP () (или acedNEntSel ()) и пользователь выбирает левую
нижнюю сторону квадрата, эти функции заставляют entres параметр равняться имени выбранной линии. Они
устанавливают точку указки (ptres) в (6.46616, -1.0606,0.0) или близлежащее значение точки. Они возвращают
матрицу преобразования (xformres) как показано в следующем рисунке.
Наконец, они заставляют список контейнерных примитивов (refstkres) направлять на одиночный буфер
результатов содержащий имени примитива блока SQUARE.
0.70710 - 0.0 4.9497 0.70710 0.70710 0.0
7 0.70710 5 7 7
7
0.70710 0.70710 - 4.9497 - 0.70710 0.0
7 7 0.0 5 0.70710 7
7
0.0 0.0 1.0 0.0 0.0 -0.0 1.0
0.0 0.0 0.0 1.0 4.94975 4.94975 0.0
ОБРАТИТЕ ВНИМАНИЕ На использование acdbEntDel (), атрибуты, и вершина ломаной линии не может быть
удалена независимо от их родительских примитивов; acdbEntDel () работает только на основных примитивах.
Чтобы удалять атрибут или вершину, используйте acedCommand () или acedCmd () чтобы вызвать AutoCAD
ATTEDIT или команды PEDIT, используйте acdbEntMod () чтобы переопределить примитив без нежелательных
подпримитивов, или откройте вершину, или припишите, и используйте ее стирание () метод стереть это.
void getlast()
{
struct resbuf *ebuf, *eb;
ads_name ent1;
acdbEntLast(ent1);
ebuf = acdbEntGet(ent1);
eb = ebuf;
acutPrintf("\nResults of entgetting last entity\n");
// Print items in the list.
for (eb = ebuf; eb != NULL; eb = eb->rbnext)
printdxf(eb);
// Release the acdbEntGet() list.
acutRelRb(ebuf);
}
int printdxf(eb)
struct resbuf *eb;
{
int rt;
if (eb == NULL)
return RTNONE;
if ((eb->restype >= 0) && (eb->restype <= 9))
rt = RTSTR ;
else if ((eb->restype >= 10) && (eb->restype <= 19))
rt = RT3DPOINT;
else if ((eb->restype >= 38) && (eb->restype <= 59))
rt = RTREAL ;
else if ((eb->restype >= 60) && (eb->restype <= 79))
rt = RTSHORT ;
else if ((eb->restype >= 210) && (eb->restype <= 239))
rt = RT3DPOINT ;
else if (eb->restype < 0)
// Entity name (or other sentinel)
126
rt = eb->restype;
else
rt = RTNONE;
switch (rt) {
case RTSHORT:
acutPrintf("(%d . %d)\n", eb->restype,
eb->resval.rint);
break;
case RTREAL:
acutPrintf("(%d . %0.3f)\n", eb->restype,
eb->resval.rreal);
break;
case RTSTR:
acutPrintf("(%d . \"%s\")\n", eb->restype,
eb->resval.rstring);
break;
case RT3DPOINT:
acutPrintf("(%d . %0.3f %0.3f %0.3f)\n",
eb->restype,
eb->resval.rpoint[X], eb->resval.rpoint[Y],
eb->resval.rpoint[Z]);
break;
case RTNONE:
acutPrintf("(%d . Unknown type)\n", eb->restype);
break;
case -1:
case -2:
// First block entity
acutPrintf("(%d . <Entity name: %8lx>)\n", eb->restype, eb->resval.rlname[0]);
}
return eb->restype;
}
Command: line
From point: 1,2
To point: 6,6
To point: ENTER
Буфер результатов в начале списка (с -1 кодом стража) содержит имя примитива, который этот
список представляет. AcdbEntMod () функциональные использования это, чтобы идентифицировать
примитив, который нужно изменить.
Коды для компонентов примитива (сохраненный в restype поле) - используемые DXF. Как с DXF,
элементы заголовка примитива возвращены только, если они имеют значения другие чем значение
по умолчанию. В отличие от DXF, необязательные поля определения примитива возвращены
независимо от того, равняются ли они их значениям по умолчанию. Это упрощает обработку;
приложение может всегда предполагать, что эти поля присутствуют. Также в отличие от DXF,
связанного X, Y, и координат Z возвращены как одиночная переменная точки (resval.rpoint), не как
отдельный X (10), Y (20), и Z (30) групп. Значение restype содержит номер группы координаты X (в
диапазоне 10-19).
127
Чтобы находить группу с определенным кодом, приложение может пересекать список. Entitem ()
функция, показанная здесь ищет список буфера результата группу указанного типа.
Если код группы DXF, указанный gcode параметром - не подарок{*настоящее*} в списке (или если
gcode - не, правильная{*допустимая*} группа DXF), entitem () “ уменьшается конец ” и возвращает
NULL. Обратите внимание, что entitem () эквивалентен функции AutoLISP (assoc).
AcdbEntMod () функция изменяет примитив. Это передает список, который имеет тот же самый
формат как список, возвращенный acdbEntGet (), но с некоторыми из значений группы примитива
(возможно) изменяемых приложением. Эти функциональные дополнения acdbEntGet (); первичные
средства, которыми ObjectARX-приложение модифицирует базу данных -
восстанавливая{*отыскивая*} примитив с acdbEntGet (), изменяя его список примитива, и затем
пропуская список назад к базе данных с acdbEntMod ().
ОБРАТИТЕ ВНИМАНИЕ, чтобы восстановить значение по умолчанию цвета примитива или linetype,
использовать acdbEntMod () чтобы установить цвет в 256, который является BYLAYER, или linetype
к BYLAYER.
Приложение может также добавлять примитив к базе данных рисунка, вызывая acdbEntMake ()
функция. Подобно acdbEntMod (), параметр к acdbEntMake () - список буфера результата, чей
формат подобен таковому списка, возвращенного acdbEntGet (). (AcdbEntMake () запрос
игнорирует поле имени примитива [-1], если это присутствует.) новый примитив добавлен в конец к
базе данных рисунка (это становится последним{*прошлым*} примитивом в рисунке). Если
примитив - сложный примитив (ломаная линия или блок), это не добавлено в конец к базе данных,
пока это не закончено.
Следующий типовой кодовый фрагмент создает круг на уровне MYLAYER.
128
int status;
struct resbuf *entlist;
ads_point center = {5.0, 7.0, 0.0};
char *layer = "MYLAYER";
entlist = acutBuildList(RTDXF0, "CIRCLE",// Entity type
8, layer, // Layer name
10, center, // Center point
40, 1.0, // Radius
0 );
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake buffer.
if (status == RTERROR) {
acdbFail("Unable to make circle entity\n");
return BAD;
}
Сложные примитивы
Сложный примитив (ломаная линия или блок) должен быть создан множителем, вызывает к
acdbEntMake(), используя отдельный запрос каждый подпримитив. Когда acdbEntMake() сначала
получает начальный компонент для сложного примитива, это создает временный файл, чтобы
собрать данные определения (и расширенные данные, если есть). Каждый последующий
acdbEntMake() запрос добавляет новый подпримитив к файлу. Когда определение сложного
примитива закончено (то есть когда acdbEntMake() получает соответствующий Seqend или Endblk
подпримитив), примитив проверен для последовательности, и если допустимо, это добавлено к
рисунку.
Файл удален, когда сложный примитив закончен или когда его создание отменено.
Следующий пример содержит пять, вызывает acdbEntMake () которые создают одиночный сложный
примитив, ломаную линию. Ломаная линия имеет linetype ПОДЧЕРКНУТОГО ШТРИХОВОЙ
ЛИНИЕЙ и цвет СИНИХ. Это имеет три вершина, расположенные в (1,1,0) координатах, (4,6,0), и
(3,2,0). Все другие необязательные данные определения принимают значения по умолчанию.
int status;
struct resbuf *entlist, result;
ads_point newpt;
entlist = acutBuildList(
RTDXF0, "POLYLINE",// Entity type
62, 5, // Color (blue)
6, "dashed",// Linetype
66, 1, // Vertices follow.
0);
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake() buffer.
if (status != RTNORM) {
acutPrintf ("%d",status);
acedGetVar ("ERRNO", &result);
acutPrintf ("ERRNO == %d, result.resval.rint);
acdbFail("Unable to start polyline\n");
return BAD;
}
newpt[X] = 1.0;
newpt[Y] = 1.0;
newpt[Z] = 0.0; // The polyline is planar
entlist = acutBuildList(
RTDXF0, "VERTEX", // Entity type
62, 5, // Color (blue)
6, "dashed", // Linetype
10, newpt, // Start point
0);
129
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake() buffer.
if (status != RTNORM) {
acdbFail("Unable to add polyline vertex\n");
return BAD;
}
newpt[X] = 4.0;
newpt[Y] = 6.0;
entlist = acutBuildList(
RTDXF0, "VERTEX", // Entity type
62, 5, // Color (blue)
6, "dashed", // Linetype
10, newpt, // Second point
0);
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake() buffer.
if (status != RTNORM) {
acdbFail("Unable to add polyline vertex\n");
return BAD;
}
newpt[X] = 3.0;
newpt[Y] = 2.0;
entlist = acutBuildList(
RTDXF0, "VERTEX", // Entity type
62, 5, // Color (blue)
6, "dashed", // Linetype
10, newpt, // Third point
0);
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake() buffer.
if (status != RTNORM) {
acdbFail("Unable to add polyline vertex\n");
return BAD;
}
entlist = acutBuildList(
RTDXF0, "SEQEND", // Sequence end
62, 5, // Color (blue)
6, "dashed", // Linetype
0);
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake() buffer.
if (status != RTNORM) {
acdbFail("Unable to complete polyline\n");
return BAD;
}
Создание блока подобно, за исключением того, что, когда acdbEntMake () успешно создает Endblk
примитив, это возвращает значение RTKWORD. Вы можете проверять имя нового блока запросом
к acedGetInput ().
Анонимные Блоки
Вы можете создавать анонимные блоки, вызывая acdbEntMake (). Чтобы делать так, Вы должны открыть блок
с именем, чей первый символ - * и блочный флажок типа (группа 70) чей младший бит установлен в 1.
AutoCAD назначает новый анонимный блок имя; символы в строке имени, которые следуют за *, часто
игнорируются. Вы тогда создаете анонимный блок, путем Вы создали бы регулярный блок, за исключением
того, что это более важно вызвать acedGetInput ().
Поскольку имя сгенерировано в соответствии с AutoCAD, ваша программа не имеет никакого другого пути
знания имени нового блока.
Следующий код начинает анонимный блок, заканчивает его, и возвращает его имя.
130
int status;
struct resbuf *entlist;
ads_point basept;
char newblkname[20];
ads_point pnt1 = ( 0.0, 0.0, 0.0);
entlist = acutBuildList(
RTDXF0, "BLOCK",
2, "*ANON", // Only the ’*’ matters.
10, "1", // No other flags are set.
0 );
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake buffer.
if (status != RTNORM) {
acdbFail("Unable to start anonymous block\n");
return BAD;
}
// Add entities to the block by more acdbEntMake calls.
.
.
.
entlist = acutBuildList(RTDXF0, "ENDBLK", 0 );
if (entlist == NULL) {
acdbFail("Unable to create result buffer list\n");
return BAD;
}
status = acdbEntMake(entlist);
acutRelRb(entlist); // Release acdbEntMake buffer.
if (status != RTKWORD) {
acdbFail("Unable to close anonymous block\n");
return BAD;
}
status = acedGetInput(newblkname);
if (status != RTNORM) {
acdbFail("Anonymous block not created\n");
return BAD;
}
К ссылке анонимный блок, создайте примитив вставки с acdbEntMake() (Вы не можете передавать
анонимный блок к команде INSERT.)
Продолжая предыдущий пример, следующий кодовый фрагмент вставляет анонимный блок в (0,0).
131
В следующем примере, первый примитив в текущем рисунке - ломаная линия с несколькими вершиной.
Следующий код изменяет вторую вершину ломаной линии и затем восстанавливает его отображаемое
изображение.
Параметр acdbEntUpd() может определить или основной примитив или - tity; в любом случае, acdbEntUpd()
восстанавливает полный примитив. Хотя его первичное использование - для сложных примитивов,
acdbEntUpd() может восстанавливать любой примитив в текущем рисунке.
ОБРАТИТЕ ВНИМАНИЕ, когда расширенные данные отысканы acdbEntGetX (), начало расширенных данных
обозначено -3 кодом стража; -3 страж находится в буфере результатов, который предшествует первой 1001
группе. 1001 группа содержит прикладное имя первого отысканного приложения, как показано в рисунке.
132
Организация Расширенных Данных
Расширенные данные состоят из одного или большее количество 1001 групп, каждая из которых начинается с
уникального прикладного имени. Прикладные названия - строковые значения. Расширенные группы данных
возвратились acdbEntGetX () следуют за данными определения в порядке, в котором они сохранены в базе
данных.
Строка 1000. Строки в расширенных данных могут быть до длиной 255 байтов (с 256-ым байтом,
зарезервированным для нулевого символа).
Прикладно 1001 (также строковое значение). Прикладные названия могут быть до длиной 31 байтов
е имя (32-ой байт зарезервирован для нулевого символа) и должен твердо придержаться правил
для названий таблицы идентификаторов (типа названий уровня). Прикладное имя может
содержать символы, цифры, и специальные символы $ (долларовый признак), - (дефис), и
_ (символ подчеркивания). Это не может содержать пробелы. Символы на имя
преобразованы к верхнему регистру.
Если Вы пытаетесь добавлять 1001 группу, но никакие другие расширенные данные к существующему
примитиву, попытка игнорируется. Если Вы пытаетесь делать примитив, чей только расширенная группа
данных - сингл 1001 группа, сбои попытки.
133
вложены.) Когда это читает расширенные данные, проверки AutoCAD, чтобы
гарантировать что фигурные скобки сбалансированы правильно.
Двоичные данные 1004. Двоичные данные организованы в куски переменной длины, которые могут
быть обработаны в ObjectARX со структурой ads_binary. Максимальная длина
каждого куска - 127 байтов.
Позиция в мировых 1011. В отличие от простой трехмерной точки, мировые пространственные
координатах координаты перемещены, масштабируются, вращаются, и отражены наряду с
родительским примитивом, которому расширенные данные принадлежат. Мировая
пространственная позиция также протянута, когда команда STRETCH применяется к
родительскому примитиву и этой лжи точки в пределах окна выбора.
Мировое 1012. Трехмерная точка, которая масштабируется, вращается, или отражена наряду с
пространственное родителем, но не протянута или перемещена.
смещение
Мировое 1013. Также трехмерная точка, которая вращается, или отражена наряду с
направление родителем, но не масштабируется, протянута, или перемещена. Мировое
направление - нормализованное смещение, которое всегда имеет длину модуля.
Расстояние 1041. Реальное значение, которое масштабируется наряду с родительским
примитивом.
Коэффициент 1042. Также реальное значение, которое масштабируется наряду с родителем.
Масштаба
ОБРАТИТЕ ВНИМАНИЕ, появляется ли 1001 группа в пределах списка, это обработано как строка и не
начинает новую прикладную группу.
Регистрация Приложения
Прикладные названия сохранены с расширенными данными каждого примитива, который использует их и в
APPID таблице. Приложение должно регистрировать имя или называть, это использует. В ObjectARX, это
сделано запросом к acdbRegApp (). AcdbRegApp () функция определяет строку, чтобы использовать как
прикладное имя. Это возвращает RTNORM, если это может успешно добавлять имя к APPID; иначе, это
возвращает RTERROR. Результат RTERROR обычно указывает, что имя - уже в таблице идентификаторов.
Это - не фактическое состояние ошибки, а обычно ожидаемое возвращаемое значение, потому что
прикладное имя должно быть зарегистрировано только однажды в рисунок.
Чтобы регистрировать себя, приложение должно сначала проверить, чтобы его имя было уже не в APPID
таблице, потому что acdbRegApp () должен быть вызван только однажды в рисунок. Если имя не там,
приложение должно регистрировать это; иначе, это может идти вперед и использовать данные.
Следующий типовой кодовый фрагмент показывает типичному использованию acdbRegApp ().
134
Следующий типовой кодовый фрагмент показывает типичной последовательности для
восстановления{*поиска*} расширенных{*продленных*} данных для двух указанных приложений. Обратите
внимание, что параметр приложений передает прикладные названия в связанных буферах результатов.
strsave(appname1.rstring, "MY_APP_1");
strsave(appname2.rstring, "SOMETHING_ELSE");
.
.
.
// Only extended data from "MY_APP_1" and
// "SOMETHING_ELSE" are retrieved:
working_ent = acdbEntGetX(&work_ent_addr, &appname1);
if (working_ent == NULL) {
// Gracefully handle this failure.
.
.
.
}
// Update working entity groups.
status = acdbEntMod(working_ent);
// Only extended data from registered applications still in the
// working_ent list are modified.
Как типовые показы кода, расширенные данные, отысканные acdbEntGetX() функция может изменяться
последующим запросом к acdbEntMod (), также, как acdbEntMod () используется, чтобы изменить нормальные
данные определения. (Расширенные данные могут также быть созданы, определяя, это в списке примитива
прошло к acdbEntMake ()).
При возвращении расширенных данных только определенно требуемые приложения защищают одно
приложение от повреждения данных другого приложения. Это также управляет объемом памяти что
прикладные использования, и упрощает расширенную обработку данных, которую приложение исполняет.
ОБРАТИТЕ ВНИМАНИЕ, поскольку строки прошли с приложениями, может включать групповые символы,
прикладное имя “*” заставит acdbEntGetX () возвращать все расширенные данные, приложенные примитиву.
135
допустимыми метками. Однако, если XREF Присоединяется, изменения{*замены*} к XREF
Связывают, или объединен с текущим рисунком в другим способом, это - до приложения, чтобы
пересмотреть ссылки примитива соответственно.
Xrecord Объекты
Xrecord объект - встроенный объектный класс с именем DXF “XRECORD”, который сохраняет и
управляет произвольными потоками данных, представ внешне в результате буферизуют список,
составленный из групп DXF с “ объект нормали ” группы (то есть не - xdata коды группы), в
пределах от 1 до 369.
ПРЕДУПРЕЖДЕНИЕ! Xrecord объект разработан{*предназначен*} в пути, который не будет
оскорблять более ранние версии AutoCAD; однако, xrecord объект исчезнет при создании DXF
файла от предварительного выпуска 13c4 уровень AutoCAD.
Xrecord объекты - универсальные объекты, предназначенные для использования приложениями
ObjectARX и AutoLISP. Этот класс позволяет приложениям создавать и сохранять произвольные
объектные структуры произвольных списков буфера результата не-графической информации,
полностью отделяются от примитивов. Корневой владелец для всех определенных приложением
объектов является или словарью имен объектов, которая принимает любой тип AcDbObject как
вход, включая AcDbXrecord, или словарь расширения любого объекта.
Приложения, как ожидается, будут использовать уникальные названия{*имена*} входа в словари
имен объектов. Логика использования словари имен объектов или имени входа словаря
расширения{*продления*} подобна таковому имени REGAPP. Фактически, REGAPP
названия{*имена*} совершенен для использования как названия{*имена*} входа при добавлении в
конец определенных приложением объектов к базе данных или специфическому объекту.
Использование xrecord объектов представляет существенное упрощение относительно текущей практики
назначения xdata к примитивам. Поскольку xrecord объект не должен быть связан с примитивом, Вы больше
не должны создать фиктивные примитивы (фиктивные примитивы часто использовались, чтобы обеспечить
большее количество участка памяти для xdata), или примитивов на закрепемых уровнях.
В случае объектно - определенного состояния, xrecord объекты хорошо удовлетворены для сохранения
больших количеств сохраненной информации, в то время как xdata лучше удовлетворенный для меньших
количеств данных.
136
При монтаже иерархии xrecord объектов (добавление монопольного использования или ссылки
указателя к объекту), тот объект должен уже существовать в базе данных, и, таким образом, иметь
законное имя примитива. Поскольку acdbEntMake () не возвращает имя примитива, и acdbEntLast ()
только признает графические объекты, Вы должны использовать acdbEntMakeX () если Вы
ссылаетесь на неграфические объекты.
AcdbEntMakeX () функция возвращает имя примитива объекта, добавленного к базе данных (или
графический или неграфический). Начальный Выпуск 13 выполнения acdbEntMake () только
поддержанные объекты, чей класс диктовал его определенный объект контейнера владельца в
текущем рисунке (типа входов таблицы идентификаторов, весь снабженный Выпуск 13 типов
примитива, и объекты словаря), и зарегистрировал новый объект с его владельцем. Эти функции
продолжат делать это для того же самого набора встроенных объектных классов, включая
примитивы. Для xrecords и всех классов пользователя, эти функции добавят объект к базе данных,
оставляя это до приложения, чтобы установить его связи{*ссылки*} монопольных использований
снова до словари имен объектов. AcdbEntMakeX () функция добавляет объект к базе данных для
всех типов объекта, включая, которые идут С AutoCAD. Так, даже при использовании этой функции
на существующих типах примитива, ваша программа ответствена за установку монопольного
использования.
В следующем примере, функция getblock() возвращает первый блок (если любой) в текущем
рисунке, и вызывает printdxf() функцией, чтобы отобразить содержание того блока в формате
списка.
void getblock()
{
struct resbuf *bl, *rb;
bl = acdbTblNext("BLOCK", 1); // First entry
acutPrintf("\nResults from getblock():\n");
// Print items in the list as "assoc" items.
for (rb = bl; rb != NULL; rb = rb->rbnext)
printdxf(rb);
// Release the acdbTblNext list.
acutRelRb(bl);
}
Входы, отысканные в таблице БЛОКОВ, содержат группа -2, которая содержит имя первого
примитива на блочном определении. В рисунке к одиночному блоку по имени ПОЛЕ, запрос к
getblock () печатает следующий (значение имени изменяется от сеанса до сеанса):
Результаты от getblock ():
(0 . "BLOCK")
(2 . "BOX")
(70 . 0)
(10 9.0 2.0 0.0)
(-2 . <Entity name: 40000126>)
137
Setnext опция особенно полезна, когда имеющий дело с VPORT таблицей идентификаторов,
потому что все области просмотра в специфической конфигурации области просмотра имеют то же
самое имя (типа *ACTIVE).
Имейте в виду, что, если к VPORT таблице идентификаторов обращаются, когда TILEMODE
выключен, изменения{*замены*} не имеют никакого видимого эффекта, пока TILEMODE не
поворачивает обратно на. (TILEMODE установлен или командой SETVAR или, вводя ее имя
непосредственно.) Не путают VPORT таблицу идентификаторов с примитивами области просмотра.
Общий Доступ
Большинство генерала функций, которые обращаются К AutoCAD - acedCommand () и acedCmd ().
Подобно функции (команды) в AutoLISP, эти функции посылают команды и другой ввод
непосредственно к Приглашению ко вводу команды AutoCAD.
Int
AcedCommand (int rtype, ...);
Int
AcedCmd (struct resbuf *rbp);
138
фактические данные. Заключительный параметр в списке - одиночный параметр, чей значение
является или 0 или RTNONE. Как правило, первый параметр к acedCommand () - тип, закодируют
RTSTR, и второй параметр данных - строка, которая является именем команды, чтобы вызвать.
Следующие пары параметра определяют опции или данные, которых указанная команда требует.
Коды типа в acedCommand () список параметров - типы результата.
Параметры данных должны соответствовать типам данных и значениям, ожидаемым последовательностью
подсказки той команды. Они могут быть строки, реальные значения, целые числа, точки, названия{*имена*}
примитива, или названия{*имена*} набора выбора. Данные типа углов, расстояний, и точек можно пропускать
или как строки (поскольку пользователь мог бы вводить их) или как значения непосредственно (то есть как
целое число, реальное, или направлять значения).
Пустая строка (“ ”) эквивалентна вводу пространства{*пробела*} на клавиатуре.
Из-за идентификаторов типа, acedCommand () список параметров - не тот же самый как список
параметров для AutoLISP подпрограмма (команды). Знайте это, если Вы преобразовываете
подпрограмму AutoLISP в ObjectARX-приложение.
Имеются ограничения на команды, которые acedCommand () может вызывать, которые являются
сопоставимыми ограничениям на AutoLISP функция (команды).
int docmd()
{
ads_point p1;
ads_real rad;
if (acedCommand(RTSTR, "circle", RTSTR, "0,0", RTSTR, "3,3", 0) != RTNORM)
return BAD;
if (acedCommand(RTSTR, "setvar", RTSTR, "thickness", RTSHORT, 1, 0) != RTNORM)
return BAD;
p1[X] = 1.0; p1[Y] = 1.0; p1[Z] = 3.0;
rad = 4.5;
if (acedCommand(RTSTR, "circle", RT3DPOINT, p1, RTREAL, rad, 0) != RTNORM)
return BAD;
return GOOD;
}
При условии, что AutoCAD - в Приглашении ко вводу команды, когда эта функция вызвана{*названа*},
AutoCAD исполняет следующие действия:
1 Рисует круг, который проходит до (3.0,3.0) и чей центр - в (0.0,0.0).
2 Изменяют текущую толщину к 1.0. Обратите внимание, что первый запрос к acedCommand () передает точки
как строки, в то время как секунда передает короткое целое число. Любой метод возможен.
3 Рисует другой (вытесненный) круг, чей центр - в (1.0,1.0,3.0) и чей радиус - 4.5. Этот последний{*прошлый*}
запрос к acedCommand () использует трехмерную точку и реальный (с двойной точностью с плавающей
точкой) значение. Обратите внимание, что точки пропускает ссылка, потому что ads_point - тип массива.
Использование acedCmd ()
AcedCmd() функция эквивалентна acedCommand(), но передает значения к AutoCAD в форме списка буфера
результата. Это полезно в ситуациях, где сложная логика вовлечена в построение списка команд AutoCAD.
AcutBuildList () функция полезен для построения списков команд.
AcedCmd() функция также имеет преимущество, что список команд может изменяться во время выполнения
скорее чем быть установленным во времени компиляции. Его недостаток - то, что требуется слегка дольше,
чтобы выполниться. Для получения дополнительной информации, см. ObjectARX Ссылку.
Следующий типовой кодовый фрагмент заставляет AutoCAD исполнять REDRAW на экране графики потока
(или область просмотра).
139
Приостановка ввода пользователя
Если команда AutoCAD происходит, и AutoCAD сталкивается с символом ПАУЗЫ как параметр к
acedCommand () или acedCmd (), команда временно приостановлена, чтобы позволить прямой
ввод пользователя, включая перемещение. Символ ПАУЗЫ состоит из строки, которая содержит
одиночную наклонную черту влево. Это подобно наклонной черте влево механизм паузы,
предусмотренный меню.
Следующий запрос к acedCommand () вызывает команду ZOOM и затем использует символ ПАУЗЫ
так, чтобы пользователь мог выбирать одну из опций ZOOM.
Следующий запрос начинает команду CIRCLE, устанавливает среднюю точку как (5,5), и затем
делает паузу, чтобы позволить пользователю перетаскивать радиус круга на экране. Когда
пользователь определяет выбранную точку (или вводит выбранный радиус), функциональные
резюме, тянущий линию от (5,5) до (7,5).
ads_point p1;
ads_name first, last;
acedCommand(RTSTR, "Circle", RTSTR, "5,5", RTSTR, "2", 0);
acedCommand(RTSTR, "Line", RTSTR, "1,5", RTSTR, "8,5", RTSTR, "", 0);
acdbEntNext(NULL, first); // Get circle.
acdbEntLast(last); // Get line.
// Set pick point.
p1[X] = 2.0;
p1[Y] = 5.0;
p1[Z] = 0.0;
acedCommand(RTSTR, "Trim", RTENAME, first, RTSTR, "",
RTLB, RTENAME, last, RTPOINT, p1, RTLE,
RTSTR, "", 0);
Системные Переменные
Пара функций, acedGetVar () и acedSetVar (), дает возможность ObjectARX-приложениям
осматривать и изменить значение переменных системы AutoCAD.
Эти функции используют строку, чтобы определить имя переменной (или в верхнем регистре или нижнем
регистре), и (одиночном) буфере результатов для типа и значения переменной.
Буфер результатов требуется в этом случае, потому что переменные системы AutoCAD входят в разнообразие
типов: целые числа, реальные значения, строки, 2-ые точки, и трехмерные точки.
Следующий типовой кодовый фрагмент гарантирует, что последующие команды FILLET используют
радиус по крайней мере 1.
140
В этом примере, буфер результатов распределен как динамическая локальная переменная, когда это
объявлено в приложении. Приложение должно явно не управлять использованием памяти буфера, поскольку
это делает с динамически распределенными буферами.
Если переменная системы AutoCAD - строковый тип, acedGetVar () распределяет пространство для
строки. Приложение ответствено за освобождение этого пространства{*пробела*}. Вы можете
делать это, вызывая функцию стандартной библиотеки для C свободный (), как показано в
следующем примере:
acedGetVar("TEXTSTYLE", &rb);
if (rb.resval.rstring != NULL)
// Release memory acquired for string:
free(rb.resval.rstring);
Символы AutoLISP
Функции acedGetSym () и acedPutSym () позволяют ObjectARX-приложениям осматривать и
изменять{*заменять*} значение переменных AutoLISP.
В первом примере, пользователь вводит следующие выражения AutoLISP:
Тогда следующий типовой код показывает, как acedGetSym() отыскивает новые значения символов.
ads_point pt1;
pt1[X] = pt1[Y] = 1.4; pt1[Z] = 10.9923;
rb = acutBuildList(RTSTR, "GREETINGS", 0);
rc = acedPutSym("teststr", rb);
acedPrompt("TESTSTR has been reset\n");
acutRelRb(rb);
rb = acutBuildList(RTLB, RTSHORT, -1,
RTSTR, "The combinations of the world",
RTSTR, "are unstable by nature.", RTSHORT, 100,
RT3DPOINT, pt1,
RTLB, RTSTR, "He jests at scars",
RTSTR, "that never felt a wound.", RTLE, RTLE, 0);
rc = acedPutSym("longlist", rb);
acedPrompt("LONGLIST has been created\n");
acutRelRb(rb);
rb->restype = RTNIL;
acedPutSym("var1", rb);
141
Пользователи могут отыскивать эти новые значения. (Как показано в примере, ваша программа должна
уведомить пользователей относительно любых изменений.)
Поиск Файла
AcedFindFile () функция дает возможность приложению искать файл специфического имени. Приложение
может определить каталог, чтобы искать, или это может использовать поток путь библиотеки AutoCAD.
В следующем типовом кодовом фрагменте, acedFindFile () ищет требуемое имя файла согласно пути
библиотеки AutoCAD.
Если запрос к acedFindFile () успешен, fullpath параметр установлен в полностью квалифицированную строку
имени пути, типа следующего:
/home/work/ref/refc.dwg
Вы можете также запрашивать пользователей вводить имя файла посредством стандарта файловое
диалоговое окно AutoCAD. Чтобы отображать файловое диалоговое окно, вызовите acedGetFileD ().
Следующий типовой кодовый фрагмент использует файловое диалоговое окно, чтобы запросить
пользователей относительно имени ObjectARX-приложения.
Объектная Привязка
AcedOsnap () функция находит точку, используя один из Режимов объектной привязки AutoCAD. Поспешные
режимы определены в строковом параметре.
В следующем примере, запрос к acedOsnap () ищет midpoint линии около pt1.
Следующий запрос ищет или midpoint или оконечную точку линии, или центра дуги или круга —, какой бы ни -
самый близкий pt1.
Третий параметр (pt2 в примерах) установлен в поспешную точку, если найдены. AcedOsnap ()
функциональные возвращения RTNORM, если точка найдена.
ОБРАТИТЕ ВНИМАНИЕ, что переменная системы APERTURE определяет допустимую близость выбранной
точки к примитиву при использовании Объектной Привязки.
142
Описатели Области просмотра
Функция acedVports (), подобно функции AutoLISP (vports), получает список описателей текущих областей
просмотра и их местоположений.
Следующий типовой код получает текущую конфигурацию области просмотра и передает это назад к AutoLISP
для дисплея.
Точно так же, если четыре области просмотра равняться-размера расположены в четырех углах экрана, и
TILEMODE включен, предшествующий код может возвращать конфигурацию, показанную в следующем
рисунке.
Описатель текущей области просмотра - всегда сначала в списке. В списке, показанном в предшествующем
числе{*рисунке*}, номер 5 области просмотра - текущая область просмотра.
Геометрические Утилиты
Одна группа функций дает возможность приложениям получить геометрическую информацию.
AcutDistance () функция находит, что расстояние между двумя точками, acutAngle () находит угол между
линией, и X ось текущих ВЕРХНИХ РЕГИСТРОВ (в КООРДИНАТНОМ плане), и acutPolar () находит точку
посредством полярных координат (относительно начальной точки). В отличие от большинства функций
ObjectARX, эти функции не возвращают значение состояния. AcdbInters () функция находит пересечение двух
линий; это возвращает RTNORM, если это находит точку, которая соответствует спецификации.
ОБРАТИТЕ ВНИМАНИЕ В отличие от acedOsnap (), функции в этой группе просто вычисляют точку, линию,
или угловые значения, и фактически не сделают запрос текущего рисунка.
143
base [X] = 1.0; base [Y] = 7.0; base [Z] = 0.0;
acutPolar (base, rads, length, endpt);
Запрос к acutPolar () устанавливает endpt в точку, которая является тем же самым расстоянием от (1,7),
поскольку pt1 - от pt2, и это - под тем же самым углом от X оси как угол между pt1 и pt2.
Обратите внимание, что с вертикальными текстовыми стилями, точки все еще возвращаются в слева направо,
заказ{*по приказу;порядок*} " основание к вершине ", так что первый список точки содержит отрицательные
смещения от текстового начала координат.
AcedTextBox () функция может также измерять строки в attdef и attrib примитивах. Для attdef,
acedTextBox () измеряет строку отметки (группа 2); для attrib примитива, это измеряет текущее
значение (группа 1).
Следующая функция, которая использует некоторый примитив, обрабатывающий функции,
запрашивает пользователя выбирать текстовый примитив, и затем тянет{*рисует*} поле
ограничения вокруг текста от координат, возвращенных acedTextBox ().
144
точки ECS, восстановленные{*отысканные*} из примитива в координаты UCS, используемые
acedCommand (). См. “ Преобразования Системы координат ” на странице 271.
int tbox()
{
ads_name tname;
struct resbuf *textent, *tent;
ads_point origin, lowleft, upright, p1, p2, p3, p4;
ads_real rotatn;
char rotatstr[15];
if (acedEntSel("\nSelect text: ", tname, p1) != RTNORM) {
acdbFail("No Text entity selected\n");
return BAD;
}
textent = acdbEntGet(tname);
if (textent == NULL) {
acdbFail("Couldn’t retrieve Text entity\n");
return BAD;
}
tent = entitem(textent, 10);
origin[X] = tent->resval.rpoint[X]; //ECS coordinates
origin[Y] = tent->resval.rpoint[Y];
tent = entitem(textent, 50);
rotatn = tent->resval.rreal;
// acdbAngToS() converts from radians to degrees.
if (acdbAngToS(rotatn, 0, 8, rotatstr) != RTNORM) {
acdbFail("Couldn’t retrieve or convert angle\n");
acutRelRb(textent);
return BAD;
}
if (acedTextBox(textent, lowleft, upright) != RTNORM) {
acdbFail("Couldn’t retrieve text box
coordinates\n");
acutRelRb(textent);
return BAD;
}
acutRelRb(textent);
// If not currently in the WCS, at this point add
// acedTrans() calls to convert the coordinates
// retrieved from acedTextBox().
p1[X] = origin[X] + lowleft[X]; // UCS coordinates
p1[Y] = origin[Y] + lowleft[Y];
p2[X] = origin[X] + upright[X];
p2[Y] = origin[Y] + lowleft[Y];
p3[X] = origin[X] + upright[X];
p3[Y] = origin[Y] + upright[Y];
p4[X] = origin[X] + lowleft[X];
p4[Y] = origin[Y] + upright[Y];
if (acedCommand(RTSTR, "pline", RTPOINT, p1,
RTPOINT, p2, RTPOINT, p3,RTPOINT, p4, RTSTR, "c",
0) != RTNORM) {
acdbFail("Problem creating polyline\n");
return BAD;
}
if (acedCommand(RTSTR, "rotate", RTSTR, "L", RTSTR, "",
RTPOINT, origin, RTSTR, rotatstr, 0) != RTNORM) {
acdbFail("Problem rotating polyline\n");
return BAD;
}
return GOOD;
}
Предшествующий пример использует команду ROTATE AutoCAD, чтобы вызвать вращение. Более
прямой способ делать это состоит в том, чтобы включить вращение в вычисление точек поля,
следующим образом:
145
p2[X] = origin[X] + (upright[X]*crot - lowleft[Y]*srot);
p2[Y] = origin[Y] + (upright[X]*srot + lowleft[Y]*crot);
p3[X] = origin[X] + (upright[X]*crot - upright[Y]*srot);
p3[Y] = origin[Y] + (upright[X]*srot + upright[Y]*crot);
p4[X] = origin[X] + (lowleft[X]*crot - upright[Y]*srot);
p4[Y] = origin[Y] + (lowleft[X]*srot + upright[Y]*crot);
ОБРАТИТЕ ВНИМАНИЕ, что функции Several имеют подобные названия, но - не часть группы
вводов пользователя: acedGetFunCode (), acedGetArgs (), acedGetVar (), и acedGetInput ().
Следующие функции ведут себя подобно функциям ввода пользователя: acedEntSel (),
acedNEntSelP (), acedNEntSel (), и acedDragGen (). Следующая таблица кратко описывает функции
ввода пользователя.
Имя функции Описание
AcedGetInt Получает целочисленное значение
AcedGetReal Получает реальное значение
AcedGetDist Получает расстояние
AcedGetAngle Получает угол (к 0 градусам как определено ANGBASE переменной)
AcedGetOrient Получает угол (к 0 градусам вправо)
AcedGetPoint Получает точку
AcedGetCorner Получает угол прямоугольника
AcedGetKword Получает ключевое слово (см. описание ключевых слов позже в этой секции)
AcedGetString Получает строку
С некоторыми функциями ввода пользователя типа acedGetString (), пользователь вводит значение
в линию подсказки AutoCAD. С другими типа acedGetDist (), пользователь или вводит ответ на
подсказке, выравнивают, или определяет значение, выбирая точки на графическом экране.
Если экран используется, чтобы определить значение, AutoCAD отображает линии с резиновой
полосой, которые являются подчиненными к прикладному контролю{*управлению*}.
Предшествующий запрос к acedInitGet () может заставлять AutoCAD высвечивать линию резиновый
полоса (или поле).
AcedGetKword () функция отыскивает ключевое слово. Ключевые слова - также строковые
значения, но они не содержат никакое незаполненное пространство, могут быть сокращены, и
должны быть основаны перед acedGetKword () запрос запросом к acedInitGet (). Все функции ввода
пользователя (кроме acedGetString ()) могут принимать значения ключевого слова в дополнение к
значениям, которые они обычно возвращают, если acedInitGet () был вызван{*назван*}, чтобы
основать ключевые слова. Функции Ввода пользователя, которые принимают ключевые слова,
могут также принимать произвольный текст (без пространств{*пробелов*}).
Пользователь AutoCAD не может ответить на функцию ввода пользователя, вводя выражение AutoLISP.
Функции ввода пользователя воспользуются преимуществом возможности с обнаружением ошибок
AutoCAD. Тривиальные ошибки (типа ввода только единственный{*отдельный*} номер в ответ на
acedGetPoint ()) пойман в соответствии с AutoCAD и не возвращен функцией ввода пользователя.
Приложение должно только проверить условия{*состояния*}, показанные в следующей таблице.
146
RTREJ AutoCAD отклонил запрос как инвалид
RTKWORD Пользователь ввел ключевое слово или произвольный текст
RTCAN случай позволяет пользователю отменить запрос приложения, нажимая ESC. Это
помогает приложению соответствовать стилю встроенного AutoCAD, командует, которые всегда
позволяют отмену пользователя. Возвращаемые значения RTNONE и RTKWORD управляются
функцией acedInitGet (): возвращения функции ввода пользователя RTNONE или RTKWORD
только, если эти значения явно позволились предшествующим acedInitGet () запрос.
int age;
acedInitGet(RSG_NONULL | RSG_NOZERO | RSG_NONEG, NULL);
acedGetInt("How old are you? ", &age);
147
if ((rc = acedGetInt("How old are you? ", &age)) == RTKWORD) {
// Keyword or arbitrary input
acedGetInput(userstring);
}
int stat;
ads_real x, pi = 3.14159265;
char kw[20];
// Null input is not allowed.
acedInitGet(RSG_NONULL, "Pi Two-pi");
if ((stat = acedGetReal("Pi/Two-pi/<number>: ", &x)) < 0) {
if (stat == RTKWORD && acedGetInput(kw) == RTNORM) {
if (strcmp(kw, "Pi") == 0) {
x = pi;
stat = RTNORM;
} else if (strcmp(kw, "Two-pi") == 0) {
x = pi * 2;
stat = RTNORM;
}
}
}
if (stat != RTNORM)
acutPrintf("Error on acedGetReal() input.\n");
else
acutPrintf("You entered %f\n", x);
Запрос к acedInitGet () предотвращает пустой указатель, вводят, и определяет два ключевых слова: “Pi” и “Два
- pi”. Когда acedGetReal () вызван{*назван*}, пользователь отвечает на подсказку Pi/Two-pi / <номеру>, вводя
или реальное значение (сохраненный в местной переменной x) или одном из ключевых слов. Если
пользователь вводит ключевое слово, acedGetReal () возвращает RTKWORD. Приложение отыскивает
ключевое слово, вызывая acedGetInput () (обратите внимание, что это проверяет{*отмечает*} состояние
ошибки этой функции), и затем устанавливает значение x к pi или 2pi, в зависимости от которого ключевое
слово было введено. В этом примере, пользователь может вводить или p, чтобы выбрать pi или t, чтобы
выбрать 2pi.
148
Графическое перемещение Наборов Выбора
Функция acedDragGen () запрашивает пользователя перетаскивать группу отобранных объектов, как показано в следующем
примере:
int rc;
ads_name ssname;
ads_point return_pt;
// Prompt the user for a general entity selection.
if (acedSSGet(NULL, NULL, NULL, NULL, ssname) == RTNORM)
// The newly selected entities
rc = acedDragGen(ssname,
"Drag selected objects", // Prompt
0, // Display normal cursor (crosshairs)
dragsample, // Transformation function
return_pt); // Set to the specified location.
Прерывания от пользователя
Функции ввода пользователя и acedCommand (), acedCmd (), acedEntSel (), acedNEntSelP (), acedNEntSel (),
acedDragGen (), и acedSSGet () функции возвращают RTCAN, если пользователь AutoCAD отвечает, нажимая
ESC. Внешняя функция должна обращаться с этим ответом как запрос отмены задания и возвращение
немедленно.
ObjectARX также обеспечивает функцию, acedUsrBrk (), это явно проверяет{*отмечает*}, нажал ли
пользователь ESC. Эта функция позволяет приложениям ObjectARX проверить прерывание пользователя.
Приложение не должно вызвать acedUsrBrk () если это не исполняет длинное вычисление между
взаимодействиями с пользователем. Функция acedUsrBrk () никогда не должна использоваться как
замена{*заместитель*} проверки значения, возвращенного функциями ввода пользователя, которые могут
возвращать RTCAN.
В некоторых случаях, приложение будет хотеть игнорировать запрос отмены пользователя. Если дело обстоит
так, это вызвало acedUsrBrk () чтобы очистить запрос; иначе, ESC будет все еще
невыполненный{*выдающийся*} и вызовет следующий запрос ввода пользователя терпеть неудачу. (Если
приложение игнорирует ESC, это должно печатать сообщение, чтобы сообщить пользователю, которого это
делает так.) Всякий раз, когда ObjectARX-приложение вызвано, условие ESC автоматически очищено.
Например, следующий кодовый фрагмент терпит неудачу, если пользователь вводит ESC в подсказку.
int test()
{
int i;
while (!acedUsrBrk()) {
acedGetInt("\nInput integer:", &i); // WRONG
.
.
.
}
}
Слегка изменяемый кодовый фрагмент, который следует правильно за метками ввод ESC без того, чтобы
вызвать acedUsrBrk ().
int test()
{
int i;
for (;;) {
if (acedGetInt("\nInput integer:", &i) != RTNORM)
break;
...
}
}
Следующая выборка изменяет{*заменяет*} условие цикла. Это строительство также работает правильно.
int test()
{
int i;
while (acedGetInt("\nInput integer:", &i) == RTNORM) {
...
}
}
149
Имеющее силу место, чтобы использовать acedUsrBrk () находится в длинной операции. Например, код,
который шагает через каждый примитив в базу данных рисунка, может быть потребление времени и должен
вызвать acedUsrBrk ().
Следующий пример показывает схему вызванной функции, когда приложение получает запрос kInvkSubrMsg.
Это возвращает реальное значение AutoLISP.
Int dofun ()
{
Ads_real x
// Проверить{*отметить*} параметры, и ввести условия здесь.
// Вычислить значение x.
AcedRetReal (x);
return GOOD;
}
ОБРАТИТЕ ВНИМАНИЕ, что внешняя функция может делать больше чем один запрос к функциям
возвращения значения по единственному запросу kInvkSubrMsg, но функция AutoLISP возвращает только
значение последней вызванной функцией.
Преобразования
Функции, описанные в этой секции - утилиты для преобразования типов данных и модулей.
Строковые Преобразования
Функции acdbRToS () и acdbAngToS () преобразовывают значения, используемые в AutoCAD к строковым
значениям, которые могут использоваться в выводе или как текстовые данные. AcdbRToS () функция
преобразовывает реальное значение, и acdbAngToS () преобразовывает угол. Формат строки результата
управляется значением переменных системы AutoCAD: модули и точность определены LUNITS и LUPREC для
реальных (линейных) значений и AUNITS и AUPREC для угловых значений. Для и функционирует, DIMZIN
dimensioning переменное средство управления, как продвижение и конечные нули написаны к строке
результата. Дополнительные функции acdbDisToF () и acdbAngToF () преобразовывают строки назад в
реальные значения (расстояния) или углы. Если пропускается строка, сгенерированная acdbRToS () или
acdbAngToS (), acdbDisToF () и acdbAngToF () (соответственно), как гарантируют, возвратят имеющее силу
значение.
Например, следующие показы фрагмента вызывают к acdbRToS () (. Проверка Ошибки не показывается, но
должна быть включена в приложения.)
Ads_real x = 17.5;
char fmtval [12];
// Точность - 3-ий параметр: 4 места в первом
// Вызвать, 2 места в другие.
AcdbRToS (x, 1, 4, fmtval); // Режим 1 = научный
AcutPrintf (" Значение, отформатированное как %s\n ", fmtval);
AcdbRToS (x, 2, 2, fmtval); // Режим 2 = десятичное число
AcutPrintf (" Значение, отформатированное как %s\n ", fmtval);
AcdbRToS (x, 3, 2, fmtval); // Режим 3 = разработка
AcutPrintf (" Значение, отформатированное как %s\n ", fmtval);
AcdbRToS (x, 4, 2, fmtval); // Режим 4 = архитектурный
AcutPrintf (" Значение, отформатированное как %s\n ", fmtval);
AcdbRToS (x, 5, 2, fmtval); // Режим 5 = дробный
AcutPrintf (" Значение, отформатированное как %s\n ", fmtval);
150
Значения на экране текста AutoCAD.
Значение, отформатированное как 1.7500E+01
Значение, отформатированное как 17.50
Значение, отформатированное как 1‘ -5.50 І
Значение, отформатированное как 1’ -5 1/2 І
Значение, отформатированное как 17 1/2
Когда UNITMODE переменная системы установлена в 1, который определяет, что модули отображены как
введено, строка, возвращенная acdbRToS () отличается для разработки (режим равняется 3), архитектурный
(режим равняется 4), и дробный (режим равняется 5) модулям. Например, первые две линии
предшествующего типового вывода были бы, тот же самый, но последние строки будет появляться
следующим образом:
AcdbDisToF () функциональные дополнения acdbRToS (), так следующее вызывают, которые используют
строки, сгенерированные в предыдущих примерах, весь результат набора к тому же самому значению, 17.5.
(Снова, примеры не показывают проверку ошибок.)
Они вызывают (все еще принятие что DIMZIN равняется 0) отображают следующие значения на экране текста
AutoCAD.
ОБРАТИТЕ ВНИМАНИЕ, что UNITMODE переменная системы также воздействует на строки, возвращенные
acdbAngToS () когда это возвращает строку в модулях инспектора (режим равняется 4). Если UNITMODE
равняется 0, возвращенная строка может включать пробелы (например, “ N 45d E ”); если UNITMODE
равняется 1, строка не содержит никакие пробелы (например, “N45dE”).
AcdbAngToF() функциональные дополнения acdbAngToS (), так следующее вызывает весь набор параметр
результата к тому же самому значению, 3.14159. (Это округлено до 3.1416 в примере, который использует
радианы.)
151
ОБРАТИТЕ ВНИМАНИЕ, когда Вы имеете строку, которая определяет угол в градусах{*степенях*}, минутах, и
секундах, Вы должны использовать наклонную черту влево (\), чтобы выйти из символа секунд (І) так, чтобы,
казалось, не было конца строки. Второй из предшествующего acdbAngToF () примеры демонстрируют это.
Реальные преобразования
Файл acad.unt определяет разнообразие преобразований между реальными модулями типа миль /
километров, Фаренгейта / Цельсия, и так далее. Функция acutCvUnit () берет значение, выраженное в одной
системе модулей и возвращает эквивалентное значение в другой системе. Две системы модулей определены
строками, которые должны соответствовать одному из определений acad.unt.
Если модули текущего рисунка технические или архитектурные (футы и дюймы), следующий фрагмент
преобразовывает указанное пользователем расстояние в метры.
Следующий кодовый фрагмент берет символ (значение в этом примере произвольно) и преобразовывает это
к верхнему регистру. AcutToUpper () функция не имеет никакого эффекта, если символ - уже верхний регистр.
int cc = 0x24;
cc = acutToUpper (cc);
целочисленный код (restype == RTSHORT) который определяет WCS, текущий UCS, или текущий DCS
(или текущей области просмотра или пространства листа).
имя примитива (restype == RTENAME), как возвращено одним имени примитива или выбора
устанавливают функции. Это определяет ECS названного примитива. Для плоских примитивов, ECS
может отличиться от WCS. Если ECS не отличается, преобразование между ECS и WCS - операция
тождества.
152
трехмерный вектор вытеснения (restype == RT3DPOINT), который является другим методом
определения ECS примитива. Векторы Вытеснения всегда представляются в мировых координатах;
вектор вытеснения (0,0,1) определяет WCS непосредственно.
Следующее - описания систем координат AutoCAD, которые могут быть определены от и до параметров.
WCS Мировая система координат. Система координат “ссылки”. Все другие системы координат
определены относительно WCS, который никогда не изменяется. Значения, измеренные
относительно WCS устойчивы поперек изменений{*замен*} к другим системам координат.
UCS Система координат Пользователя. “Рабочая” система координат. Все точки прошли к AutoCAD,
командует, включая возвратился от подпрограмм AutoLISP и внешних функций, - точки в текущем
UCS (если пользователь не предшествует им с * в Приглашении ко вводу команды). Если Вы хотите,
чтобы ваше приложение послало координаты в WCS, ECS, или DCS к AutoCAD командует, Вы
должны сначала преобразовать их к UCS, вызывая acedTrans ().
ECS Система координат Примитива. Значения Точки, возвращенные acdbEntGet () выражены в этой
системе координат относительно примитива непосредственно. Такие точки бесполезны, пока они не
преобразованы{*конвертированы*} в WCS, текущий UCS, или текущий DCS, согласно
предназначенному использованию примитива. Наоборот, точки должны быть оттранслированы в
ECS прежде, чем они написаны к базе данных посредством acdbEntMod () или acdbEntMake ().
DCS Система координат Дисплея. Система координат, в которую объекты преобразованы прежде, чем
они отображены. Начало координат DCS - точка, сохраненная в переменной ЦЕЛЕВОЙ СИСТЕМЫ
AutoCAD, и ее Z ось - направление рассмотрения. Другими словами, область просмотра - всегда
представление{*вид*} плана его DCS. Эти координаты могут использоваться, чтобы определить, где
кое-что появляется пользователю AutoCAD. Когда от и до целочисленных кодов - 2 и 3, в любом
порядке, 2 указывает, что DCS для текущей области просмотра пространства модели, и 3 указывает
DCS для пространства листа (PSDCS). Когда этот код 2 используется с целым числом, закодируют
другой чем 3 (или другие средства определения системы координат), принято указать DCS
пространства потока (пространство листа или пространство модели), и другой параметр принят,
чтобы указать систему координат в текущем пространстве.
PSDCS DCS Пространства листа. Эта система координат может быть преобразована только к или от DCS в
настоящее время активной области просмотра пространства модели. Это - по существу 2-ое
преобразование, где X и координаты Y всегда масштабируются и смещены, если disp параметр - 0.
Координата Z масштабируется, но никогда не оттранслирована; это может использоваться, чтобы
найти коэффициент масштаба между этими двумя системами координат. PSDCS (целое число
закодируют 2) может быть преобразован только в текущую область просмотра пространства модели:
если от параметра равняется 3, к параметру должен равняться 2, и наоборот.
Если текущий UCS вращается на 90 градусов против часовой стрелки во всем мире Z ось, запрос к
acedTrans() устанавливают результат к сути (2.0, -1.0,3.0).
Однако, если acedTrans() вызван, как показано в следующем примере, результат - (-2.0,1.0,3.0).
Контроль Дисплея
ObjectARX имеет несколько функций для управления дисплеем AutoCAD, включая, и текстовые и
графические экраны.
Интерактивный Вывод
Основные функции вывода - acedPrompt(), который отображает сообщение на линии подсказки AutoCAD, и
acutPrintf(), который отображает текст на текстовом экране. AcutPrintf() последовательность запроса функции
эквивалентен функции стандартной библиотеки для C printf(). Это обеспечивается как отдельная функция,
потому что на некоторых платформах стандартный C printf () заставляет сообщение вывода корежить экран
графики AutoCAD. (Помните, что acdbFail() функция также отображает сообщения на текстовом экране.)
Размер строки, отображенной acedPrompt() не должен превысить длину линии подсказки графического
экрана; типично это - не больше, чем 80 символов.
153
Размер строки, отображенной acutPrintf() не должен превысить 132 символа, потому что это - размер
строкового буфера, используемого acutPrintf() функция (133 байта, с последним байтом, зарезервированным
для символа пустого указателя).
"section=submenu"
Где секция указывает секцию меню, и подменю указывает который подменю активизировать в пределах той
секции.
Например, следующий функциональный запрос заставляет OSNAP подменю, определенный в текущем файле
меню появляться на экране.
acedMenuCmd ("S=OSNAP");
acedMenuCmd ("B=MY-BUTTONS");
В Выпуске 12 и более ранних версий AutoCAD, Вы могли назначать любой вид меню для любой другой.
Например, Вы могли назначать меню SCREEN для меню POP. С Выпуском 13 и более поздних версий
AutoCAD, Вы можете назначать меню для других меню на платформе Windows только, если они имеют тот же
самый тип. Меню POP может быть назначено только на другое меню POP, и меню SCREEN для другого меню
SCREEN. Вы можете определить меню подробно, потому что Windows загружает частичные меню.
Запрос acedMenuCmd () и при принятии “P1=test.numeric” назначает меню 12 POP для меню 2 POP, при
предположении, что следующие определения файла меню существуют.
*** MENUGROUP=test
*** POP12
**NUMERIC
[Numeric Menu]
[First item]
[Second item]
Следующие показы запроса, как активизировать раскрывающееся меню и затем отображают это.
AcedMenuCmd ("P1=NUMERIC");
Запрос к acedMenuCmd () назначает подменю NUMERIC на раскрывающееся меню 1 (в левом верхнем углу
графического экрана).
См. Руководство Настройки AutoCAD для подробной информации относительно заказных меню.
154
ПРЕДУПРЕЖДЕНИЕ! Поскольку эти функции зависят от кода в AutoCAD, их операция может изменяться от
выпуска. Приложения, которые вызывают эти функции, не могут быть восходяще совместимы. Также, они
зависят от текущей аппаратной конфигурации. В частности приложения, которые вызывают acedGrText () и
acedGrRead (), вряд ли, будут работать тот же самый на всех конфигурациях, если разработчик не использует
их как описано ранее, чтобы избежать аппаратно-зависимых особенностей.
Эти функции не делают почти никакое сообщение ошибки и могут повреждать графическое экранное
устройство отображения (см. пример для способа установить эту проблему).
Следующее повреждение при смене графического экранного устройства отображения вызвано неправильным
обращением к acedGrText (), acedGrDraw (), или acedGrVecs ().
Калибровка Таблетки
Пользователи AutoCAD с таблеткой отцифровывания могут калибровать таблетку, используя команду
TABLET. С acedTablet () функция, приложения может управлять калибровками, устанавливая их
непосредственно и сохраняя назначения калибровки для будущего использования. Функция берет два
параметра, список и результат, каждый из которых - список буфера результата. Первый буфер результатов в
первом списке - целочисленный код, который должен быть 0, чтобы отыскать текущую калибровку (в
результате), или 1, чтобы установить калибровку согласно остающимся буферам в списке. Калибровки
выражены как четыре трехмерных точки (в дополнение к коду). Первые три из них - направляющие — row1,
row2, и row3 — три строки матрицы преобразования таблетки. Четвертая точка - вектор, направление,
которое является нормальным на план поверхности таблетки (выраженное в WCS).
ОБРАТИТЕ ВНИМАНИЕ На TABMODE средство управления переменной системы, установлен ли режим Tablet
в На (1) или От (0). Вы можете управлять это, используя acedSetVar().
Следующая последовательность кода отыскивает текущую калибровку таблетки, и сохраняет это в calibr2. В
этом примере, пользователь использовал команду TABLET, чтобы калибровать матрицу, и режим Tablet
включен.
В этом примере, calibr1 теперь содержит результат калибровки. Поскольку это возможно идентично calibr2
(который был инициализирован acedTablet ()), Вы не обязательно нуждаетесь в этом результате. Когда Вы
устанавливаете калибровку, Вы можете определить результат NULL, который заставляет acedTablet ()
устанавливать калибровку “ тихо. ”
Матрица преобразования прошла, поскольку row1, row2, и row3 - 3x3, матрица преобразования хотела
преобразовать 2-ую точку. 2-ая точка выражена как вектор столбца в гомогенных координатах (добавляя 1.0
как третий элемент), так что преобразование напоминает это:
155
X M 00 M 01 M X'
' 02
Y' = M 10 M 11 M x Y'
12
D M 20 M 21 1.
' 1.0 0
Вычисление точки подобно трехмерному случаю. AutoCAD преобразовывает точку, используя следующие
формулы:
X' = M 00 X + M 01 Y + M 02
Y' = M 10 X + M 11 Y + M 12
D' = M 20 X + M 21 Y + 1.0
Чтобы поворачивать заканчивающийся вектор назад в 2-ую точку, первые два компонента разделены третью,
коэффициентом масштаба, выдавая точку D ' (X '/D ', Y '/D ').
Для проективного преобразования, которое является, большинство общего случая, acedTablet () делает
полное вычисление. Но для афинных и ортогональных преобразований, и - оба 0, удет быть 1.0 - также.
Вычисление опущено; заканчивающаяся 2-ая точка - просто.
Афинное преобразование - специальный, однородный случай проективного преобразования. Ортогональное
преобразование - специальный случай афинного преобразования: не только являются и 0, но и и.
М. 20 М. 21 D '
( X ', Y ')
М. 20 М. 21 М. 00 = М. 11
М. 10 = - М. 01
ОБРАТИТЕ ВНИМАНИЕ, когда Вы устанавливаете калибровку, результат не равняется параметру списка, если
направление в списке не было нормализовано; AutoCAD нормализует вектор направления прежде, чем это
возвращает это. Также, это гарантирует, что третий элемент в третьем столбце (row3 [Z]) равен 1. Эта
ситуация не должна возникнуть, если Вы устанавливаете калибровку, используя значения, отысканные из
AutoCAD посредством acedTablet (). Однако, это может случаться, если ваша программа вычисляет
преобразование непосредственно.
Следующий запрос иллюстрирует использование скобок в образце. В этом случае, acutWcMatch () возвращает
RTNORM, если matchme равняется “STR1”, “STR2”, “STR3”, или “STR8”.
Строка образца может определить множественные образцы, отделенные запятыми. Следующий запрос
возвращает RTNORM, если matchme равняется “ABC”, если это начинается с “XYZ”, или если это
заканчивается “123”.
156
if (acutWcMatch(matchme, "ABC,XYZ*,*123") == RTNORM) {
.
.
.
}
AcutWcMatchEx () функция подобна acutWcMatch (), но это имеет дополнительный параметр, чтобы позволить
этому игнорировать регистр.
bool
acutWcMatchEx(
const char * string,
const char * pattern,
bool ignoreCase);