Вы находитесь на странице: 1из 423

ObjectARX ™, AutoCAD ®

Среда программирования
Библиотеки 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++.

Среда программирования ObjectARX


ObjectARX среда программирования обеспечивает объектно-ориентированный C++
прикладной программный интерфейс для разработчиков, чтобы использовать, настроить, и расширить
AutoCAD. ObjectARX библиотеки включают непостоянный набор инструментальных средств для прикладных
разработчиков, чтобы воспользоваться преимуществом открытой архитектуры AutoCAD, обеспечивая прямой
доступ к структурам базы данных AutoCAD, графической системе, и коренным определениям команд. Кроме
того, эти библиотеки разработаны с возможностью интерфейса с VLisp
и другим прикладным языкам программирования так, чтобы разработчики могли выбирать инструментальные
средства программирования.
Как разработчик, Вы можете использовать ObjectARX, чтобы выполнить следующие задачи:
 Обращение к базе данных AutoCAD
 Взаимодействие с редактором AutoCAD
 Создание интерфейса пользователя, использующее MFC
 Поддержка многодокументной среды
 Создание заказных классов
 Формирование комплексного приложения
 Взаимодействуют с другими средами программирования

Этот раздел - краткий обзор этих тем. Более подробно они будут обсуждены в последующих разделах.

Доступ к Базе данных AutoCAD


Рисунок AutoCAD - коллекция объектов, сохраненных в базе данных. Объекты представляют собой не только
графические объекты, но также и внутренние конструкции
типа таблиц идентификаторов и словарей. ObjectARX обеспечивает ваше приложение доступом к этим
структурам базы данных. Кроме того, Вы можете создавать новую базу данных объектов для вашего
определенного приложения.

Взаимодействие с Редактором AutoCAD


ObjectARX обеспечивает классы и функции элемента, чтобы взаимодействовать с
редактором AutoCAD. Вы можете регистрировать команды в AutoCAD для обработки их как встроенных
команд. Ваше приложение может получать и отвечать на уведомление относительно разнообразных событий,
которые происходят в AutoCAD.

Создание Интерфейсов пользователя с MFC


ObjectARX приложения может быть сформированы с динамически связанной MFC библиотекой. Вы можете
использовать эту библиотеку, чтобы создать стандартные
графические интерфейсы пользователя Windows.

Поддержка МНОГОДОКУМЕНТАЛЬНОГО ИНТЕРФЕЙСА


С ObjectARX Вы можете создавать приложения, которые поддержат многодокументную среду AutoCAD и
смогут должным образом взаимодействовать с другими приложениями Windows.

12
Создание Заказных Классов
Вы можете усиливать классы в иерархии ObjectARX, чтобы создать ваши собственные
заказные классы. Кроме того, Вы можете использовать обширную графику
Библиотеки ObjectARX при создании заказных классов.

Формирование Комплексных Приложений


ObjectARX поддерживает развитие комплексных приложений, обеспечивая следующие возможности:
 уведомление
 управление Транзакции
 Глубоко имитирующий
 редактирование Ссылки(справочников)
 расширение Протокола
 поддержка Proxy-объекта
 Взаимодействие с другими средами

ObjectARX приложения может связываться с другими интерфейсами программирования, типа VLisp, ActiveX, и
COM. Кроме того, ObjectARX приложения могут взаимодействовать с Internet связанными с объектами URL,
загружая и сохраняя чертежные файлы от WWW.

Библиотека классов ObjectARX


ObjectARX среда состоит из следующих групп классов и функций:
AcRx Классы для связывания приложения и для класса во время выполнения
регистрации и идентификации.
AcEd Классы для регистрации команд AutoCAD и для уведомления о событиях AutoCAD.
AcDb классы базы данных AutoCAD.
AcGi Графические классы для исполнения объектов AutoCAD.
AcGe Сервисные классы для общей линейной алгебры и геометрического объекта.

Следующая таблица перечисляет библиотеки, требуемые, чтобы связать приложения ObjectARX.

AcRx acad.lib, rxapi.lib, acrx15.lib


AcEd acad.lib, rxapi.lib, acedapi.lib, acrx15.lib
AcDb acad.lib, rxapi.lib, acdb15.lib, acrx15.lib
AcGi acad.lib, rxapi.lib, acgiapi.lib, acrx15.lib
AcGe acad.lib, rxapi.lib, acge15.lib, acrx15.lib

Все приложения ObjectARX должны связаться с acad.lib и rxapi.lib. Другие библиотеки могут также требоваться
в зависимости от префикса ObjectARX класса и функции, что Вы используете.
Следующие разделы берут, ближе смотрят на каждую из ObjectARX библиотек.
Для получения дополнительной информации относительно определенных(удельных) классов и функций
элемента, см. ObjectARX справочники.

AcRx Библиотека
AcRx библиотека обеспечивает классы с системным уровнем для DLL инициализации и соединения и для
регистрации класса во время выполнения и идентификации. Базовый класс этой библиотеки - AcRxObject,
который обеспечивает следующие средства:

 идентификация класса во время выполнения и анализу наследования


 добавление во время выполнения нового протокола к существующему классу (см. главу
19,“Расширение Протокола”)
 объектное равенство и испытание сравнения
 копирование объекта

AcRx библиотека также обеспечивает набор макрокоманд C++, чтобы помочь Вам создать новые ObjectARX
классы, полученные из AcRxObject (см. главу 11, «Получение
заказного ObjectARX класса»).
AcRxDictionary - другой важный класс в этой библиотеке. Словарь - a
Отображение от текстовой строки до другого объекта(цели). AcRx библиотека размещает ее объекты, классы,
и сервисные словари в глобальном объектном словаре, который
является образцом AcRxDictionary класса. Приложения могут прибавлять объекты к
этому словарю так, чтобы они были доступны для других приложений.
Иерархия классов для AcRx библиотеки следующие:
AcRxObject
AcRxClass

13
AcRxDictionary
AcRxDynamicLinker
AcRxEvent
AcEditor
AcRxService
AcRxKernal
AcDbServices
AcEdServices
AcadAppInfo

Идентификация типа во время выполнения


Каждый подкласс AcRxObject имеет связанный объект описателя класса (типа
AcRxClass), который используется для идентификации типа во время выполнения. ObjectARX обеспечивает
 Функции для испытания, имеет ли объект специфический класс или полученный класс,
 Функции для определения, имеют ли два объекта тот же самый класс, и
 Функции для возвращения объекта описателя класса для данного класса.
Для получения дополнительной информации при использовании AcRx классов см. главу 3, “ ObjectARX
Прикладные Основы, ” глава 11, при Получении Заказного ObjectARX Класса, ” и Глава 19, “ Расширение
Протокола. ”

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

AcDbDictionary AcDbSymbolTable AcDbSymbolTableRecord


AcDbDictionaryWithDefault AcDbAbstractViewTable
AcDbAbstractViewTableRecord
AcDbFilter AcDbViewportTable
AcDbLayerFilter AcDbViewTable AcDbViewportTableRecord
AcDbSpatialFilter AcDbBlockTable AcDbViewTableRecord
AcDbGroup AcDbDimStyleTable AcDbBlockTableRecord
AcDbIDBuffer AcDbFontTable AcDbDimStyleTableRecord
AcDbIndex AcDbLayerTable AcDbFontTableRecord
AcDbLayerIndex AcDbLinetypeTable AcDbLayerTableRecord
AcDbSpatialIndex AcDbRegAppTable AcDbLinetypeTableRecord
AcDbLongTransaction AcDbTextStyleTable AcDbRegAppTableRecord
AcDbMlineStyle AcDbUCSTable AcDbTextStyleTableRecord
AcDbPlaceholder AcDbUCSTableRecord
AcDbPlotSettings
AcDbLayout
AcDbProxyObject
AcDbXrecord
AcDbEntity
AcDbRasterImageDef
AcDbRasterImageDefReactor
AcDbRasterVariables

Для получения дополнительной информации на 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.

Глава 2. Первичные базы данных


База данных AutoCAD сохраняет объекты, которые составляют рисунок AutoCAD. Эта глава обсуждает
ключевые элементы базы данных: объекты, таблицы идентификаторов и словарь имен объектов.
Эта глава также представляет объектные маркеры(дескрипторы), объект IDs(цель), и протокол для открытия и
заключительных объектов(целей) базы данных. Типовой код дает пример создания объектов, уровней, и
групп, и добавления объектов(целей) к базе данных.
 Краткий обзор базы данных AutoCAD
 Основная база данных
 Создание объекта в AutoCAD
 Создание объекта в ObjectARX

Краткий обзор Базы данных AutoCAD


Рисунок AutoCAD - коллекция объектов, сохраненных в базе данных. Некоторые из основных объектов базы
данных - объекты, таблицы идентификаторов, и словари. Объекты - специальный вид базы данных, имеют
графическое представление в пределах рисунка AutoCAD. Строки, круги, дуги, текст, solids, области(регионы),
сплайны, и эллипсы - примеры объектов. Пользователь может видеть объект на экране и может управлять им.
Таблицы идентификаторов и словари - контейнеры, имел обыкновение сохранять объекты базы данных. Оба
контейнерных объекта отображают строку имени к объекту базы данных. База данных AutoCAD включает
фиксированный набор таблиц идентификаторов, каждая из которых содержит образцы специфического
класса отчета таблицы идентификаторов. Вы не можете прибавлять новую таблицу идентификаторов к базе
данных. Примеры таблиц идентификаторов - таблица уровня (AcDbLayerTable), который содержит отчеты
таблицы уровня, и блочную таблицу (AcDbBlockTable), который содержит блочные отчеты таблицы. Все
объекты AutoCAD принадлежат блочным отчетам таблицы.
Словари обеспечивают более универсальный контейнер для сохранения объектов, чем таблицы
идентификаторов. Словарь может содержать любой объект типа AcDbObject или подкласса этого. База
данных AutoCAD создает словарь называемый названным объектным словарем, когда это создает новый
рисунок. Названный объектный словарь может просматриваться как главное “оглавление” для всех словарей,
связанных с базой данных. Вы можете создавать новые словари в пределах названного объектного словаря и
прибавлять новая база данных. Следующий рисунок показывает ключевые компоненты базы данных
AutoCAD.
D a ta b a s e

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()

Количество баз данных.


Множество баз данных могут быть загружены в одном сеансе AutoCAD. Каждый объект в сеансе имеет метку
и ID. Метка уникально идентифицирует объект в пределах специфической базы данных. ID уникально
идентифицирует объект во всех базах данных, загруженных в одно время. ID сохраняется только в течение
сеанса редактирования, но метка сохраняется с рисунком. В отличие от ID объекта, метка может быть
неуникальна, когда множество баз данных загружены в сеансе AutoCAD.

Получение ID объекта
Через ID Вы можете получить указатель на фактический объект базы данных для обеспечения исполнения
операций с ним. Для примера, см. “Открытие и Закрытие ObjectARX Объекты” на странице 27.
Вы можете получить ID объекта несколькими способами:
 Создание объекта и добавление его в конец базы данных. База данных тогда дает объекту ID и
возвращает его Вам.
 Используют протокол базы данных для получения ID объектов, которые созданы автоматически,
когда база данных создана (типа фиксированного набора таблиц идентификаторов и названного
объектного словаря).
 Используют класс - определенный протокол для получения объекта IDs. Некоторые классы, типа
таблиц идентификаторов и словарей, определяют объекты, которые имеют другие объекты. Эти
классы обеспечивают протокол для получения объекта IDs находящихся в собственности объектов.
 Используют iterator, чтобы шагнуть через список или устанавить объект. AcDb библиотека
обеспечивает множество iterators, которые могут использоваться, чтобы шагнуть через различные
виды контейнерных объектов (AcDbDictionaryIterator, AcDbObjectIterator).
 Сделать запрос набору выборов. После того, как пользователь выбрал объект, Вы можете
спрашивать, чтобы набор выборов для списка имен объекта выбранных объектов, и от имен,
преобразовал к объекту IDs. Для получения дополнительной информации на selectionsets, см. главу
6, “Объекты”.

Обязательные объекты Базы данных


Поскольку объекты созданы в AutoCAD, они добавлены к соответствующему контейнерному объекту в его
базе данных. Объекты добавлены к записям в блочной таблице. Записи Таблицы идентификаторов
добавлены к соответствующим таблицам идентификаторов. Все другие объекты добавлены к словарю имен
объектов или к объектам, которые принадлежат другим объектам (и, в конечном счете, тем же словарям), или
к словарю расширения. Сценарий в следующем разделе – “Создании Объектов в AutoCAD, ” детализирует
этот процесс. Словари Расширений обсуждены в разделе “Словарь Расширения” на странице 89.
Чтобы быть пригодной для использования, база данных должна иметь по крайней мере следующий набор
объектов:
 набор девяти таблиц идентификаторов, который включает блочную таблицу, таблицу уровня, и
linetype таблицу. Блочная таблица первоначально содержит три записи: *MODEL_SPACE, и два
пространства листа, называемые *PAPER_SPACE и *PAPER_SPACE0. Эти блочные записи таблицы
представляют модельное пространство и два предопределенных бумажных пространственных
размещения. Таблица уровня первоначально содержит одну запись - уровень 0. Linetype таблица
первоначально содержит тип линии CONTINUES.
 объектный словарь имен. Когда база данных создана, этот словарь уже содержит четыре словаря баз
данных: словарь GROUP, MLINE, LAYER, и PLOT. В пределах словаря стиля MLINE, стиль
STANDART - всегда существует.

Эти объекты могут быть автоматически созданы в новой базе данных при параметре kTrue в
конструкторе buildDefaultDrawing. Принятие KFalse создает пустую базу данных, в которую DWG или DXF
™ файл может быть загружен.

Создание объектов в AutoCAD


Этот раздел описывает создание строки, круга, уровня, и группы в AutoCAD и показывает, как AutoCAD
прибавляет эти объекты к базе данных. Сначала, предположите, что пользователь создает строку в
модельном пространстве command: line 4,2 10,7
В базе данных, AutoCAD создает образец класса AcDbLine и затем сохраняет это в модельном
пространственном блочном отчете таблицы как показано:

18
Когда Вы сначала вызываете AutoCAD, и база данных находится в ее заданном по умолчанию состоянии,
объекты добавлены в пространство модели, основное пространство в AutoCAD, который используется
для модельной геометрии и графики. Бумажное пространство предназначено, чтобы поддержать
“документационную” геометрию и графику, типа основ пленки для изготовления топологических чертежей,
блоков заголовка, и annotational текста. Команды создания объекта в AutoCAD (LINE, в этом случае)
заставляют объект быть добавленными к текущей базе данных также как к блоку пространства модели.
Вы можете спрашивать любой объект, принадлежащий базе данных.
Затем, предположите, что пользователь создает круг командой:

circle 9,3 2

Снова, AutoCAD создает образец соответствующего объекта — здесь, AcDbCircle — и прибавляет это к
пространству модели.

Затем, пользователь создает уровень:


layer_make mylayer
AutoCAD создает новую запись таблицы уровня и затем прибавляет его в таблицу уровней.

19
Наконец, группируем все объекты вместе:
group 3,2 9,3
AutoCAD создает новую группу и прибавляет ее к словарю GROUP, который содержится в объектном
словаре имен. Новая группа содержит список ID объектов, которые составляют группу.

Создании объектов в ObjectARX


Пример ObjectARX кода в этом разделе создает те же самые объекты как в предыдущем разделе (линия и
круг). Показывается код для создания нового уровня, изменение цвета линии, и добавления группы к
словарю GROUP.

Создание примитивов
Следующий код 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;
}

CreateLine() получает блочную таблицу для текущего рисунка.


Тогда это открывает в модельном пространстве запись блочной таблицы. После закрытия блочной таблицы,
это прибавляет объект к блочной таблице и затем закрывает таблицу и объект.
ОБРАТИТЕ ВНИМАНИЕ, когда Вы используете любые объекты ObjectARX, Вы должны их как можно скорее
закрыть.

createCircle () создает круг и прибавляет это к блочной таблице пространства модели:

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;
}

Создание Нового Уровня


Следующий код получает таблицу идентификаторов уровня от базы данных, создает новую запись таблицы
уровня ASDK_MYLAYER.

void
createNewLayer()
{
AcDbLayerTable *pLayerTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLayerTable, AcDb::kForWrite);

AcDbLayerTableRecord *pLayerTableRecord =
new AcDbLayerTableRecord;
pLayerTableRecord->setName("ASDK_MYLAYER");

// Defaults are used for other properties of


// the layer if they are not otherwise specified.
//
pLayerTable->add(pLayerTableRecord);
pLayerTable->close();
pLayerTableRecord->close();
}

21
Открытие и Закрытие объекта ObjectARX
Все примеры кода, показанные в этой главе иллюстрируют протокол для открытия и закрытия объектов,
который вы будете должны соблюсти всякий раз, когда Вы работаете с объектами резидента-базы. Этот
протокол гарантирует, что объекты - физически в памяти, когда к ним должны обращаться.Прежде, чем Вы
можете изменять объект, Вы должны открыть его:

acdbOpenObject(pObject, objId, AcDb::kForWrite);

Открытые функции имеют параметр режима, который определяет, открываете ли Вы объект для чтения,
записи или уведомления. В то время как объект открыт для записи, Вы можете изменять его. Когда Вы
закончите, Вы должны явно закрыть объект как показано в следующем примере, независимо от режима, в
котором это было открыто:

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
грохаться.

Добавление Группы к Словарю Группы


Cледующий код создает группу (pGroup) из линии и круга, созданного в createLine () и createCircle (), и
помещает группу в словарь GROUP. Объект IDs линии и круга пропускают в функцию. Обратите внимание, как
словарь GROUP открыт для записи, изменяется, и затем явно закрыт.

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();
}

Глава 3. Прикладные Основы ObjectARX


Эта глава описывает, как записывать и выполнить приложение ObjectARX. Это перечисляет сообщения,
которые пропускает в соответствии с AutoCAD к приложению ObjectARX и показывает, как приложение
типично отвечает на те сообщения. Эта глава также обсуждает регистрацию новых команд, как загружать и
разгружать приложение по запросу AutoCAD, особенности загрузки и обработку ошибок.

 Создание приложения ObjectARX


 Пример приложения
 Регистрация новых команд
 Загрузка приложения ObjectARX
 Разгрузка приложения ObjectARX
 Запрос на загрузку
 ARX Command

22
 Выполнение приложения ObjectARX

Создание приложения ObjectARX


Приложение ObjectARX - DLL, который совместно использует адресное пространство AutoCAD и делает
прямые функциональные запросы к AutoCAD. ObjectARX приложения типично осуществляют команды, к
которым можно обращаться изнутри AutoCAD.
Эти команды часто осуществляются, используя заказные классы. Создание приложения ObjectARX
подразумевает следующие общие шаги.
1. Создайте заказные классы, чтобы осуществить новые команды.
Вы можете получать заказные классы из большинства таблиц идентификаторов иерархии классов
ObjectARX.
2. Определите, которые сообщения AutoCAD ваше приложение ObjectARX обработает. AutoCAD
посылает разнообразие сообщений к приложениям ObjectARX, указывая, что специфические события
произошли в пределах AutoCAD. Вы решаете, которым сообщениям ваше приложение ответит и
которые действия будут вызваны.
3. Осуществьте точку входа для AutoCAD.
AutoCAD звонит в приложение ObjectARX через AcrxEntryPoint(), которая заменяет функцию main()
программы C++. Вы ответственны за осуществление acrxEntryPoint() в вашем приложении.
AcrxEntryPoint() вызывает функции, которые вы связали с определенными сообщениями AutoCAD.
4. Инициализация реализации.
В пределах вашего приложения ObjectARX, Вы будете должны инициализировать любые заказные
классы, что Вы создали, и восстанавливаете ObjectARX дерево классов во время выполнения.
Дополнительно, если Вы прибавляете команды, Вы должны регистрировать их в AutoCAD.
5. Готовьтесь к разгрузке.
Чтобы создавать хорошее приложение ObjectARX, Вы должны удалить любые заказные классы и
команды, когда ваше приложение разгружено.

Следующие разделы обсуждают общие шаги разработки приложения ObjectARX более подробно.

ОБРАТИТЕ ВНИМАНИЕ, что ObjectARX Мастер доступен для создания ObjectARX проекты. См.
objectarx\utils каталог в ObjectARX SDK.

Создание Заказных Классов


Вы можете получать заказные классы из большинства ObjectARX иерархии классов.
Это позволяет Вам усиливать функциональные возможности классов ObjectARX при создании ваших
собственных объектов. Определение заказных классов обсуждено подробно в гл. 11, "Получении Заказного
ObjectARX Класса".

Ответ на Сообщения AutoCAD


Имеются четыре категории сообщений, что AutoCAD посылает приложениям ObjectARX:
 Сообщения, которые посланы всем приложениям
 Сообщения, которые посланы только если приложение имеет зарегистрированную Alisp-функцию с
acedDefun()
 Сообщения, которые посланы приложениям, которые зарегистрированы как сервисы ObjectARX
 Сообщения, отвечающие приложениям, которые используют ActiveX Автоматизацию
Следующие пять таблиц описывают сообщения, что AutoCAD посылает toObjectARX приложению. Первая
таблица перечисляет сообщения, посланные всем приложениям.

Сообщения, посланные всем приложениям Message

Сообщение Описание

KInitAppMsg Посланный, когда приложение ObjectARX загружено, чтобы открыть связь


между AutoCAD и приложением.
KUnloadAppMsg Посланный, когда приложение ObjectARX разгруженно (или когда пользователь
разгружает приложение или когда сам AutoCAD закончен). Закрывает файлы и
исполняет операции очистки.
KLoadDwgMsg Посланным однажды, когда рисунок открыт. Тогда, если приложение
регистрируется, любые функции с Автошепелявят, AutoCAD посылает это
сообщение однажды за каждый рисунок, загруженный в редактора. Редактор
AutoCAD полностью инициализирован в этом точке, и все глобальные функции
доступны. Однако, Вы не можете использовать acedCommand () функция от
kLoadDwgMsg

23
KPreQuitMsgSent, когда AutoCAD выходит, но прежде, чем это начинает разгружать все
приложения ObjectARX..

Следующая таблица перечисляет сообщения, что AutoCAD посылает приложениям, которые имеют
буферизованный функцию AutoLISP с acedDefun ():

Сообщение Описание

kUnloadDwgMsg Посланный, когда пользователь выходит из сеанса рисунка.

kInvkSubrMsg Посланным, чтобы вызвать функции буферизованное использование


acedDefun ().
kEendMsg Посланным только, когда команда END введена и имеются изменения(замены),
которые должны быть сохранены (когда dbmod! = 0). KEndMsg не послан для
НОВОГО или ОТКРЫТОГО, вместо этого, kSaveMsg и kLoadDwgMsg посланы.
В течение КОНЦА, если dbmod = 0, то kQuitMsg послан вместо kEndMsg.
kQuitMsg когда выход из AutoCAD (заканчивается без того, чтобы сохранить рисунок
потому что QUIT команда была введена. KQuitMsg может также быть получен с
командой END, как отмечено выше.
Если команда END послана и dbmod = 0, то kQuitMsg послан.
kSaveMsg когда AutoCAD сохраняет рисунок потому что SAVE
SAVEAS, NEW или команда OPEN введены.

kCcfgMsgSent когда AutoCAD возвращается от программы конфигурации, и используемый


только для изменения драйвера дисплея.

Следующая таблица перечисляет сообщения, что приложение получает, если это имеет
зарегистрированный сервис с ObjectARX.

Сообщение Описание

KDependencyMsg когда приложение ObjectARX имеет буферизованный объект AcRxService и


индекс зависимости на тех сервисных изменениях от 0 до 1.
KNoDependencyMsgSent когда приложение ObjectARX имеет буферизованный объект AcRxService и
индекс зависимости на тех сервисных изменениях от 1 до 0.

Следующая таблица перечисляет сообщения, что приложение должно ответить к тому, если это
использует ActiveX Автоматизацию. См. главу 23, “ ОБЩАЯ ОБЪЕКТНАЯ МОДЕЛЬ, ActiveX
Автоматизация, и Объектный Менеджер Свойства. ”

Сообщение Описание

kOleUnloadAppMsg Посылается, чтобы определить, может ли приложение быть выгружено (то есть
ни один из его объектов ActiveX или интерфейсов не упомянут другими
приложениями).

См. rxdefs.h файл, где эти константы перечисления определены в соответствии с объявлением типа
AppMsgCode. Вы будете должны решить, на которые сообщения ваше приложение ObjectARX ответит.
Следующая таблица описывает рекомендуемые действия после получения данного сообщения.
ObjectARX прикладные реакции на сообщения AutoCAD

Сообщение Рекомендуемые действия

kInitAppMsg Регистрируйте услуги, классы, AcEd команды и реакторы, AcRxDynamicLinker


реакторы. Инициализируйте системные ресурсы приложения типа устройств
и окон.
Исполните всю одноразовую раннюю инициализацию.
AcRx, AcEd, и AcGe весь активен. Сохраните значение pkt параметра, если
Вы хотите разблокировать и повторно блокировать ваше приложение. Не
ожидайте, что драйверы устройства будут инициализированы, любые
ресурсы интерфейса пользователя быть активными, приложения, которые
будут загружены в специфическом порядке, будут автошепелявить, чтобы
присутствовать, или любые базы данных, чтобы быть открытыми. Запросы,

24
возводящие в степень любое из этих предположений приведут к состоянию
ошибки, иногда фатальному.
AcDb и AcGi библиотеки вообще еще не активен, хотя связано AcRx, и другие
структуры на месте

KUnloadAppMsg Исполняют заключительную системную очистку ресурса. Что-нибудь начатое


или созданное в kInitAppMsg должно теперь быть остановлено или
разрушено. Не ожидайте вещи быть любой отличным от описания
kInitAppMsg. AutoCAD мог быть главным образом демонтирован к времени,
этот запрос сделан, если бы не перечисленные библиотеки, поскольку
активный в kInitAppMsg Делают описание.
KOleUnloadAppMsg Это сообщение нужно ответить только приложениями, использующими
ActiveX Автоматизацию.
Ответьте с AcRx:: kRetOK, если приложение может быть вызгружено (ни один
из его объектов ActiveX или интерфейсов не упомянут другими
приложениями). Если это не может быть выгружено, отвечать с AcRx::
kRetError.
KLoadDwgMsg исполняют инициализацию, уместную текущему рисунку сеанса
редактирования. AcDb, AcGi, и интерфейс пользователя API - все теперь
активные.
Было ли что - нибудь сделано к рисунку, не определен.
Все Снабженные автохамом API теперь активны. Вы можете исполнять
регистрацию функции AutoLISP в это время, и инициализировать интерфейс
пользователя. Другие операции, чтобы исполнить теперь включают поллинг
драйверы AutoCAD и запрос AcEditorReactor события, если Вы хотите самый
ранний возможный доступ к acdbHostApplicationServices()->workingDatabase().
Не Делайте что - нибудь, что Вы не хотели бы случиться для каждого рисунка
сеанс редактирования. Предположите, что это сообщение послано больше
чем однажды в выполнение программы.
KUnloadDwgMsg выпускают или очищают все начатое или буферизованный в ответ на код
kLoadDwgMsg. Выпустите все AcDb реакторы, исключая постоянные
реакторы.
Не выпустите системные ресурсы, которые не связаны к сеансу
редактирования, или очищают классы AcRx, AcEd реакторы, или команды;
они остаются правильными(допустимыми) поперек сеансов редактирования.
KDependencyMsg исполняют любые действия, которые являются необходимыми для вашего
приложения, когда другие приложения станут зависящий от этого, типа
блокировки вашего приложения так, чтобы это не могло быть разгруженно.
KNoDependencyMsg исполняют любые действия, которые являются необходимыми для вашего
приложения, когда имеются больше не никакие другие приложения,
зависящие вашего, типа разблокирования вашего приложения так, чтобы это
могло быть разгруженно пользователем если желательно.
KInvkSubrMsg вызывают функции, буферизованные с acedDefun (). Определите функцию,
звоня по телефону к acedGetFuncode (). Возвращаемые значения с
acedRetxxx ().
Не Делайте много здесь кроме функционального обращения.
KPreQuitMsg разгружают любые зависимости (приложения, DLLs, и так далее) который
ваше приложение управляет, чтобы гарантировать, что они являются
разгруженным before your приложением.
kEndMsg Рассмотрите использование AcEditorReactor повторных вызовов случая как
kCfgMsg альтернатива к ответу на эти сообщения. Не ответьте на эти сообщения, если
kQuitMsg вы отвечаете на эквивалентные повторные вызовы случая, сделанные через
kSaveMsg AcEditorReactor.

Последовательность событий в приложении ObjectARX


Процесс проходящих сообщений между AutoCAD и приложением ObjectARX течет почти полностью в
одном направлении — от AutoCAD до приложения ObjectARX. Следующая диаграмма показывает
типичной последовательности прохождения сообщения.

25
Если приложение загружено, когда рисунок уже открытый, последовательно посланы сообщения
kInitAppMsg и kLoadDwgMsg. Когда приложение ObjectARX разгружено, в то время как сеанс
редактирования происходит - kUnloadDwg и kUnloadApp.

Осуществление Точки входа для AutoCAD


AutoCAD звонит в ObjectARX модуль через acrxEntryPoint (), который заменяет main() программы C++. Вы
ответственны за осуществление acrxEntryPoint (), как описано в этом разделе.
AcrxEntryPoint () функция служит как точка входа для AutoCAD, чтобы связаться с приложением ObjectARX.
ObjectARX программы может связываться с AutoCAD, возвращая коды состояния. Все запросы, чтобы
вызвать функции, определенные через acedDefun() сделаны с acrxEntryPoint(). Если Вы определяете новую
команду с
ObjectARX или с acedRegFunc(), AutoCAD немедленно выполняет функцию, связанную с командой (см. “
Загрузка ObjectARX Приложение ” на странице 43).
AcrxEntryPoint () функция имеет следующую сигнатуру:

extern "C"
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt);

msg Представляет сообщение, посланное от ObjectARX ядра К приложению.


pkt Содержит значения данных пакета.
AppRetCode Содержит код состояния, возвращенный AutoCAD.

В пределах определения acrxEntryPoint(), Вы записываете выключатель Операторный или подобный код,


чтобы декодировать сообщения от AutoCAD, исполнить Соответствующие действия, связанные с каждым
сообщением, и возвращением целочисленное состояние.

ПРЕДУПРЕЖДЕНИЕ! Использование kRetError для конечного возвращаемого значения от AcrxEntryPoint()


заставит ваше приложение быть разгруженным, кроме Для сообщений kOleUnloadAppMsg и
kUnloadAppMsg. В этих случаях, если KRetError возвращен, приложение не будет разгружено.

Следующий код показывает скелет допустимой инструкции выключателя:


AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch(msg) {
case AcRx::kInitAppMsg:
break;
case AcRx::kUnloadAppMsg:
break;
...
default:
break;

26
}
return AcRx::kRetOK;
}

Инициализация ObjectARX Приложения


Вы должны инициализировать любые заказные классы и команды, что ваше приложение определяет. Эта
инициализация может иметь место в любом AcRx::kInitAppMsg случае вашего acrxEntryPoint () или в функции,
называемой от этого случая.

Инициализация приложения ObjectARX


1, если Вы определили, заказной класс, вызывает его rxInit () функция.
Определение заказных классов обсуждено подробно в главе 11, при Получении a
Заказной ObjectARX Класс. ”
2, если Вы определили заказные классы, вызывают acrxBuildClassHierarchy() для восстановления ObjectARX
дерева классов во время выполнения. Для эффективности вызовите acrxBuildClassHierarchy() однажды после
запроса Rxinit() для каждого из ваших заказных классов.
3 Исполняют любую другую инициализацию, в которой Вы нуждаетесь.
4 Регистрируют сервисное название{*имя*}.
Регистрация сервисного названия{*имени*} предложена, будут ли другие приложения зависеть
На ваше приложение. Регистрация сервисного названия{*имени*} позволяет другие приложения
Регистрироваться в зависимости от обслуживания{*службы*}, и позволять вашему приложению
проверять{*отмечать*} если Это имеет любые зависимости перед разгрузкой. Регистрация сервисного
названия{*имени*} для Ваше приложение также необходимо, если Вы собираетесь экспортировать
символические функции от вашего приложения, использующего ObjectARX механизм. Вы можете
использовать acrxRegisterService(), или использование AcRxService класс. Для больше Информация
относительно регистрирующих услуг, см. документацию по AcRxService В ObjectARX справочниках.
5 Регистра командует с механизмом команды AutoCAD.
Используйте AcedRegCmds- > addCommand () чтобы делать AutoCAD, знающий команды
Это ваше приложение определяет. Для получения дополнительной информации, см. “ Регистрация Нового
Команды ” на странице 40.

Подготовка к Разгрузке
Когда ваше приложение разгружено, Вы должны очистить любые заказные классы или
Команды, которые ваше приложение создало. Это должно иметь место в 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");

// Удалить AsdkMyClass класс с ACRX времени выполнения


// Иерархия классов. Если это сделано, в то время как база данных
// Все еще активный, это должно вызвать все объекты{*цели*} класса
// AsdkMyClass, чтобы быть превращен в proxies.
//
DeleteAcRxClass (AsdkMyClass:: desc ());
}

Регистрация Новых Команд


Этот раздел описывает добавляющиеся новые команды, использующие команду AcEdсМеханизм
регистрации. Для информации относительно добавления нового использования команд Функции acedDefun() и
acedRegFunc (), см. главу 20, “ ObjectARX Глобальные Сервисные Функции. ” Для информации относительно
добавления нового использования команд ALisp функция defun, см. Руководство Настройки AutoCAD.

Стек Команды
Команды AutoCAD сохранены в группах в стеке команды, который
Определенный AcEdCommandStack классом. Один образец стека команды
Создан в сеанс AutoCAD. Этот стек состоит из заказных команд
То, что Вы определили. AcedRegCmds () макрокоманда дает Вам, обращаются к
Стек команды.
Когда Вы прибавляете команду, Вы также назначаете это название{*имя*} группы. Хорошая политика{*полис*}
Должен использовать ваш буферизованный префикс разработчика для названия{*имени*} группы, чтобы
избежать названия{*имени*}
Столкновения с другими командами. Команда называет в пределах данной группы
Должен быть уникален, и названия{*имена*} группы должны быть уникальны. Однако, множественные
приложения
Может прибавлять команду того же самого названия{*имени*}, потому что группа называет Делает команды
однозначными.

ОБРАТИТЕ ВНИМАНИЕ, что автоплата поддерживает схему регистрации разработчика


предотвратить Namespace находится в противоречии между различными приложениями. Каждый
буферизованный разработчик Выбирает одни или более буферизованные символы разработчика (RDS),
чтобы использовать исключительно. Буферизованный Символы разработчика - одно из требований “
Сформированные с ObjectARX ” программа эмблемы. Для получения дополнительной информации, идите
интерактивно к http://www.veritest.com/autodesk/main(f).htm.
Вы обычно прибавляете команды по одному с AcEdCommandStack:: addCommand () функция, и Вы
удаляете команды Группа с AcEdCommandStack:: removeGroup () функция. Вы можете также
Используйте AcEdCommandStack:: removeCmd () функция, чтобы удалить команды По одному. Как
часть его очистки перед выходом, ваше приложение нуждается к Удалите любые команды это
буферизованный.

Сигнатура для addCommand () функция

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.
Использование вашего зарегистрированного префикса разработчика также рекомендуется для имен группы.

Сигнатура для removeCmd()


virtual Acad::ErrorStatus
AcEdCommandStack::removeCmd
(const char* cmdGroupName,
const char* cmdGlobalName) = 0;

Сигнатура для removeGroup()


virtual Acad::ErrorStatus
AcEdCommandStack::removeGroup
(const char* groupName);

Порядок поиска
Когда команда вызвана, стек команды обыскан названием{*именем*} группы, затем названием{*именем*}
команды в пределах группы. Вообще, первая группа зарегистрировалась, будет первый обысканный, но Вы не
можете всегда предсказывать, каков этот заказ{*порядок*} будет. Используйте AcEdCommandStack::
popGroupToTop () функция, чтобы определить, что специфическая группа должна быть обыскана сначала. На
уровне пользователей, опция Group команды ARX позволяет пользователю определять которую группу искать
сначала.

Глобальная переменная против Местных Названий Команды


Когда Вы прибавляете команду к AutoCAD, Вы должны определить, и глобальное название{*имя*}, которое
может использоваться на любом языке и ограниченном названии{*имени*}, которое является
оттранслированной версией названия{*имени*} команды, которое нужно использовать в версии иностранного
языка AutoCAD. Если Вы не должны транслировать название{*имя*} команды в местный язык, то же самое
название{*имя*} может использоваться, и для глобальной переменной и местных названий{*имен*}.

Прозрачный против Модальных Команд


Команда может быть или прозрачна или модальная. Прозрачная команда может быть вызвана, когда
пользователь запрашивается относительно ввода. Модальная команда может быть вызвана только, когда
AutoCAD переносит приглашение ко вводу команды и никакие другие команды, или программы в настоящее
время активны. CommandFlags параметр к AcEdCommandStack:: addCommand () функция определяет ли
Новая команда - модальный (ACRX_CMD_MODAL) или прозрачный (ACRX_CMD_TRANSPARENT).
CommandFlags параметр также определяет другие опции для команды. См. AcEdCommandStack в ObjectARX
справочниках. Прозрачные команды могут быть вложены, только один уровень (то есть основная команда
вызван, который вызывает одну прозрачную команду).
Если Вы создаете множественные команды, которые работают на общем{*обычном*} наборе глобальных
объектов рассматривают, должны ли Вы делать их модальными так, чтобы они не Вмешайтесь друг с другом.

29
Если такие столкновения - не проблема, делая новые команды прозрачные результаты в большей гибкости
использования.

Загрузка ObjectARX Приложения


Вы можете загружать приложение ObjectARX, используя любой из следующих методов:
 Обеспечивают приложение особенностями, которые позволяют этому быть запросом,
загруженным в соответствии с AutoCAD. Эти особенности включают специфические для
приложения входы в Windows NT (или Windows ® 95) системный реестр. См. “ Загрузка
Запроса ” на странице 45.
 Определяют приложение в начальном файле модуля, acad.rx. Этот файл содержит текст
ASCII с именами всех программ AutoCAD, должен загрузиться, когда это начато. Каждая
строка в файле содержит название программы (с путем, если файл не в каталоге на пути
поиска файлов библиотеки AutoCAD). Acad.rx файл должен также быть в каталоге на пути
поиска файлов AutoCAD.
 Делают прикладной запрос загрузки от другого приложения ObjectARX, используя
AcRxDynamicLinker:: loadModule ().
 Используют диалоговое окно APPLOAD, определенное в премии AutoCAD, программируют
loadapp.arx.
 Используют arxload () функция от АвтоЛисп.
 Используют acedArxLoad () функция от ObjectARX.
 Вводят команду ARX в командную строку AutoCAD и используют опцию Load.

Путь поиска файлов


Если Вы не определяете, путь поиска файлов, загружая функции типа arxload ищет приложение в каталогах,
указанных путем библиотеки AutoCAD.
Путь библиотеки AutoCAD включает следующие каталоги в показанном порядке:
1. текущий каталог.
2. каталог, который содержит файл текущего рисунка.
3. каталоги, указанные путем поддержки (см. Руководство Настройки AutoCAD).
4. каталог, который содержит программные файлы AutoCAD.

Распечатка Загруженных ObjectARX Приложений


Чтобы видеть названия всех программ ObjectARX, в настоящее время загруженных, используйте опцию
команды ARX. Для получения дополнительной информации, см. “ ARX Команду ” на странице 53. Диалоговое
окно APPLOAD (определенный в премии AutoCAD программирует loadapp.arx) также перечисляет
названия{*имена*} программ ObjectARX, в настоящее время загруженных.

Разгрузка ObjectARX Приложения


Вы можете разгрузить приложение ObjectARX с любым из следующих методов (если это разблокировано):
 Заставят приложение разгрузить запрос от другого приложения ObjectARX, используя
AcRxDynamicLinker:: unloadModule ().
 Используют диалоговое окно APPLOAD, определенное в премии AutoCAD, программируют
loadapp.arx. Этот файл определяет интерфейс пользователя для Автошепелявящегося
arxload и функций arxunload.
 Используют функцию arxunload от Alisp.
 Используют acedArxUnload () функция от ObjectARX.
 Вводят команду ARX в командную строку AutoCAD и используют опцию Unload.

Разблокировка приложения
По умолчанию, приложения блокированы и не могут быть разгружены. Чтобы быть классифицирован как
“незагружаемое” приложение, приложение должно гарантировать, что AutoCAD и другие приложения больше
не обращаются{*относятся*} к любым объектам{*целям*}, или структурирует приложение, определил.
Прежде, чем Вы делаете приложение незагружаемым, быть очень осторожным, что никакие клиентские
приложения не содержат активные указатели на любые объекты{*цели*} в вашем адресном пространстве. Для
списка операций очистки приложение должно исполнить, чтобы быть незагружаемым, см. “ Подготовка к
Разгрузке ” на странице 38.
Если Вы хотите делать ваше приложение незагружаемым, Вы должны сохранить значение pkt параметра,
посланного с AcRx:: kInitAppMsg. Pkt параметр будет использоваться unlockApplication () на. По умолчанию,
прикладная программа блокирована. Если Вы разблокируете приложение, это может быть разгружено.

Используйте следующий две функции, чтобы блокировать и разблокировать приложение:


bool

30
AcRxDynamicLinker::lockApplication(void* pkt) const;
bool
AcRxDynamicLinker::unlockApplication(void* pkt) const;

Следующие функциональные проверки, действительно ли приложение блокировано:


bool
AcRxDynamicLinker::isApplicationLocked(const char* name) const;

Аналогичные глобальные функции также обеспечиваются:


bool
acrxLockApplication(void* pkt);
bool
acrxUnlockApplication(void* pkt);
bool
acrxApplicationIsLocked(const char* modulename);

Загрузка по запросу
Загрузка Запроса - особенность AutoCAD, который автоматически пытается загружать приложение
ObjectARX, которое - не резидент в AutoCAD. Приложения ObjectARX могут быть предназначены для
загрузки в соответствии с AutoCAD под одним или большим количеством следующих обстоятельств:
 когда читается чертежный файл, который содержит заказные объекты, созданные отсутствующим
приложением;
 когда пользователь или другое приложение выпускает одну из команд отсутствующего приложения;
 когда AutoCAD начат;

ОБРАТИТЕ ВНИМАНИЕ На приложения, которые осуществляют загрузку запроса на запуске AutoCAD,


будет загружен прежде, чем перечисляли в acad.rx.

AutoDesk рекомендует разработать приложения ObjectARX, которые воспользуются преимуществом


загружающей запроса особенности AutoCAD потому что загрузка запроса, обеспечивая следующие выгоды:
 Ограничивает создание полномочных объектов (см. главу 14, “ Полномочные Объекты”)
 Обеспечивает большую гибкость для загрузки приложений ObjectARX
 Сохраняет память, загружая приложения только, когда их функциональные возможности требуются
Для приложения, чтобы быть доступный для загрузки запроса, специфическая для приложения информация
должна присутствовать в системном реестре системы Windows. Кроме того, Приложения ObjectARX с больше
чем один DLL могут нуждаться в модуле “контроллера”, который является ответственным за загрузку всех
других компонентов
Приложение. Наконец, DEMANDLOAD системная переменная должна быть установлена в соответствующее
значение для загрузки запроса.

ОБРАТИТЕ ВНИМАНИЕ, что приложение ObjectARX может быть запрос, загруженный от пути на местной
машине, или, используя адрес Internet.

AutoCAD, Системный реестр Системы Windows, и Приложения


ObjectArx
AutoCAD использует системный реестр системы Windows, чтобы поддержать широкий диапазон прикладной
информации, включая информацию, которая уникально идентифицирует различный AutoCAD, выпуск версии
языка и программы (типа Карты AutoCAD ®) который может быть установлен на любом данном компьютере.
Информация системного реестра, которая идентифицирует различные версии AutoCAD, имеет
специфическое значение для ObjectARX разработчиков. Инсталляционная программа для приложения
ObjectARX должна присоединить информацию относительно того Приложения ObjectArx с информацией
относительно версии(й) AutoCAD, с которым предполагается работать.
Программа инсталляции AutoCAD создает уникальную клавишу{*ключ*} временной метки в системном
реестре немедленно ниже цифровой клавиши выпуска (также как добавление той же самой инсталляции ID к
выполнимой программе непосредственно). Эта клавиша{*ключ*} гарантирует, что различные версии AutoCAD
от того же самого выпуска будут способны заполнить их собственные разделы системного реестра. В
пределах этой клавиши{*ключа*}, значения сохранены для местоположения файлов AutoCAD, версии языка, и
названия{*имени*} изделия{*программы*}, как иллюстрировано в этом примере:

\\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
...

Инсталляционная программа для Приложения ObjectArx должна быть способна расположить


соответствующий выпуску AutoCAD клавишу{*ключ*}, также как соответствующий язык и значения программы.

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 истощена.

Модификация Системного реестра при Инсталляции Приложения


ObjectArx
AutoCAD использует Windows NT (или Windows 95) системный реестр, чтобы расположить Приложения
ObjectArx для загрузки запроса. Часть раздела AutoCAD системного реестра используется для информации
относительно местоположения информации системного реестра ObjectARX appli-cations'.
Инсталляционная программа для Приложения ObjectArx должна создать определенные клавиши{*ключи*} и
значения в системном реестре, которые требуются для загрузки запроса. Некоторые из требуемых
клавиш{*ключей*} и значений должны быть созданы в разделе AutoCAD системного реестра, и другие должны
быть созданы в разделе приложения ObjectARX системного реестра.
Если Приложение ObjectArx разработано{*предназначено*}, чтобы работать с больше чем одной версией
AutoCAD (то есть различных версий языка или связанных изделий{*программ*}, типа Карты AutoCAD),
инсталляционная программа должна прибавить соответствующую информацию к разделу системного реестра
для каждой версии AutoCAD.
Инсталляционный процесс для Приложений ObjectArx должен поэтому включить:
 Проверка, что разделы системного реестра для соответствующей версии AutoCAD существуют. (Если
раздел AutoCAD системного реестра не существует, пользователь должен быть предупрежден, что
совместимая версия AutoCAD не была установлена, и инсталляция должна быть прервана.)
 Создание определенного набора клавиш{*ключей*} и значений для приложения в пределах раздела
(ов) системного реестра для соответствующей версии (й) AutoCAD.
 Создание главной клавиши{*ключа*} для приложения непосредственно, и совокупности той
клавиши{*ключа*} с другим набором определенных клавиш{*ключей*} и значений. См.
\objectarx\samples\polysamp\demandload каталог ObjectARX
SDK для информации относительно того, как системный системный реестр изменяется для запроса,
загружающего типовую программу polysamp.
Следующий два раздела описывают, как инсталляционная программа приложения должна создать системную
информацию системного реестра, требуемую для загрузки запроса. Типовая инсталляционная программа
включена в \objectarx\utils каталог ObjectARX SDK.

Создание Дополнительных клавиш AutoCAD и Значений


Программа инсталляции приложения ObjectARX должна быть разработана{*предназначена*}, чтобы
управлять набором клавиш{*ключей*} и значений для того приложения в пределах раздела системного
системного реестра для каждой версии AutoCAD, с которым предназначено работать. Следующий пример
показывает размещению клавиш{*ключей*} и значений в разделе системного реестра, который должен быть
создан и поддерживаться для приложения:

\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\releaseNum\
ACAD-1:LocaleID\
Applications\
ApplicationName\
LoadCtrls:REG_DWORD:acrxAppLoadReason
RegPath:REG_SZ:RegistryPathWhereLoaderIsSpecified

ReleaseNum и клавиши{*ключи*} ACAD-1:LocaleID созданы программой инсталляции AutoCAD.


Клавиша{*ключ*} ApplicationName должна быть логическое название{*имя*} приложения, которое используется
внутренне в соответствии с AutoCAD, чтобы идентифицировать программу. Значение acrxAppLoadReason
определяет условия, при которых приложение будет загружено, используя один или более логический ORS
следующих шестнадцатеричных значений, перечисленных с их связанными значениями:

0x01 Загружают приложение после обнаружения полномочного объекта{*цели*}.


0x02 Загружают приложение после запуска AutoCAD.

32
0x04 Загружают приложение на обращение команды.
0x08 Загружают приложение по запросу пользователем или другим приложением.
0x10 Не загружают приложение.

Значение RegistryPathWhereLoaderIsSpecified должно идентифицировать путь системного реестра для


собственного раздела приложения системного реестра.
ObjectARX API включает acrxRegisterApp () функция, которая может использоваться в Приложении ObjectArx,
чтобы ввести информацию относительно приложения в раздел AutoCAD системного реестра. Как правило,
acrxRegisterApp () ввел бы эту информацию, первый раз, когда приложение загружен, и подтверждать
присутствие той информации относительно последующих загрузок.

Создание ключей и значений приложения ObjectArx


Программа инсталляции приложения ObjectARX должна быть разработана, чтобы управлять разделом
приложения системного реестра. Этот раздел системного реестра должен включить клавиши{*ключи*} и
значения, идентифицирующие основной модуль приложения и набора команд для приложения.

Значение в клавише{*ключе*} 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 и поэтому команды также.

Удаление Системной Информации Системного реестра


Может быть полезно удалить информацию Приложения ObjectArx от системного реестра, если приложение
модернизировано или удалено. ObjectARX API включает функцию acrxUnregisterApp (), который является
коллегой acrxRegisterApp (). Это удаляет информацию относительно приложения от раздела AutoCAD
системного реестра.

Системная переменная DEMANDLOAD


AutoCAD DEMANDLOAD переменная системы управляет опциями загрузки запроса Приложений ObjectArx. По
умолчанию DEMANDLOAD системная переменная установлена (когда AutoCAD установлен) чтобы допустить
загрузке запроса приложений на обращении команды или на полномочном обнаружении, когда любая опция
определена в системном входе системного реестра для приложения. Установка DEMANDLOAD не затрагивает
загрузку запроса на запуске AutoCAD, или по запросу пользователем или приложением, когда любая из этих
опций определена в системном системном реестре. (См. “ Создание Дополнительных клавиш AutoCAD и
Значений ” на странице 48).

Законные значения для системной переменной могут использоваться в комбинации.


Они определены следующим образом:

0 Отключает загрузку запроса всех Приложений ObjectArx.


1 Допускает загрузке запроса Приложений ObjectArx после обнаружения полномочных объектов{*целей*}.
2 Допускает загрузке запроса Приложений ObjectArx на обращение команды.
3 Допускает загрузке запроса для и полномочных объектов{*целей*} и обращения команды (значение по
умолчанию).

33
DEMANDLOAD системная переменная позволяет пользователю отключать загрузку запроса всех Приложений
ObjectArx, которые имеют системные параметры настройки системного реестра, определяющие загрузку
запроса на обращении команды, и полномочном обнаружении. Это не может заставлять приложение быть
загруженным запросом, если соответствующие системные параметры настройки системного реестра не
существуют.

Загрузка Запроса на Обнаружении Заказных Объектов{*целей*}


Когда DWG или DXF файл, содержащий заказные объекты загружен, AutoCAD определяет,
действительно ли приложение - обработчик загружено. Если приложение не загружено, и первый
бит переменной системы DEMANDLOAD установлен, AutoCAD ищет системный реестр системы
Windows информацию относительно приложения и его модуля загрузчика. Если AutoCAD находит
соответствующую информацию в системном реестре, это загружает приложение.

ОБРАТИТЕ ВНИМАНИЕ, что загрузка Запроса на обнаружении заказных классов будет только
работать с классами, которые получены из 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, и загрузка продолжается.

Загрузка Запроса на Команде


AutoCAD будет пытаться загружать соответствующее Приложение ObjectArx, если пользователь вызывает
команду, которая не зарегистрирована с AutoCAD.
Чтобы поддерживать загрузку запроса на обращении команды, программа инсталляции приложения
ObjectARX должна создать соответствующие клавиши{*ключи*} и значения в системном реестре для команд
приложения. Раздел приложения Commands системного реестра должен содержать информацию команды
подобно этому:

\\ 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 макрокоманде для
загрузки запроса на команде, чтобы работать.

Загрузка Запроса на Запуске AutoCAD


Загрузка Запроса Приложения ObjectArx на запуске AutoCAD может быть определена, используя 0x02 (или
Вы можете исполнять ИЛИ 0x02 с другим законным значением) со значением LoadCtrls в системном реестре,
как показано здесь.

\\HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R15.0\
ACAD-1:409\
Applications\PolyCAD\
LoadCtrls:REG_DWORD:0x02
RegPath:REG_SZ:

Управление Приложениями с Системным реестром


Как только системная информация системного реестра была создана для загрузки запроса, что та же самая
информация может использоваться набором функций ObjectARX, чтобы загружать, разгрузить, и
контролировать присутствие Приложений ObjectArx, независимых от загружающей запроса особенности.
Параметр AppName, используемый первой двумя из этих функций - логическое прикладное название{*имя*}.
Следующие функции ObjectARX могут использоваться с зарегистрированными прикладными
названиями{*именами*}:
Bool acrxLoadApp ("AppName")
Эта функция берет одиночный параметр, который представляет случай{*регистр*} -нечувствительное
логическое название{*имя*} приложения, которое будет загружено. Функция возвратилась бы 0, если загрузка
потерпела неудачу, или 1, если загрузка преуспевает.
Bool acrxUnloadApp ("AppName")
Эта функция берет одиночный параметр, который представляет случай{*регистр*} -нечувствительное
логическое название{*имя*} приложения, которое было предварительно загружено. Функция возвращается 0,
если разгруженные сбои, или 1, если это преуспевает.
Пусто *acrxLoadedApps ()
Эта функция возвращает массив строк как пустой *, содержа логическое прикладное название{*имя*} каждого
приложения, которое в настоящее время загружено. Функциональные возвращения ПУСТОЙ УКАЗАТЕЛЬ,
если никакие приложения не загружены. Это - ответственность вызывающей программы выпустить
пространство{*пробел*}, распределенное для возвращенных строк.

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
была выполнена.

Command Group Name: Enter the command group name

Заказ{*порядок*} поиска важен только, когда название{*имя*} команды перечислено в множественных группах.
Этот механизм позволяет различным приложениям ARX определять те же самые названия{*имена*} команды
в их собственных отдельных группах команд.
ARX приложения, которые определяют группы, команд должны издать название{*имя*} группы в их
документации.
Группа не предназначена, чтобы быть выбранной пользователем непосредственно. Пользователь определяет,
которая группа обыскана сначала, взаимодействуя со сценарием, который выполняет команду ARX с опцией
Group. Эта возможность обычно внедряется в ключевые сценарии пункта меню. Пользователь выбирает пункт
меню от сценария.
Ключевой сценарий пункта меню выполняет опцию Group, чтобы установить, которая группа обыскана
сначала, давая команды того же самого названия{*имени*} (но вероятно различные функциональные
возможности) от одного прикладного старшинства по командам от другого.
Например, приложения по имени ABC и XYZ Интерьеры определяют группы ABC команд и XYZ,
соответственно. Большинство команд Конструкции ABC названо с терминологией конструкции, в то
время как большинство XYZ команды Интерьеров названо со внутренней областью, украшающей
терминологию, но и приложения определяют команды по имени INVENTORY и ORDERS. При работе
над аспектами конструкции рисунка, пользователь выбирает пункт меню, определенный
Конструкцией ABC, и следующий сценарий выполняется:
ARX
Группа
ABC
Сценарий выталкивает набор команд Construction ABC, чтобы дать этому высший приоритет и
решать INVENTORY к версии Конструкции ABC команды. Позже, когда внутренний проектировщик
работает над рисунком к тому же самому набору загруженных приложений, выбор, ключевой
значок гарантирует, что XYZ команды Интерьеров имеют старшинство.

ОБРАТИТЕ ВНИМАНИЕ, что группы Command не связаны с командами, определенными в


AutoLISP или определены запросом к acedDefun () Приложениями ObjectArx. Программный
механизм, который определяет группы команд, описан в “ Заказ{*порядок*} Поиска ” на странице
42.

 Classes
Отображает иерархию классов классов C++, полученных из объектов{*целей*}, зарегистрированных в
системе, ли зарегистрированный в соответствии с AutoCAD или в соответствии с программой ARX.
 Services
Перечисляет названия{*имена*} всех услуг, зарегистрированных в соответствии с AutoCAD и в
соответствии с загруженными программами ARX.

Выполнение Приложений ObjectArx от AutoLISP


Приложение ObjectArx может определять набор функций, известных к AutoLISP как внешние функции,
используя acedDefun (). После того, как приложение загружено, Вы можете вызывать внешнюю функцию
точно, поскольку Вы можете вызывать встроенную или определяемую пользователем функцию AutoLISP.
Переменные AutoLISP можно пропускать как параметры к внешней функции, и внешняя функция может
возвращать результат.
Внешняя функция может также запрашивать пользователя вводить данные, или от клавиатуры или,
определяя пункты{*точки*} или объекты{*цели*} с устройством управления позицией, и внешняя функция
может устанавливать Windows или AutoCAD платформа-независимая справка.

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

Инициализация базы данных


Когда сеанс AutoCAD начинается, база данных содержит следующие элементы:
 N набор девяти таблиц идентификаторов.
Block table (AcDbBlockTable)
Dimension style table (AcDbDimStyleTable)
Layer table (AcDbLayerTable)
Linetype table (AcDbLinetypeTable)
Registered applications table (AcDbRegAppTable)
Text style table (AcDbTextStyleTable)
User Coordinate System table (AcDbUCSTable)
Viewport table (AcDbViewportTable)
View table (AcDbViewTable)

Некоторые из таблиц идентификаторов уже содержат один или большее количество записей. Таблица
уровня содержит уровень 0. Блочная таблица первоначально содержит три записи: *MODEL_SPACE,
*PAPER_SPACE, и *PAPER_SPACE0. Linetype таблица всегда имеет НЕПРЕРЫВНЫЙ, BY_LAYER, и
BY_BLOCK linetype. Таблица зарегистрированных приложений всегда имеет ACAD. Текстовая таблица
стиля всегда имеет СТАНДАРТНЫЙ.
 словарь имен объектов. Когда база данных создана, этот словарь уже содержит два словаря баз
данных: словарь ГРУППЫ и MLINE словарь стиля. В пределах MLINE словаря стиля, СТАНДАРТНЫЙ
стиль - всегда имеется.
 N фиксированный набор переменных заголовка. (Они - не объекты базы данных.)

Создание и Начальная загрузка Базы данных


Используйте new, чтобы создать базу данных и delete, чтобы уничтожить ее. AcDbDatabase конструктор имеет
один параметр со значением по умолчанию Adesk:: kTrue. Если этот параметр - Adesk:: kTrue, то база данных
заполняется со стандартными объектами базы данных, описана в “ Начальная База данных. ”, если параметр
- Adesk:: kFalse, то пустая база данных создана и может заполняться, считывая чертежный файл.
Используйте следующую функцию, чтобы читать в чертежном файле:

AcadErrorStatus
AcDbDatabase::readDwgFile(char* fileName);

Если Вы получаете любой из кодов ошибки слежения, Вы вероятно хотите возвратить рисунок к стандарту,
AutoCAD возвращает механизм, обеспеченный интерфейсом пользователя:

KDwgNeedsRecovery
KDwgCRCDoesNotMatch
KDwgSentinelDoesNotMatch
KdwgObjectImproperlyRead

ПРЕДУПРЕЖДЕНИЕ! Никогда не удалите базу данных, возвращенную acdbHostApplicationServices()-


>workingDatabase().

Сохранение Базы данных


Чтобы сохранять базу данных, используйте AcDbDatabase:: saveAs () функция:

39
Acad:: ErrorStatus
AcDbDatabase:: saveAs (char* имя файла);

Имя файла может быть путь к местному файлу, или адресу Internet.

Установка Заданного по умолчанию Формата файла


ObjectARX обеспечивает способность определить заданный по умолчанию формат файла для SAVEAS,
SAVE и команд QSAVE. (Команда AUTOSAVE всегда сохраняет рисунки в формате чертежного файла
AutoCAD 2000.)
Класс AcApDocument содержит перечисление, которое определяет формат, используемый при сохранении
рисунка к файлу. Его значения показываются в следующей таблице:

Name Usage (file extension)


kR12_dxf AutoCAD Release 12/LT2 DXF (*.dxf)

kR13_dwg AutoCAD Release 13/LT95 Drawing (*.dwg)

kR13_dxf AutoCAD Release 13/LT95 DXF (*.dxf)

kR14_dwg AutoCAD Release 14/LT97 Drawing (*.dwg)

kR14_dxf AutoCAD Release 14/LT97 DXF (*.dxf)

kR15_dwg AutoCAD 2000 Drawing (*.dwg)

kR15_dxf AutoCAD 2000 DXF (*.dxf)

kR15_Template AutoCAD 2000 Drawing Template File (*.dwt)

kNative Current DWG version is AutoCAD 2000

kUnknown Invalid format

AcApDocument:: formatForSave () функция возвращается, поток{*ток*} сохраняет{*экономит*} формат,


используемый SAVEAS, СОХРАНЯЕТ{*ЭКОНОМИТ*}, и командами QSAVE:
AcApDocument:: SaveFormat
FormatForSave ();
Возвращенное значение может быть или сеанс-широкая настройка по умолчанию, или различная установка,
которую пользователь выбрал для этого документа. Если это - перегрузка для этого документа, это не будет
упорствовать{*сохраняться*} поперек сеансов.
AcApDocmanager:: setDefaultFormatForSave () функция использует одно из значений SaveFormat, чтобы
заставить формат файла использовать при сохранении рисунка к SAVEAS, СОХРАНЯТЬ{*ЭКОНОМИТЬ*}, и
командам QSAVE. Это устанавливает сеанс-широкое значение по умолчанию, которое пользователь может
выбирать временно перегружать для индивидуального документа:
Acad:: ErrorStatus
SetDefaultFormatForSave (
AcApDocument:: формат SaveFormat);
Эти функции только непосредственно сообщают относительно или устанавливают формат файла для
интерактивных команд, введенных пользователем. Если Вы хотите, чтобы ваше приложение использовало
поток{*ток*}, сохраняют{*экономят*} формат, каждый раз Вы желаете сохранить{*экономить*} базу данных, Вы
будете сначала должны вызвать{*назвать*} formatForSave (), и затем использовать возвращенное значение
SaveFormat, чтобы определить, которые функционируют, чтобы звонить. Например, если бы formatForSave ()
возвратил kR14_dxf, Вы вызвали бы{*назвали бы*} acdbDxfOutAsR14 () чтобы записать базу данных как
Выпуск 14 DXF файл.
Убедитесь, что брали следующий во внимание:
 Или Вы или ваш пользователь можете устанавливать постоянный сеанс-широкий заданный по
умолчанию формат для, сохраняют{*экономят*}, который будет удостоен, все сохраняют{*экономят*}
команды кроме, АВТОСОХРАНЯЮТ{*АВТОЭКОНОМЯТ*}.
 Только пользователь может временно (не постоянно между сеансами) перегружают эту установку для
специфического документа.
 formatForSave () метод возвращает формат, в котором пользователь желает, чтобы индивидуальный
документ был сохранен; это будет или сеанс-широкое значение по умолчанию или временная
перегрузка, как соответствующий.

Глобальные функции сохранения


ObjectARX также содержит две глобальных функции для сохранения рисунков:

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.

Создание Новой Базы данных от Существующей Базы данных


Следующая функция - эквивалент команды WBLOCK*:

Acad:: ErrorStatus
AcDbDatabase::wblock(AcDbDatabase*& NewDb);

Эта функция создает новую базу данных от вызванной базы данных ("this").
Любые неупомянутые символы во входной базе данных опущены в новой базе данных (который делает новую
базу данных потенциально уборщиком и меньший чем оригинал). Однако, это не заботится о копировании
определенных приложением объектов, чей монопольное использование внедрено в названном объектном
словаре. Вы должны передать{*переместить*} данные прикладной программы от исходной базы данных до
целевой базы данных, используя AcEditorReactor функции уведомления.

Создание Новой Базы данных с примитивами


Другие две формы AcDbDatabase:: wblock () функция создает новую базу данных, чей образцовый
пространственный блочный отчет{*запись*} таблицы содержит указанные объекты от входной базы данных.
Первая форма этой функции копирует объекты с названного блочного отчета{*записи*} таблицы. Вторая
форма функции копирует массив объектов.

Копирование Названного Блока


Следующая функция эквивалентна вызову команды WBLOCK с названием{*именем*} блочного определения:

Acad:: ErrorStatus
AcDbDatabase::wblock(AcDbDatabase*& NewDb,
AcDbObjectId recordId);

RecordId параметр представляет блочный запись таблицы во входной базе данных.


Объекты в этом блочном записи таблицы скопированы в образцово - пространственный блочный запись
таблицы новой базы данных. Ядро вставки новой базы данных - блочное начало координат записи таблицы.

Копирование Массива примитивов


Следующая функция эквивалентна вызову команды WBLOCK и затем использование опции, чтобы выбрать
определенные объекты и определять арифметическую запятую вставки:

Acad::ErrorStatus
AcDbDatabase::wblock(AcDbDatabase*& newDb,
const AcDbObjectIdArray& idArray,
const AcGePoint3d* point);

Эта функция создает новую базу данных, которая включает объекты, указанные в idArray параметре.
Объекты, которые могут быть в образцовых пространственных или бумажных пространственных блочных
отчетах{*записях*} таблицы входной базы данных, помещены в образцовое пространство{*пробел*} новой
базы данных. Также включенный в новую базу данных - объекты, принадлежащие или упомянутый теми
объектами, также как владельцами тех объектов. Указанный пункт{*точка*} - пункт{*точка*} начала координат,
во внешних координатах, для нового рисунка (то есть это - арифметическая запятая вставки в образцовом
пространстве{*пробеле*} новой базы данных).

Вставка Базы данных


AcDbDatabase:: вставка () функции копируют одну базу данных в базу данных, на которую функция элемента
вызвана. AutoCAD объединяет объекты, которые это определяет, типа MLINE стиля и словарей ГРУПП;
однако, это не заботится о копировании определенных приложением объектов, чей монопольное
использование внедрено в названном объектном словаре. Вы должны передать{*переместить*} данные
прикладной программы от исходной базы данных до целевой базы данных, используя AcEditorReactor
функции уведомления.

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) к объектам.

Установка Текущих Значений Базы данных


Если свойство данных типа цвета или linetype не определено для объекта, текущее значение базы данных,
для которого данные используются. Следующие разделы выделяют функции, имел обыкновение определять
текущие значения данных, связанные с базой данных.

Номер цвета Базы данных


Если цвет не определен для объекта, текущего номера цвета базы данных, сохранен в CECOLOR системной
переменной, используется. Следующий набор функций и восстанавливает{*отыскивает*} текущий номер цвета
в базе данных:

Acad::ErrorStatus
AcDbDatabase::setCecolor(const AcCmColor& color);

AcCmColor AcDbDatabase::cecolor() const;

База данных Linetype Значение


Следующий набор функций и восстанавливает{*отыскивает*} поток{*ток*} linetype значение в базе данных:

Acad::ErrorStatus
AcDbDatabase::setCeltype(AcDbObjectId);

AcDbObjectId AcDbDatabase::celtype() const;

База данных Linetype Значение Масштаба


База данных имеет три linetype параметры настройки масштаба:
 установка масштаба linetype для текущего объекта, сохраненного в CELTSCALE системной
переменной.
 установка масштаба linetype для текущего рисунка, сохраненного в LTSCALE системной переменной.
 флажок, который указывает, применить ли linetype, масштабирующий к пространству{*пробелу*},
объект постоянно находится в или к появлению{*виду*} объекта в бумажном пространстве{*пробеле*}.
Эта установка сохранена в PSLTSCALE системной переменной.

Глобальная переменная LTSCALE и PSLTSCALE параметры настройки используется, когда рисунок


восстановлен (см. главу 6, “примитивы”). Используйте следующие функции, чтобы устанавливать и запросить
эти значения:

Acad::ErrorStatus
AcDbDatabase::setLtscale(double);

double AcDbDatabase::ltScale() const;

Acad::ErrorStatus

42
AcDbDatabase::setCeltscale(double);

double AcDbDatabase::celtscale() const;

Acad::ErrorStatus
AcDbDatabase::setPsltscale(Adesk::Boolean)
Adesk::Boolean AcDbDatabase::psltscale() const;

Значение Уровня Базы данных


Следующий набор функций устанавливает и восстанавливает текущее значение уровня в базе данных:

Acad::ErrorStatus
AcDbDatabase::setClayer(AcDbObjectId);

AcDbObjectId AcDbDatabase::clayer() const;

Пример Операций Базы данных


Следующий пример показывает createDwg () подпрограмма, которая создает новую базу данных, получает
образцовый пространственный блочный отчет{*запись*} таблицы, и создает два круга, которые добавлены,
чтобы моделировать пространство{*пробел*}. Это использует AcDbDatabase:: saveAs () функция, чтобы
сохранить{*экономить*} рисунок. Вторая подпрограмма, readDwg (), читает в сохраненном рисунке, открывает
образцовый пространственный блочный отчет{*запись*} таблицы, и выполняет итерации через это, печать
имена класса объектов, которые это содержит.

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. Эти классы и функции обеспечивают схему
приложений, чтобы проверить объекты для редактирования и проверяют{*отмечают*} их назад в к их
первоначальному местоположению. Эта операция заменяет первоначальные объекты отредактированными.
Имеются три типа длинного операционного контроля:
 От нормального блока в пределах того же самого рисунка
 От внешней ссылки (таблица перекрестных ссылок) рисунка
 От несвязанной, временной базы данных

Класс и Функциональный Краткий обзор


Основные классы и функции
 AcDbLongTransaction класс
 AcDbLongTransWorkSetIterator класс
 AcApLongTransactionReactor класс
 AcApLongTransactionManager класс
 AcDbDatabase:: wblockCloneObjects () функция
AcDbLongTransaction Класс
AcDbLongTransaction - класс, который содержит информацию, необходимую, чтобы проследить длинную
сделку. AcDbLongTransactionManager класс берет ответственность за создание и добавление в конец
объектов AcDbLongTransaction к базе данных. Это тогда возвращает AcDbObjectId объекта
AcDbLongTransaction. Подобно всем другим объектам резидента базы, его разрушение обработано базой
данных.
ОБРАТИТЕ ВНИМАНИЕ, что объекты AcDbLongTransaction добавлены к базе данных, в то время как они
активны и стерты, как только сделка завершила. Они не сохранены в DWG или DXF файлах, и поэтому не
постоянны.
AcDbLongTransWorkSetIterator Класс
AcDbLongTransWorkSetIterator обеспечивает доступ только для чтения к объектам в наборе работ. В течение
конструкции в AcDbLongTransaction:: newWorkSetIterator (), это может быть установлено, чтобы включить
только активный набор работ, или включать объекты, добавлялся к набору работ, потому что они упомянуты
объектами в наборе работ (вторичные объекты). Это может также обрабатывать объекты, удаленные из
набора работ, или AcDbLongTransaction:: removeFromWorkSet (), или, стирая.
AcApLongTransactionReactor Класс
AcApLongTransactionReactor обеспечивает уведомление определенным к длинным операционным операциям.
Это разработано{*предназначено*}, чтобы использоваться вместе с глубокими уведомлениями аналога,
которые будут также посланы, но изменятся, в зависимости от которого тип контроля / в выполняется. Чтобы
подключить эти уведомления с глубокими уведомлениями аналога, объект AcDbIdMapping, используемый для
имитации может быть восстановлен{*отыскан*}, вызывая AcDbLongTransaction:: activeIdMap () функция.
AcApLongTransactionManager Класс
AcApLongTransactionManager - менеджер для старта и управления длинными трудами. Имеется только один
для каждого сеанса AutoCAD, и к этому обращаются через указатель, возвращенный объектом
acapLongTransactionManager.
AcDbDatabase:: wblockCloneObjects () Функция
WblockCloneObjects () функция - элемент AcDbDatase. Это будет глубоко имитировать объекты от одной базы
данных до другой и следовать за жесткими ссылками{*справочниками*} так, чтобы все зависимые объекты
также имитировались. Поведение отчетов{*записей*} таблицы идентификаторов, когда дубликаты найдены,
определено параметром типа. Следующая диаграмма показывает отношениям между типом таблицы
идентификаторов (перечисление DuplicateRecordCloning) и глубокий тип аналога (перечисление
DeepCloneType).

44
Отношения между DeepCloneTypes и DuplicateRecordCloning для Различные команды и функции

Command or API DeepCloneType DuplicateRecordCloning


Function
COPY kDcCopy kDrcNotApplicable
EXPLODE kDcExplode kDrcNotApplicable
BLOCK kDcBlock kDrcNotApplicable
INSERT/BIND kDcXrefInsert kDrcIgnore
XRESOLVE kDcSymTableMerge kDrcXrefMangleName
INSERT kDcInsert kDrcIgnore
insert() kDcInsertCopy kDrcIgnore
WBLOCK kDcWblock kDrcNotApplicable
deepCloneObjects() kDcObjects kDrcNotApplicable
wblockObjects() kDcObjects kDrcIgnore
wblockObjects() kDcObjects kDrcReplace
wblockObjects() kDcObjects kDrcMangleName
wblockObjects() kDcObjects kDrcUnmangleName

Пример длинной транзакции


Эти простые показы примера, как проверять объекты от другой базы данных, измените их в текущей базе
данных, и затем проверьте{*отметьте*} их назад в к первоначальной базе данных. Запросы, которые являются
частью длинного операционного процесса, обозначены в полужирной печати.

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 Ссылку{*справочники*}.
Объекты Таблицы перекрестных ссылок в рисунке могут изменяться, но они не могут быть сохранены к
первоначальному рисунку таблицы перекрестных ссылок (рисунок оригинала только для чтения).

Внешняя ссылка Пред- и Последующая обработка


Внешняя ссылка (таблица перекрестных ссылок) пред- и последующая обработка делает возможным
восстановить приложенную таблицу перекрестных ссылок в оперативной памяти AcDbDatabase так, чтобы это
могло быть сохранено назад к файлу. В течение решения таблицы перекрестных ссылок, много
отчетов{*записей*} таблицы идентификаторов искарежены, и некоторые стерты. Исторически, это было
сделано, чтобы упростить процесс решения, и было приемлемо, потому что базы данных были только для
чтения. Эта обработка делает возможным временно полностью изменить изменения{*замены*} решения так,
чтобы база данных таблицы перекрестных ссылок могла изменяться и написан назад к ее файлу.
Функции, которые помогают в пред- и последующая обработка, добавлены к AcDbDatabase. Они включают
сервисную функцию, чтобы найти связанный блочный отчет{*запись*} таблицы от базы данных таблицы
перекрестных ссылок, также как способности восстановить решенную таблицу перекрестных ссылок, и
сбрасывать это назад к надлежащему решенному условию{*состоянию*} после восстановления.
Общепринятое использование для этих функций было бы должно делать восстановление к первоначальным
символам, делать модификации к базе данных, сохранять{*экономить*} базу данных, и затем восстанавливать
отправленные{*ускоренные*} символы. Эти шаги должны быть написаны в одиночный блок кода,
предотвращать попытки восстановить рисунок главного компьютера, выполнять любые команды таблицы
перекрестных ссылок, или обеспечивать подсказки пользователя, в то время как база данных таблицы
перекрестных ссылок находится в ее восстановленном условии{*состоянии*}.
Функции
 AcDbDatabase:: xrefBlockId ()
 AcDbDatabase::restoreOriginalXrefSymbols()
 AcDbDatabase::restoreForwardingXrefSymbols()

AcDbDatabase:: xrefBlockId () Функция


XrefBlockId () функция получит AcDbObjectId блочного отчета{*записи*} таблицы, который
обращается{*относится*} к этой базе данных как таблица перекрестных ссылок. Когда таблица
перекрестных ссылок перезагружена по любой причине (например, Перезагрузке ТАБЛИЦЫ
ПЕРЕКРЕСТНЫХ ССЫЛОК или командам Пути ТАБЛИЦЫ ПЕРЕКРЕСТНЫХ ССЫЛОК), прежняя
база данных сохраняется в памяти для Отмены. Это означает, что больше чем одна база данных
могут указывать на тот же самый отчет{*запись*} таблицы блока таблицы перекрестных ссылок.
Однако только каждый будет в настоящее время активная база данных таблицы перекрестных
ссылок для того отчета{*записи*}. Указатель базы данных, возвращенный AcDbBlockTableRecord::
xrefDatabase () функция на найденном отчете{*записи*} будет активная база данных для той
таблицы перекрестных ссылок.

AcDbDatabase:: restoreOriginalXrefSymbols () Функция


RestoreOriginalXrefSymbols () функция восстанавливает решенную базу данных таблицы
перекрестных ссылок к ее первоначальной форме, поскольку это было бы если только что

47
загружено от ее файла. Таблица перекрестных ссылок - тогда в условии{*состоянии*}, где это
может изменяться и сохранен назад к файлу. После запроса этой функции, рисунок главного
компьютера - больше не в правильном{*допустимом*} государстве{*состоянии*} для
перегенерального или для любых модификаций команды таблицы перекрестных ссылок или
перезагрузок. Модификации базы данных, сохраните{*экономьте*} назад, и
restoreForwardingXrefSymbols () функция должна назваться прежде, чем что - нибудь, что могло бы
позволять перегенеральный.

AcDbDatabase::restoreForwardingXrefSymbols () Функция
RestoreForwardingXrefSymbols () функция восстанавливает таблицу перекрестных ссылок назад к
правильному{*допустимому*}, приложенное государство{*состояние*}. Мало того, что это
восстанавливает оригинал решенные символы, но и это также разыскивает недавно добавленные
символы и решает их также. RestoreForwardingXrefSymbols () функция не может обрабатывать
недавно добавленный, вложенные отчеты{*записи*} таблицы блока таблицы перекрестных ссылок,
если они уже не существуют и решены в ведущем рисунке.

Закрытие файла и Проверки Последовательности


Базовый класс AcDbXrefFileLock обеспечивается, чтобы обработать управление закрытия файла
таблицы перекрестных ссылок. Его основная цель состоит в том, чтобы готовить блок таблицы
перекрестных ссылок в рисунке для правки по месту, тем не менее, это может использоваться для
других целей. Принимается, что эти методы файла таблицы перекрестных ссылок работают на
текущем рисунке базы данных. AcdbXrefReload () функция глобальной переменной обрабатывает
список объекта IDs отчета{*записи*} таблицы блока таблицы перекрестных ссылок для
перезагрузки таблицы перекрестных ссылок. Принимается, что каждая таблица перекрестных
ссылок блокирует ссылки{*справочники*} объекта ID отчета{*записи*} таблицы чертежный файл
таблицы перекрестных ссылок, который может быть перезагружен к текущему рисунку. Это имеет
те же самые функциональные возможности как команда подсистемы ТАБЛИЦЫ ПЕРЕКРЕСТНЫХ
ССЫЛОК AutoCAD
Для Перезагрузки.

Индексы и Фильтры
Индекс и классы фильтра и функции обеспечивают схему приложений, чтобы определить заказные индексы и
заказную фильтрацию блочных данных. Приложение может определять его создания заказных ИС 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.

Рисунок Итоговой Информации


Диалог Свойства Рисунка позволяет пользователям AutoCAD внедрять вспомогательные данные
(называемый итоговой информацией) в их DWG файлах, и помогает в восстановлении{*поиске*} DWG
файлам, основанным на этих данных. Это обеспечивает пользователей AutoCAD поиском файла основного
уровня и возможностями управления.
Через Проводник Windows, свойства рисунка могут рассматриваться вне AutoCAD. Использованный вместе с
AutoCAD DesignCenter Расширенный Находят особенность, итоговая информация позволяет пользователям
искать рисунки, содержащие предопределенные или заказные данные.
AcDbDatabaseSummaryInfo, AcDbSummaryInfoReactor, и классы AcDbSummaryInfoManager
обеспечивают API, чтобы работать с итоговой информацией и обсуждены ниже. Для большего
количества подробности относительно этих классов, см. ObjectARX Ссылку{*справочники*}.

AcDbDatabaseSummaryInfo Класс
AcDbDatabaseSummaryInfo класс формирует набор символьных строк, которые могут
использоваться, чтобы прибавить дополнительную информацию к DWG файлу. Максимальная
длина этих строк - 511 символов. Эта информация сохранена и восстановлена{*отыскана*} в
объекте Summary Information с определенными методами для каждого информационного поля.
Предопределенные поля
 N Заголовок
 N Тема
 N Автор
 N Ключевые слова

49
 N Комментарии
 N Последний{*прошлый*} сохраненный
 N номер Пересмотра
 N ядро Гиперсвязи
Вы можете создавать ваши собственные заказные поля в дополнение к предопределенным полям.
Эти заказные поля сохранены в списке, и Вы можете управлять заказными полями или их
названием{*именем*} (или клавиша{*ключ*}) или позиция (индекс) в списке. Заказные поля индексированы,
начинаясь в 1, и не имеется никакого предела числу полей, которые Вы можете создавать.

AcDbSummaryInfoReactor Класс
Этот класс обеспечивает реактор, чтобы сообщить, изменена{*заменена ли*} итоговая информация.

AcDbSummaryInfoManager Класс
AcDbSummaryInfoManager класс организовывает итоговые информационные реакторы, с методами
прибавлять и удалить реакторы, и посылать уведомление, что итоговая информация изменилась.

Глобальные Итоговые Информационные Функции


ObjectARX содержит несколько глобальных функций для доступа к итоговой информации:
Acad:: ErrorStatus
AcdbGetSummaryInfo (
AcDbDatabase* pDb,
AcDbDatabaseSummaryInfo*& PInfo);

Acad:: ErrorStatus
AcdbPutSummaryInfo (
Константа AcDbDatabaseSummaryInfo* pInfo);
AcDbSummaryInfoManager*
AcdbGetSummaryInfoManager ();

Для получения дополнительной информации на этих функциях, см. ObjectARX Ссылку{*справочники*}.

Сохраненный Программным обеспечением Autodesk


Следующий AcDbDatabase метод возвращает Adesk:: kTrue, если это решает, что база данных
была последняя сохранена программным обеспечением Autodesk (типа AutoCAD или AutoCAD
LT®):
Adesk::Boolean
dwgFileWasSavedByAutodeskSoftware();

Глава 5. Объекты Базы данных


Эта глава описывает темы, которые касаются всех объектов базы данных AutoCAD, включая объекты, записи
таблицы идентификаторов и словари. Главные включенные концепции открывают и закрывают объекты,
управляя объектами в памяти, монопольном использовании объекта, и расширяя объект, используя xdata или
словарь расширения объекта. Другие общие операции на объектах, типа записи в файл и стирания, также
обсуждены.
 Открытие и Закрытие Объектов Базы данных
 Удаляющие Объекты
 Монопольное использование Базы данных Объектов
 Добавление Объектно - определенных Данных
 Стирающие Объекты
 Объектная Запись в файл

Открытие и Закрытие Объектов Базы данных


Каждый объект AcDbObject может быть упомянут тремя различными способами:
 его маркером{*дескриптором*}
 его объектом ID
 указателем образца C++
Когда AutoCAD не выполняется, рисунок сохранен в файловой системе.
Объекты, содержащиеся в DWG файле идентифицированы их маркерами{*дескрипторами*}.
После того, как рисунок открыт, информация рисунка доступна через объект AcDbDatabase.
Каждый объект в базе данных имеет объект ID, который сохраняется в течение текущего сеанса

50
редактирования, от создания до стирания AcDbDatabase, в котором объект постоянно находится.
Открытые функции берут объект ID как параметр и возвращают указатель на объект AcDbObject.
Этот указатель правилен, пока объект не закрыт, как показано в следующем рисунке.

Вы можете открывать объект, используя acdbOpenObject ():

Acad::ErrorStatus
AcDbDatabase::acdbOpenObject(AcDbObject*& obj,
AcDbObjectId id,
AcDb::OpenMode mode,
Adesk::Boolean
openErasedObject =
Adesk::kFalse);

Вы можете отображать маркер(дескриптор) к объекту ID, используя эту функцию:

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 эквивалентен AcDbObjectId. AcDb библиотека обеспечивает две автономных функции,


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

// Returns an ads_name for a given object ID.


//
acdbGetAdsName(ads_name& objName,
AcDbObjectId objId);
// Returns an object ID for a given ads_name.
//
acdbGetObjectId(AcDbObjectId& objId,
ads_name objName);

Вообще, Вы получаете объект через выбор, и это возвращено в форме 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;
}

Вы можете открывать объект в одном из трех режимов:


 kForRead. Объект может быть открыт для читаемого до 256 устройств считывания, пока
объект не уже открытый для записи, или для уведомляют.
 kForWrite. Объект может быть открыт для записи, если это не уже открыто. Иначе,
открытые сбои.
 kForNotify. Объект может быть открыт для уведомления, когда объект закрыт, открытым для
чтения, или открытый для записи, но не, когда это уже открыто для, уведомляют. См. главу
15, “Уведомление”. Приложения будут редко должны открыться, объект для уведомляет и
посылает этому уведомление.

Следующая таблица показывает возвращенным кодам ошибки, когда Вы пытаетесь открывать объект в
различных режимах, и объект уже открытый.

Открытие объектов в различных режимах


Object already opened for: kForRead kForWrite kForNotify
openedForRead eAtMaxReaders eWasOpenForRead (Succeeds)
(if readCount = 256;
otherwise succeeds)
openedForWrite eWasOpenForWrite eWasOpenForWrite (Succeeds)
openedForNotify eWasOpenForNotify eWasOpenForNotify eWasOpenForNotify
wasNotifying (Succeeds) eWasNotifying eWasNotifying
Undo eWasOpenForUndo eWasOpenForUndo (Succeeds)

Если Вы пробуете открывать объект для записи, и Вы получаете ошибку eWasOpenForRead, Вы


можете использовать upgradeOpen () чтобы модернизировать открытого состояния, чтобы
записать, если имеется только одно устройство считывания объекта. Тогда Вы использовали бы
downgradeOpen () чтобы понизить его состояние, чтобы читать. Точно так же, если ваш объект
открытый для, уведомляют — например, когда Вы получаете уведомление —, и Вы хотите открыть
это для записи, Вы можете использовать upgradeFromNotify () чтобы модернизировать его
открытого состояния, чтобы записать. Тогда Вы использовали бы downgradeToNotify () чтобы
понизить его состояние, чтобы уведомить.
Для получения дополнительной информации относительно того, как управлять комплексными
последовательностями открытия и закрытия объектов, см. “ Менеджер Транзакции ” на странице 451.

Удаление объекта
Когда Вы создаете образец объекта AcDbObject с намерением добавления в конец этого к базе
данных, используете AcDbObject:: новый () функция. Когда объект сначала создан и еще не был
добавлен к базе данных, Вы можете удалять это. Однако, как только объект был добавлен к базе
данных, Вы не можете удалять это; AutoCAD управляет стиранием всех объектов резидента базы.

Монопольное использование Базы данных Объектов


Объект, который неявно принадлежит базе данных скорее чем другой объект базы данных, называется
корневым объектом. База данных содержит десять корневых объектов: эти девять таблиц идентификаторов и
названный объектный словарь. Все файловые операции начинаются, регистрируя из корневых объектов базы
данных. См. “ Запись в файл Объекта ” на странице 95.
За исключением корневых объектов, каждый объект в базе данных должен иметь владельца, и
данный объект может иметь только одного владельца. База данных - дерево, созданное этой
иерархией находящихся в собственности объектов. Следующий запрос прибавляет объект к базе
данных и назначает ИДЕНТИФИКАТОР на это, но объект еще не имеет владельца: db- >
addAcDbObject (...); Обычно, Вы прибавите объект к его владельцу, использующему функцию
элемента, которая одновременно прибавляет это к базе данных, типа AcDbBlockTableRecord::
appendAcDbEntity () функция, которая исполняет обеих задачи сразу.

Подключения{*связи*} монопольного использования AutoCAD следующие:


 блочная таблица делает запись собственных объектов.

52
 Каждая таблица идентификаторов имеет специфический тип отчета{*записи*} таблицы
идентификаторов.
 объект AcDbDictionary может иметь любой объект AcDbObject.
 объект Any AcDbObject может иметь словарь расширения{*продления*}; объект имеет его
словарь расширения{*продления*}.

Кроме того, приложения могут устанавливать их собственные подключения{*связи*} монопольного


использования.

Добавление Объектно - определенных Данных


Вы можете использовать любой из четырех механизмов для добавления образец-определенных данных в
вашем приложении:
 Расширенные{*продленные*} данные (xdata)
 Xrecords (см. главу 7, “ Контейнерные Объекты ”)
 словари Расширений{*продления*} любого объекта
 Объекты пользователя, которые могут держаться, данные (видят главу 12, “ Происходящий
от 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;

Используйте AcDbObject:: setXData () функция, чтобы определить xdata для объекта:


virtual Acad::ErrorStatus
AcDbObject::setXData(const resbuf* xdata);

Следующий пример использует 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 в каталоге выборок.

Следующий пример показывает instantiating xrecord и добавление этого к словарю


расширения{*продления*} в названном объектном словаре:

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);
}

Глобальный Функциональный Пример


Следующий пример использует глобальные функции ObjectARX, чтобы создать xrecord и
прибавлять это к словарю, связанному с клавишей ASDK_REC{*ключом*}.

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).

По умолчанию, Вы не можете открывать стертый объект с acdbOpenObject () функция. Если Вы


пытаетесь делать так, eWasErased код ошибки будет возвращен.

extern Acad::ErrorStatus
acdbOpenObject(AcDbObject*& obj,
AcDbObjectId objId,
AcDb::OpenMode openMode,

57
Adesk::Boolean openErasedObject =
Adesk::kFalse);

Чтобы открывать стертый объект, используйте kTrue для последнего{*прошлого*} параметра


acdbOpenObject () функция.
Контейнерные объекты типа ломаных линий и блочных отчетов{*записей*} таблицы обычно обеспечивают
опцию пропуска стертых элементов при выполнении итераций по их содержанию.
Заданное по умолчанию поведение должно пропустить стертые элементы.

Стертые объекты не зарегистрированы из к DWG или DXF файлам.

Запись Объекта в файл


Запись в файл Объекта обращается{*относится*} к конверсионному процессу между
государством{*состоянием*} объекта и одиночной последовательностью данных, для целей типа сохранения
этого на диске, копирование этого, или регистрации его государства{*состояния*} для операции отмены.
Запись в файл из иногда называется, преобразовывая в последовательную форму.
Запись в файл объекта в - процесс превращения последовательности данных назад в объект, иногда
называемый deserializing.
Запись в файл используется в нескольких контекстах в AutoCAD:
 Запись и чтение DWG файлы (использует формат DWG)
 Запись и чтение DXF файлы (использует формат DXF)
 Сообщающий среди AutoCAD, AutoLISP, и ObjectARX (использует формат DXF)
 регистрация Отмены и восстановление (использует формат DWG)
 операции Copying типа ВСТАВКИ, ТАБЛИЦЫ ПЕРЕКРЕСТНЫХ ССЫЛОК, и КОПИИ
(использует формат DWG)
 Листание (использует формат DWG)
AcDbObject имеет две функции элемента для записи в файл из: dwgOut () и dxfOut (), и две
функции элемента для записи в файл в: dwgIn () и dxfIn ().
Эти функции элемента прежде всего называются в соответствии с AutoCAD; запись в файл объекта почти
никогда явно не управляется приложениями, которые используют базу данных.
Однако, если ваше приложение осуществляет новые классы объекта базы данных, вы будете нуждаться в
более глубоком понимании объектной записи в файл. См. главу 12, “ Происходящий от AcDbObject. ”
Dwg- и dxf- префиксы указывают два существенно различных формата данных, первый типично
используемый в письменной форме к и от DWG файлов, и второй прежде всего для DXF файлов и
AutoLISP entget, entmake, и функций entmod. Первичное различие между двумя форматами - то,
что для DWG регистраторов (объект, который записывает, данные к файлу), данные явно не
отмечены.
DXF регистраторы, напротив, присоединяют код группы данных с каждым элементом данных в изданном
формате данных (см. главу 12, “ Происходящий от AcDbObject ”).

Глава 6. Примитивы
Эта глава описывает примитивы — объекты базы данных с графическим представлением. Это перечисляет
свойства и операции, все примитивы имеют в общем{*обычном*}. Примеры показывают, как создать блоки,
вставки, и комплексные примитивы, и как выбирать и высветить подпримитивы.
 Определенные Примитивы
 Монопольное использование Примитива
 Выпуск AutoCAD 12 Примитивов
 Общие{*обычные*} Свойства Примитива
 Общие{*обычные*} Функции Примитива
 Создание Образцов Примитивов AutoCAD
 Комплексные Примитивы
 Доступ Системы координат
 Функции Кривой
 Связывающиеся Гиперсвязи с Примитивами

Определенные Примитивы
Примитив в базе данных имеет графическое представление. Примеры примитивов включают
строки, круги, дуги, текст, solids, области{*регионы*}, сплайны, и эллипсы. AcDbEntity класс получен
из AcDbObject.

58
С несколькими исключениями, примитивы содержат всю необходимую информацию относительно их
геометрии. Несколько примитивов содержат другие объекты, которые проводят{*держат*} их геометрическую
информацию или атрибуты. Сложные примитивы включают следующее:
 AcDb2dPolyline, который имеет объекты AcDb2dPolylineVertex
 AcDb3dPolyline, который имеет объекты AcDb3dPolylineVertex
 AcDbPolygonMesh, который имеет объекты AcDbPolygonMeshVertex
 AcDbPolyFaceMesh, который имеет объекты AcDbPolyFaceMeshVertex и объекты
AcDbFaceRecord
 AcDbBlockReference, который имеет объекты AcDbAttribute
 AcDbMInsertBlock, который имеет объекты AcDbAttribute
Примеры создания и выполнения итераций через сложные примитивы обеспечиваются в “ Сложные
Примитивы ” на странице 134.

Монопольное использование Примитива


Примитивы в базе данных обычно принадлежат AcDbBlockTableRecord. Блочная таблица в недавно
созданной базе данных имеет три предопределенных отчета{*записи*}, *MODEL_SPACE,
*PAPER_SPACE, и *PAPER_SPACE0, которые представляют образцовое пространство{*пробел*} и
два предопределенных бумажных пространственных размещения. Дополнительные записи
добавлены всякий раз, когда пользователь создает новые блоки (блочные записи), типично,
издавая БЛОК, ШТРИХОВКУ, или команду DIMENSION.

Структура монопольного использования для примитивов базы данных следующие:

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

Общие Свойства Примитива


Все примитивы имеют множество общих{*обычных*} свойств и включают функции члена для установки и
получения их значений. Эти свойства, которые могут также быть установлены в соответствии с директивами
пользователя, являются следующим:
 Цвет
 Linetype
 Linetype масштаб
 Видимость
 Уровень
 вес Строки

60
 Графическое название{*имя*} стиля
Когда Вы добавляете примитив к блочному отчету{*записи*} таблицы, AutoCAD автоматически
вызывает AcDbEntity:: setDatabaseDefaults () функция, которая устанавливает свойства в их
значения по умолчанию, если Вы явно не установили их.
AcDbViewport приобретает параметры настройки текущего графического окна.
Если свойство было явно не определено для примитива, текущее значение базы данных для того свойства
используется. См. главу 4, “ Операции Базы данных, ” для описания функций члена, используемых для
установки и получения текущих значений свойства, связанных с базой данных.

Цвет примитива
Цвет Примитива может быть установлен и читать как числовые индексные значения в пределах от
от 0 до 256, или образцами AcCmColor, который обеспечивается для будущего использования
расширенной цветовой моделью. В настоящее время, цвет использований AutoCAD индексирует
только. Правильный цветной индекс может быть получен от образца AcCmColor использование
AcCmColor:: getColorIndex () функция члена.
Цвет индексирует 1 до 7, используются для стандартных цветов, как показано в следующей таблице:

Color Number Color Name


1 Red
2 Yellow
3 Green
4 Cyan
5 Blue
6 Magenta
7 White or Black

Цвета 8 до 255 определены устройством отображения.

Следующие индексные значения имеют специальные значения:

0 Определяет BYBLOCK. Примитивы наследуют цвет текущей блочной ссылки{*справочников*}, которая


указывает на блочный отчет{*запись*} таблицы, что примитив постоянно находится в, или черный / белый,
если примитив постоянно находится непосредственно в образцовом пространственном или бумажном
пространственном блочном отчете{*записи*} таблицы.

256 Определяет BYLAYER. Примитивы принимают цвет связанного уровня примитива.

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 в
целевой базе данных примитива.

Специальные linetype входы следующие:


CONTINUOUS - Значение по умолчанию linetype, который автоматически создан в linetype таблице
идентификаторов
BYLAYER Linetype значение уровня примитива
BYBLOCK Linetype значение примитива окружающий блочный поток определения блокирует
ссылку{*справочники*}
Если значение linetype определено для примитива, текущее значение по умолчанию базы данных linetype
значение игнорируется.

61
Следующие функции дают возможность Вам установить linetype для примитива, или по имени или объектом
ID:

virtual Acad::ErrorStatus
AcDbEntity::setLinetype(const char* newVal);

virtual Acad::ErrorStatus
AcDbEntity::setLinetype(AcDbObjectId newVal);

Эта функция возвращает название{*имя*} текущего примитива linetype:

char* AcDbEntity::linetype() const;

Эта функция возвращает объект ID для отчета{*записи*} таблицы идентификаторов определение linetype:

AcDbObjectId AcDbEntity::linetypeId() const;

Примитив Linetype Масштаб


Когда примитив - первый instantiated, его масштаб linetype инициализирован к недопустимому
значению. Когда примитив добавлен к базе данных, если масштаб linetype не был определен для
примитива, это установлено в поток базы данных linetype значение масштаба. Это значение по
умолчанию базы данных сохранено в CELTSCALE системной переменной.
Linetype Масштаб, указанный В Примитив
Если значение масштаба linetype определено для примитива, текущее значение по умолчанию базы данных
linetype значение масштаба игнорируется.
Следующие функции позволяют Вам устанавливать и запрашивать масштаб linetype относительно
примитива:

Acad::ErrorStatus
AcDbEntity::setLinetypeScale(double newVal);

double
AcDbEntity::linetypeScale() const;

Регенерация Рисунка
Когда примитив восстановлен, его эффективный масштаб linetype - изделие{*программа*} и, примитива
linetype масштаб и глобальная база данных linetype масштаб. Для небумажных пространственных
примитивов, масштаб linetype рассчитан следующим образом:

effltscale = ent->linetypeScale() * ent->database()->ltscale();

Если PSLTSCALE - 1, эффективный масштаб linetype тогда применяется к появлению{*виду*}


образцового пространственного примитива когда рассматривается в бумажном
пространстве{*пробеле*}. Если PSLTSCALE - 0, то все масштабирование linetype выполнено
относительно образцовых пространственных представлений{*видов*}. См. Руководство
программиста AutoCAD для дальнейшего объяснения масштабов 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);

Эта функция возвращает название{*имя*} текущего уровня примитива:

char* AcDbEntity::layer() const;

Эта функция возвращает объект ID для текущего уровня (объект типа AcDbLayerTableRecord):

AcDbObjectId AcDbEntity::layerId() const;

Общие функции Примитива


Примитивы также имеют множество общих{*обычных*} функций, прежде всего предназначенных для
использования в соответствии с AutoCAD. Этот раздел обеспечивает общий фон{*подготовку*} при
использовании некоторых из этих функций. Для примеров осуществления функций для новых классов, см.
главу 13, “ Происходящий от AcDbEntity. ”
Общие{*обычные*} функции примитива включают следующее:
 intersectWith () используется в вырезке, простираться, филе, chamfer, перерыве, и
возражать поспешные операции Intersection
 transformBy () используется, чтобы пройти в преобразованной матрице, которая
перемещает, масштабирует, или вращает пункты{*точки*} в объекте
 getTransformedCopy () создает копию объекта и применяет преобразование к этому
 getOsnapPoints () возвращает поспешные пункты{*точки*} и вид поспешных пунктов{*точек*}
 getGripPoints () возвращает пункты{*точки*} власти{*захвата*}, которые являются
надмножеством пунктов{*точек*} протяжения
 getStretchPoints () значения по умолчанию к getGripPoints () и обычно имеют то же самое
выполнение
 moveStretchPointsAt () используется командой STRETCH AutoCAD, чтобы переместить
указанные пункты точки и значения по умолчанию к transformBy ()
 moveGripPointsAt () используется редактированием власти{*захвата*} AutoCAD, чтобы
переместить указанные точки и значения по умолчанию к transformBy ()
 worldDraw () создает представление-независимое геометрическое представление
примитива
 viewportDraw () создает представление геометрического объекта иждивенца представления
примитива
 draw () стоит в очереди примитив и сбрасывает на диск графическую очередь так, чтобы
примитив и что - нибудь еще в очереди были оттянуты
 list() используется командой LIST AutoCAD и производит acutPrintf () инструкции
 getGeomExtents () возвращает пункты{*точки*} угла поля, которое включает трехмерные
степени вашего примитива
 explode() расчленяет примитив в набор более простых элементов
 getSubentPathsAtGsMarker () возвращает пути подпримитива, которые передают данному
GS маркер (см. “ GS Маркеры и Подпримитивы ” на странице 109)
 getGsMarkersAtSubentPath () возвращает GS маркер, который соответствует данному пути
подпримитива
 subentPtr () возвращает указатель, соответствующий данному пути подпримитива
 highlight () высвечивает указанный подпримитив (см. “ GS Маркеры и Под-примитивы ” на
странице 109)

Объектные точки привязки


Объекты могут определить некоторые характерные пункты{*точки*} для них, типа среднего
пункта{*точки*}, midpoint, или оконечной точки. Когда AutoCAD приобретает пункты{*точки*} и
находится в режиме Object Snap, это вызывает getOsnapPoints () функция, чтобы приобрести

63
уместные поспешные пункты{*точки*} для указанного режима Object Snap. Следующая таблица
перечисляет возможные режимы Object Snap.

Объектные режимы Snap


Mode Description
kOsModeEnd Endpoint
kOsModeMid Midpoint
kOsModeCen Center
kOsModeNod Node
e
kOsModeQua Quadrant
d
kOsModeIns Insertion
kOsModePer Perpendicular
p
kOsModeTan Tangent
kOsModeNea Nearest
r

Сигнатура для AcDbEntity:: getOsnapPoints ()

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;

TransformBy () функция изменяет примитив, используя указанную матрицу.


В AutoCAD, это называется перемещением власти{*захвата*}, вращать, масштабировать, и отражать режимы.
В некоторых случаях{*делах*}, однако, применяя преобразование требует, чтобы новый примитив был создан.
В таких случаях{*делах*}, getTransformedCopy () функция используется так, чтобы заканчивающийся примитив
мог быть образец различного класса чем первоначальный примитив.
Когда Вы взрываете блочную ссылку{*справочники*}, которая неоднородно масштабировалась,
getTransformedCopy () функция - обратился к примитивам в блочной ссылке{*справочниках*}, чтобы создать
новые примитивы (см. “ Взрывающиеся Примитивы ” на странице 123).

Пересечение точек
IntersectWith () функция возвращает пункты{*точки*}, где примитив пересекает другой примитив в рисунке.
Входные значения для этой функции - примитив и перекрестный тип, который может быть один из
следующего:
 kOnBothOperands (никакой примитив расширен{*продлен*})
 kExtendThis
 kExtendArg
 kExtendBoth
Например, предположите, что рисунок содержит три строки, показанные в следующей иллюстрации. Line1 -
"это" и line3 - примитив параметра. Если перекрестный тип - kExtendThis, пункт{*точка*} возвращен как
пункт{*точка*}, где line1 ("это") пересек бы line3, если line1 были расширены{*продлены*}. Если перекрестный
тип - kExtendArgument, и line2 - примитив параметра, никакие данные не возвращены, потому что, даже если
это было расширено{*продлено*}, line2 не будет пересекать line1. Если перекрестный тип - kExtendBoth, и
line2 - примитив параметра, пункт{*точка*} B возвращен. Если перекрестный тип - kExtendNone, и line2 -
примитив параметра, никакие данные не возвращены.

IntersectWith () функция - перезагруженная функция с двумя формами.

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;

Возвращенные пункты{*точки*} - всегда на примитиве ("this"). Поэтому, в случаях{*делах*} очевидного


пересечения, пересеченные пункты{*точки*} проектируются назад к примитиву прежде, чем они возвращены.
Обе версии intersectWith () функция позволяют Вам снабжать необязательные GS маркеры, чтобы
оптимизировать выполнение{*работу*} для этой функции. Если intersectWith примитива () функция
осуществила использование GS маркеров, то поставляющий{*снабжающий*} GS маркеры может ограничивать
перекрестную область и ускорять испытание.
Например, в следующем рисунке, если пользователь выбирает, одна строка многоугольника, проходящего в
GS маркере для той строки устраняет потребность проверить другие пять строк многоугольника.

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);

Преобразование GS Маркеры к Путям Подпримитива


Используйте getSubentPathsAtGsMarker () функция, чтобы получить подпримитив для GS маркера,
возвращенного acedSSNameX () функция. Законченный синтаксис для этой функции

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:: подсветкой () чтобы исполнить высвечивание{*увеличение яркости*}.

// Эта функция вызывает{*называет*} getObjectAndGsMarker ()


// чтобы получить объект ID твердых и его gsmarker. Это тогда вызывает
// highlightEdge (), highlightFaces (), и highlightAll () чтобы высветить выбранный
// край, все лица, окружающие тот край, и затем твердое целое.
//
void
highlightTest()
{
AcDbObjectId objId;
int marker;
if (getObjectAndGsMarker(objId, marker) != Acad::eOk)
return;
highlightEdge(objId, marker);
highlightFaces(objId, marker);
highlightAll(objId);
}

// This function uses acedSSGet() to let the user select a


// single entity. It then passes this selection set to
// acedSSNameX() to get the gsmarker. Finally, the entity name
// in the selection set is used to obtain the object ID of
// the selected entity.
//
Acad::ErrorStatus
getObjectAndGsMarker(AcDbObjectId& objId, int& marker)
{
ads_name sset;
if (acedSSGet("_:S", NULL, NULL, NULL, sset) != RTNORM) {
acutPrintf("\nacedSSGet has failed");
return Acad::eInvalidAdsName;
}
// Get the entity from the selection set and its
// subentity ID. This code assumes that the user
// selected only one item, a solid.
//
struct resbuf *pRb;
if (acedSSNameX(&pRb, sset, 0) != RTNORM) {
acedSSFree(sset);
return Acad::eAmbiguousOutput;
}
acedSSFree(sset);
// Walk the list to the third item, which is the selected
// entity’s entity name.
//
struct resbuf *pTemp;
int i;
for (i=1, pTemp = pRb;i<3;i++, pTemp = pTemp->rbnext)
{;}
ads_name ename;
ads_name_set(pTemp->resval.rlname, ename);
// Move on to the fourth list element, which is the gsmarker.
//
pTemp = pTemp->rbnext;
marker = pTemp->resval.rint;
acutRelRb(pRb);
acdbGetObjectId(objId, ename);
return Acad::eOk;
}

// This function accepts an object ID and a gsmarker.


// The object is opened, the gsmarker is used to get the

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();
}

// This function accepts an object ID and a gsmarker.


// The object is opened, the gsmarker is used to get the
// AcDbFullSubentIdPath, which is then used to highlight
// and unhighlight faces that share the edge used to
// select the object. The object is then closed.
//
void
highlightFaces(const AcDbObjectId& objId, const int marker)
{
char dummy[133];
AcDbEntity *pEnt;
acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead);
// Get the subentIds for the faces.
//
AcGePoint3d pickpnt;
AcGeMatrix3d xform;
int numIds;
AcDbFullSubentPath *subentIds;
pEnt->getSubentPathsAtGsMarker(AcDb::kFaceSubentType,
marker, pickpnt, xform, numIds, subentIds);
// Walk the subentIds list, highlighting each face subentity.
//
for (int i = 0;i < numIds; i++) {
pEnt->highlight(subentIds[i]); // Highlight face.
// Pause to let the user see the effect.
//
acedGetString(0, "\npress <RETURN> to continue...",
dummy);

68
pEnt->unhighlight(subentIds[i]);
}
delete []subentIds;
pEnt->close();
}

// This function accepts an object ID. The object is opened,


// and its highlight() and unhighlight() functions are
// used with no parameters, to highlight and
// unhighlight the edge used to select the object. The
// object is then closed.
//
void
highlightAll(const AcDbObjectId& objId)
{
char dummy[133];
AcDbEntity *pEnt;
acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead);
// Highlight the whole solid.
//
pEnt->highlight();
// Pause to let user see the effect.
//
acedGetString(0, "\npress <RETURN> to continue...",
dummy);
pEnt->unhighlight();
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;
}

Высвечивание Вложенных Блочных Ссылок


Пример, который следует за показами, высвечивающими вложенные блочные ссылки{*справочники*}. Как
показано в следующем числе{*рисунке*}, пример создает шесть примитивов: три polys (заказной примитив) и
три поля. Это также создает три блочных ссылки{*справочников*} (вставки).
Вставьте 3 (ins3) - вставка блока, который содержит poly3 и box3. Вставьте 2 (ins2) - вставка блока,
который содержит poly2, box2, и ins3. Вставьте 1 (ins1) - вставка блока, который содержит poly1,
box1, и ins2.

После того, как вставки созданы, пример высвечивает различные компоненты.

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 ()):
 Визуальное появление{*вид*} постоянный.
 взрываемый примитив стерт от базы данных.
 Одни или более новые примитивы созданы и добавлены в конец к базе данных.

Создание Образцов Примитивов AutoCAD


Этот раздел демонстрирует, как создать простые и сложные примитивы и добавлять их к базе данных. Это
также иллюстрирует создание простого примитива, простого блока, блок с атрибутами, и блочной вставкой
(блочная ссылка{*справочники*}).

Создание Простого Примитива


Следующий пример демонстрирует создание строки и добавления в конец этого к образцовому
пространственному блочному отчету{*записи*} таблицы, как описано в главе 2, “ Учебник для начинающих
Базы данных. ”

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();
}

Создание записи таблицы блоков с определениями атрибута


Блок AutoCAD - коллекция примитивов, который сохранен в записи таблицы блоков. Каждый блок имеет
объект AcDbBlockBegin, сопровождаемый одним или большее количество объектов AcDbEntity, и
заканчивается объектом AcDbBlockEnd (см. иллюстрацию на странице 100).
Блок может содержать определения атрибута, которые являются шаблонами для создания атрибутов. Атрибут
- информационный текст, связанный с блоком. В зависимости от обеспеченной пользователем установки,
атрибуты со значением могут или не может быть скопирован, когда блок вставлен в рисунок. Часто,
приложение запрашивает пользователя относительно атрибута со значением во время выполнения.

Создавать запись таблицы блоков


1 Создают новую запись таблицы блоков.
2 Добавляют запись таблицы блоков на таблицу блоков.
3 Создают примитивы и добавляют их к записи таблицы блоков.
4 Создают определения атрибута, устанавливают их значения, и добавляют их к записи таблицы блоков.

Когда Вы закрываете запись таблицы блоков, блок начинает и блокирует конечные объекты, добавлены к
блоку автоматически.

Следующий пример создает новую запись таблицы блоков по имени 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;
}

Создание блок-ссылки с Атрибутами


Блок-ссылка - примитив это ссылки запись таблицы блоков. Это содержит точку вставки, ECS информация, X,
Y, Z коэффициенты масштаба, вращение, и вектор нормали (параметры для рассмотрения блока в его новом
местоположении). Когда Вы вставляете блок в рисунок, AutoCAD сохраняет память, создавая блок-ссылку
скорее чем копирование блока непосредственно в рисунок.
Если Вы вставляете блок с определениями атрибута, атрибуты со значением могут быть заполнены
пользователем во время выполнения или приложением, когда блок вставлен.

Вставлять блок с атрибутами в рисунок


1 Создают примитив блок-ссылки (AcDbBlockReference).
2 Называют setBlockTableRecord () функцией, чтобы определить объект ID упомянутой записи таблицы блоков.
(Объект ID может также быть определен непосредственно в конструкторе блок-ссылки.)
3 Добавляют в конец блок-ссылку к записи таблицы блоков (пространство модели, пространство листа, или
некоторый другой блок).
4 Используют запись таблицы блоков iterator на упомянутой записи таблицы блоков, ища определения
атрибута. Для каждого найденного, создайте новый AcDbAttribute примитив, заполните это с данными
определения атрибута, и затем добавьте в конец это к блок-ссылке, используя appendAttribute () функция.

Следующий пример создает блок-ссылку, заполняет атрибуты, и добавляет ссылку к базе данных. Это
использует глобальные функции, чтобы получить ввод пользователя. 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();
}

Выполнение итераций через Запись таблицы блоков


Следующий пример демонстрирует, как выполнить итерации через элементы в записи таблицы блоков и
распечатывать элементы.
PrintAll () функция открывает таблицу блоков для чтения, и затем это открывает имя блока, снабженное пользователем.
Новый iterator шагает через записи таблицы блоков. Если запись содержит примитив, iterator печатает сообщение
относительно примитива.

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");
}

Сложные примитивы
Этот раздел обеспечивает примеры, показывающие, как создавать и выполнить итерации через сложные
примитивы.

Создание Сложного Примитива


Эти показы примера, как создавать объект AcDb2dPolyline и устан некоторых из его свойств — уровень,
окрашивают индекс, закрытый параметр. Это тогда создает четыре объекта (AcDb2dPolylineVertex вершины,
устанавливает их местоположение, и добавляет их к объекту ломаной линии. Наконец, это закрывает всю
открытую вершину объектов —, ломаную линию, запись таблицы блоков, и таблицу блоков. Когда объект
ломаной линии закрыт, AutoCAD добавляет объект AcDbSequenceEnd к этому автоматически.

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();
}

Выполнение итераций через Вершину в Ломаной линии


Следующее выполнение итераций показов примера через вершину в ломаной линии, использующей вершину
iterator. Это тогда печатает координаты для каждой вершины.

// Принимает объект ID AcDb2dPolyline, открывает это, и получает вершину iterator.


// Это тогда выполняет итерации через вершину, распечатывая местоположение вершины.
void
iterate(AcDbObjectId plineId)
{
AcDb2dPolyline *pPline;
acdbOpenObject(pPline, plineId, AcDb::kForRead);
AcDbObjectIterator *pVertIter= pPline->vertexIterator();
pPline->close(); // Finished with the pline header.
AcDb2dVertex *pVertex;
AcGePoint3d location;
AcDbObjectId vertexObjId;
for (int vertexNumber = 0; !pVertIter->done();
vertexNumber++, pVertIter->step())
{
vertexObjId = pVertIter->objectId();
acdbOpenObject(pVertex, vertexObjId,
AcDb::kForRead);
location = pVertex->position();
pVertex->close();
acutPrintf("\nVertex #%d’s location is"
" : %0.3f, %0.3f, %0.3f", vertexNumber,
location[X], location[Y], location[Z]);
}
delete pVertIter;
}

Доступ к Системе координат


Функции Примитива восстанавливают{*отыскивают*} и устанавливают значение координат, используя
значения Мировой системы координат. Единственное исключение к этому правилу - AcDb2dPolylineVertex
класс, описанный позже в этом разделе, который использует Систему координат Примитива (ECS) значения.
Например, если Вы вызываете getCenter () функция на круге, AutoCAD возвращает X, Y центр круга в мировых
координатах.

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


Если Вы определяете ваш собственный примитив, может быть полезно сохранить его геометрические
конструкции (точки, углы, и векторы) в терминах его собственной относительной системы координат.
Например, дуги устанавливают систему координат, в которой Z ось является перпендикулярной на план дуги.
Средняя точка дуги возвращена в мировых координатах, но начало и конечные углы может только
интерпретироваться относительно его ECS. В таких случаях, осуществьте getEcs () функция, чтобы возвратить
матрицу, которая используется, чтобы преобразовать примитив от его Системы Координаты Примитива до
Мировой системы координат. Если примитив не определен в терминах его собственной Системы координат
Примитива, то getEcs () функция возвращает единичную матрицу. (Другими словами, любое время getEcs
примитива () функция возвращает единичную матрицу, Вы можете предполагать, что примитив определен в
терминах мировых координат.)

В 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)). Конверсионные функции позволяют Вам
конвертировать{*преобразовывать*} данные от его представления параметра до точек в Декартовой системе
координат.
Сплайны, например, являются лучшими представленными в пространстве{*пробеле*} параметра. Чтобы
разбивать сплайн на три равных части, Вы сначала находите параметры, которые соответствуют точкам
сплайна и затем работают на сплайне в пространстве{*пробеле*} параметра.

Кривые могут использоваться как границы вырезки, границы продления, и как объекты конструкции для
создания сложных трехмерных примитивов.
Вы можете проектировать кривую на план в данном направлении, как показано в следующем примере.

// Accepts an ellipse object ID, opens the ellipse, and uses


// its getOrthoProjectedCurve member function to create a
// new ellipse that is the result of a projection onto the
// plane with normal <1,1,1>. The resulting ellipse is
// added to the model space block Table Record.
//
void
projectEllipse(AcDbObjectId ellipseId)
{
AcDbEllipse *pEllipse;
acdbOpenObject(pEllipse, ellipseId, AcDb::kForRead);
// Now project the ellipse onto a plane with a
// normal of <1, 1, 1>.
//
AcDbEllipse *pProjectedCurve;
pEllipse->getOrthoProjectedCurve(AcGePlane(
AcGePoint3d::kOrigin, AcGeVector3d(1, 1, 1)),
(AcDbCurve*&)pProjectedCurve);
pEllipse->close();
AcDbObjectId newCurveId;
addToModelSpace(newCurveId, pProjectedCurve);
}

// Accepts an ellipse object ID, opens the ellipse, and uses


// its getOffsetCurves() member function to create a new
// ellipse that is offset 0.5 drawing units from the
// original ellipse.
//
void
offsetEllipse(AcDbObjectId ellipseId)
{
AcDbEllipse *pEllipse;
acdbOpenObject(pEllipse, ellipseId, AcDb::kForRead);
// Now generate an ellipse offset by 0.5 drawing units.
//
AcDbVoidPtrArray curves;
pEllipse->getOffsetCurves(0.5, curves);
pEllipse->close();
AcDbObjectId newCurveId;
addToModelSpace(newCurveId, (AcDbEntity*)curves[0]);
}

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();
}

Глава 7.Контейнерные Объекты


Эта глава описывает контейнерные объекты, используемые в операциях базы данных AutoCAD: таблицы
идентификаторов, словари, группы, и xrecords. Как часть любого рисунка, AutoCAD создает установленный
набор таблиц идентификаторов и названного объектного словаря, который содержит два других словаря,
MLINE стиль и словари ГРУПП.
Примеры главы демонстрируют, как добавить входы к таблицам идентификаторов, словарям, и группам, и как
сделать запрос содержания этих контейнеров, использующих iterators.
Они также показывают, как создавать и использовать ваши собственные словари и xrecords, чтобы управлять
данными прикладной программы и объектами. Для описания словаря расширения объекта AcDbObject, см.
главу 5, “ Объекты Базы данных. ”

 Сравнение Таблиц идентификаторов и Словарей


 Таблицы идентификаторов (Symbol Tables)
 Словари (Dictionaries)
 Размещения (Layouts)
 Xrecords

Сравнение Таблиц идентификаторов и Словарей


Таблицы идентификаторов и словари исполняют по существу ту же самую функцию; они содержат входы,
которые являются базой данных, возражает, что можно искать, используя текстовую строковую
клавишу{*ключ*}. Вы можете добавлять входы к этим контейнерным объектам, и Вы можете использовать
iterator, чтобы шагнуть через входы и сделать запрос их содержания.
База данных AutoCAD всегда содержит установленный набор девяти таблиц идентификаторов, описанных в
следующем разделе. Вы не можете создавать или удалять таблицу идентификаторов, но Вы можете
добавлять или изменять{*заменять*} входы в таблице идентификаторов, которые вызваны{*названы*} записи.
Каждая таблица идентификаторов содержит только специфический тип объекта.
Например, AcDbLayerTable содержит только объекты типа AcDbLayerTableRecord. Таблицы идентификаторов
определены этим способом главным образом для совместимости с Выпуском AutoCAD 12 и предыдущих
выпусков AutoCAD.

83
Словари обеспечивают подобный механизм для сохранения и восстановления{*поиска*} объектов со
связанными клавишами{*ключами*} имени. База данных AutoCAD создает названный объектный словарь
всякий раз, когда это создает новый рисунок. Названный объектный словарь может рассматриваться как
главное “оглавление” для структур объекта небытия в рисунке. Этот словарь, по умолчанию, содержит четыре
словаря: словарь ГРУППЫ, MLINE словарь стиля, словарь размещения, и графический стиль называет
словарь. Вы можете создавать любое число дополнительных объектов и добавлять их к названному
объектному словарю. Однако, лучшая практика должна добавить один объект непосредственно к названному
объектному словарю и иметь тот объект, в свою очередь имеют другие объекты, связанные с вашим
приложением. Как правило, объект обладания - контейнерный класс типа словаря. Используйте ваш
назначенный Зарегистрированный Символ Разработчика с четырьмя символами для имени этого класса.
Объект AcDbDictionary может содержать любой тип AcDbObject, включая другие словари. Объект словаря не
исполняет контроль соответствия типов входов. Однако, MLINE словарь стиля должен содержать только
образцы класса AcDbMlineStyle, и словарь ГРУППЫ должен содержать только образцы AcDbGroup.
Приложение может требовать определенного печатания для входов в словаре, который это создает и
обслуживает{*поддерживает*}.

Иерархия классов для таблиц идентификаторов, записей таблицы идентификаторов, словарей, и iterators
следующие.

Важное различие между таблицами идентификаторов и словарями - те записи таблицы идентификаторов, не


может быть стерт непосредственно Приложением ObjectArx.
Эти записи могут быть стерты только с командой PURGE или выборочно фильтрован из с wblock
операциями. Объекты, принадлежащие словарю могут быть стерты.

ПРЕДУПРЕЖДЕНИЕ! Стирание словарей или входов словаря (см. “ Обязательные Объекты Базы данных ” на
странице 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)

Каждая таблица содержит объекты соответствующего подкласса AcDbSymbolTableRecord.


Каждый класс таблицы идентификаторов обеспечивает getAt () функцией для поиска записи, указанной по
имени. Сигнатуры для перезагруженных форм getAt () функция следующие. (##BASE_NAME## Замещает
любой из девяти типов класса таблицы идентификаторов.)

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 обеспечивает детальное описание свойств уровня.
Следующие разделы перечисляют функции члена для установки и запроса свойств уровня.

Frozen/Thawed (Заморозить / таять)


Когда уровень закрепляется, графика не восстановлена.

void AcDbLayerTableRecord::setIsFrozen(Adesk::Boolean);

Adesk::Boolean
AcDbLayerTableRecord::isFrozen() const;

On/Of (Вкл\выкл)
Когда уровень ВЫКЛЮЧЕН, графический не отображены.

void AcDbLayerTableRecord::setIsOff(Adesk::Boolean);

Adesk::Boolean
AcDbLayerTableRecord::isOff() const;

Viewport (Область просмотра)


Этот setVPDFLT () функция определяет,является ли уровень по умолчанию видимым или невидимым в новых
областях просмотра.

void AcDbLayerTableRecord::setVPDFLT(Adesk::Boolean);

Adesk::Boolean
AcDbLayerTableRecord::VPDFLT() const;

Locked/Unlocked (Блокировал / разблокировал)


Примитивы на блокированном уровне не могут изменяться пользователем AutoCAD или открыт для записи ()
функция в пределах программы.

void AcDbLayerTableRecord::setIsLocked(Adesk::Boolean);

Adesk::Boolean
AcDbLayerTableRecord::isLocked() const;

Color (Цвет)
Цвет, установленный setColor () функция используется, когда цвет примитива - BYLAYER.

void AcDbLayerTableRecord::setColor(const AcCmColor &color);

AcCmColor
AcDbLayerTableRecord::color() const;

Linetype
Linetype, установленный setLinetypeObjectId () функция используется, когда linetype примитива - BYLAYER.

void AcDbLayerTableRecord::setLinetypeObjectId(AcDbObjectId);
AcDbObjectId
AcDbLayerTableRecord::linetypeObjectId() const;

Создание и Изменение Записи Таблицы Уровня


Следующие показы примера, получающие таблицу уровня для текущей базы данных и открытия этого для
записи. Это создает новую запись таблицы уровня (AcDbLayerTableRecord) и устанавливает некоторые
атрибуты уровня (имя, закрепляемый атрибут, вкл\выкл, область просмотра, и блокированный). Тогда это
создает цветной объект класса и устанавливает цвет уровня к красному.

Чтобы устанавливать 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);
}

// Prompts the user to select objects to add to the group,


// opens the group identified by "groupId" passed in as
// an argument, then adds the selected objects to the group.
//
void
makeGroup(AcDbObjectId groupId)
{
ads_name sset;
int err = acedSSGet(NULL, NULL, NULL, NULL, sset);
if (err != RTNORM) {
return;
}
AcDbGroup *pGroup;
acdbOpenObject(pGroup, groupId, AcDb::kForWrite);
// Traverse the selection set, exchanging each ads_name
// for an object ID, then adding the object to the group.
//
long i, length;
ads_name ename;
AcDbObjectId entId;
acedSSLength(sset, &length);
for (i = 0; i < length; i++) {
acedSSName(sset, i, ename);
acdbGetObjectId(entId, ename);
pGroup->append(entId);
}
pGroup->close();
acedSSFree(sset);
}

// Accepts an object ID of an AcDbGroup object, opens it,


// then iterates over the group, removing all entities that
// are not AcDbLines and changing all remaining entities in
// the group to color red.
//
void
removeAllButLines(AcDbObjectId groupId)
{
AcDbGroup *pGroup;
acdbOpenObject(pGroup, groupId, AcDb::kForWrite);
AcDbGroupIterator *pIter = pGroup->newIterator();
AcDbObject *pObj;
for (; !pIter->done(); pIter->next()) {
pIter->getObject(pObj, AcDb::kForRead);
// If it is not a line or descended from a line,
// close it and remove it from the group. Otherwise,
// just close it.
//
if (!pObj->isKindOf(AcDbLine::desc())) {
// AcDbGroup::remove() requires that the object

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();
}

MLINE Словарь Стиля


MLINE словарь стиля содержит объекты класса AcDbMlineStyle. Как показано в следующем
рисунке, объекты класса AcDbMline каждый имеет связанный MLINE стиль, который определяет
свойства мультилинии, типа смещения, цвета, и linetype.

Словарь Размещения
Словарь размещения - заданный по умолчанию словарь в пределах названного объектного
словаря, который содержит объекты класса AcDbLayout. AcDbLayout объектно-ориентированные
памяти характеристики размещения пространства листа, включая графические параметры
настройки. Каждый объект AcDbLayout также содержит объект ID связанной записи таблицы
блоков, которая сохраняет примитивы, связанные с размещением.

90
Создание Словаря
Следующий пример создает новый словарь (ASDK_DICT) и добавляет это к словари имен
объектов. Тогда это создает два новых объекта класса пользователя AsdkMyClass (полученный из
AcDbObject) и добавляет их к словарю, используя setAt () функция.

ОБРАТИТЕ ВНИМАНИЕ, что Вы должны закрыть объекты после добавления их с setAt () функция.

// This function creates two objects of class AsdkMyClass.


// It fills them in with the integers 1 and 2, and then adds
// them to the dictionary associated with the key ASDK_DICT. If this
// dictionary doesn’t exist, it is created and added to the named
// object dictionary.
//
void
createDictionary()
{
AcDbDictionary *pNamedobj;
acdbHostApplicationServices()->workingDatabase()->
getNamedObjectsDictionary(pNamedobj, AcDb::kForWrite);
// Check to see if the dictionary we want to create is
// already present. If not, create it and add
// it to the named object dictionary.
//
AcDbDictionary *pDict;
if (pNamedobj->getAt("ASDK_DICT", (AcDbObject*&) pDict,
AcDb::kForWrite) == Acad::eKeyNotFound)
{
pDict = new AcDbDictionary;
AcDbObjectId DictId;
pNamedobj->setAt("ASDK_DICT", pDict, DictId);
}
pNamedobj->close();
if (pDict) {
// Create new objects to add to the new dictionary,
// add them, then close them.
//
AsdkMyClass *pObj1 = new AsdkMyClass(1);
AsdkMyClass *pObj2 = new AsdkMyClass(2);
AcDbObjectId rId1, rId2;
pDict->setAt("OBJ1", pObj1, rId1);
pDict->setAt("OBJ2", pObj2, rId2);
pObj1->close();
pObj2->close();
pDict->close();
}
}

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.

ObjectARX Классы Размещения


Основные классы, вовлеченные в создание и управление размещениями - следующее:
 AcDbLayout
 AcDbPlotSettings
 AcDbPlotSettingsValidator
 AcDbLayoutManager
 AcApLayoutManager
 AcDbLayoutManagerReactor
AcDbLayout, AcDbPlotSettings, и AcDbPlotSettingsValidator используются, чтобы создавать и
установить атрибуты на объектах размещения. AcDbLayoutManager, AcApLayoutManager, и
AcDbLayoutManagerReactor используются, чтобы управлять объектами размещения и исполнять
другие связанные размещением задачи. Следующие разделы обеспечивают краткий обзор
некоторых из этих классов. Для получения дополнительной информации, см. ObjectARX Ссылку.
Для примера использования ObjectARX классов размещения, см., что lmgrtest.arx производит
выборку приложения в ObjectARX, производит выборку каталога.

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;

AcDbXrecord:: setFromRbChain() функция заменяет существующую resbuf цепочку .

DXF Коды Группы для Xrecords


Следующая таблица перечисляет коды группы DXF, которые могут использоваться в records.

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();
}

// Gets the xrecord associated with the key XREC1 and


// lists out its contents by passing the resbuf list to the
// function printList.
//
void
listXrecord()
{
AcDbDictionary *pNamedobj;
acdbHostApplicationServices()->workingDatabase()
->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead);
// Get the dictionary object associated with the key ASDK_DICT.
//
AcDbDictionary *pDict;
pNamedobj->getAt("ASDK_DICT", (AcDbObject*&)pDict,
AcDb::kForRead);
pNamedobj->close();
// Get the xrecord associated with the key XREC1.
//
AcDbXrecord *pXrec;
pDict->getAt("XREC1", (AcDbObject*&) pXrec,
AcDb::kForRead);
pDict->close();
struct resbuf *pRbList;
pXrec->rbChain(&pRbList);
pXrec->close();
printList(pRbList);
acutRelRb(pRbList);
}

Часть 2. Интерфейсы пользователя


Глава 8. MFC
Библиотека фундаментальных классов Microsoft (MFC) позволяет разработчику осуществлять стандартные
интерфейсы пользователя быстро. ObjectARX среда обеспечивает набор классов, что разработчик может
использовать, чтобы создать MFC-ОСНОВАННЫЕ интерфейсы пользователя, которые ведут себя и
появляются как встроенные интерфейсы пользователя Autodesk. Эта глава описывает, как использовать MFC
библиотеку как часть Приложения ObjectArx.
 Введение
 Использование MFC с Приложениями ObjectArx
 Приложения ObjectArx с Динамически Связанным MFC
 Встроенная MFC Поддержка Интерфейса пользователя
 Использование AdUi и AcUi с VC ++ AppWizard

Введение
Приложения ObjectArx могут быть созданы, чтобы воспользоваться преимуществом Microsoft
Фундаментальный класс (MFC) библиотека. Эта глава обсуждает, как формировать ваш
Приложения ObjectArx, чтобы использовать MFC и как встроенный AutoCAD
MFC система может использоваться, чтобы создать диалоги, которые ведут себя и работают
AutoCAD.

Использование MFC с Приложениями ObjectArx


Вы имеете выбор формирования Приложений ObjectArx с любым a
Динамически связанный MFC библиотека или статически связанная MFC библиотека. Вы также
Имейте выбор использования регулярного DLL или расширения{*продления*} DLL.
ПРИМЕЧАНИЮ Это строго рекомендуют динамически связать ваш MFC ObjectARX
Приложение И делает это расширением{*продлением*} DLL, так как это - единственный метод, который
позволяет
Вы, чтобы использовать Autodesk AdUi и AcUi базовые классы MFC.
Для законченной информации относительно MFC, см. интерактивную справку Microsoft и
Технические примечания. В частности см. примечания 11 и 33 для информации относительно
Использование MFC как{*поскольку*} часть DLL, который является важной концепцией для ObjectARX.

95
MFC и Немодальные Диалоговые окна
Так как AutoCAD пытается забирать центр от всех его дочерних окон, немодальные диалоги имеют
специальное требование. Равномерно, немодальный диалог получит сообщение окна
WM_ACAD_KEEPFOCUS, которое определено в adscodes.h как 1001. Когда ваш диалог получает это
сообщение, это возвратило бы ИСТИНУ, если это сохранило центр. Если ответ на это сообщение ЛОЖНЫЙ
(который является также значением по умолчанию), то ваше диалоговое окно будет терять центр, как только
пользователь перемещает указатель от окна поля диалога.
Вы можете делать это с картой сообщения поля диалога, и ON_MESSAGE () объявление типа

BEGIN_MESSAGE_MAP (HelloDlg, CDialog)


ON_COMMAND (IDCLOSE, OnClose)
ON_COMMAND (IDC_DRAW_CIRCLE, OnDrawCircle)
ON_MESSAGE (WM_ACAD_KEEPFOCUS, onAcadKeepFocus)
END_MESSAGE_MAP ()

В этом примере, диалоговый класс приложения - HelloDlg, который получен из CDialog. Когда Вы добавляете
этот вход в карту сообщения, Вы должны также записать функцию обработчика для сообщения.
Предположите, что Вы написали функцию, вызвал keepTheFocus(), который возвращает ИСТИНУ, если ваш
диалог хочет сохранить фокус ввода и ЛОЖЬ, если диалог желает выдавать фокус AutoCAD. Обработчик
сообщения примера обеспечивается здесь:

afx_msg LONG HelloDlg::onAcadKeepFocus(UINT, LONG)


{
return keepTheFocus() ? TRUE : FALSE;
}

Приложения ObjectArx с Динамически Связанным MFC


Привилегированный метод для формирования MFC-ОСНОВАННОГО Приложения ObjectArx состоит в том,
чтобы использовать динамически связанные MFC библиотеки.

Параметры настройки Проекта Visual C++ для Динамически Связанного MFC


Формировать Приложение ObjectArx, используя общедоступную MFC библиотеку
1 Выбирают MFC AppWizard опция (DLL) для проекта.
2 Расширение Выбора DLL использование общедоступного MFC DLL.
3 Идут к диалоговому окну Project Settings и выбирают позицию табуляции General.
4 Использование Выбора MFC в Общедоступном DLL для поля Microsoft foundation class.
5 Добавляют функцию acrxEntryPoint к CPP файлу проекта. См. пример в конце главы для законченной
установки для проекта MFC.

Отладка Приложений ObjectArx с Динамический MFC


При отладке Приложений ObjectArx, сформированных с динамически связанной MFC библиотекой, свяжите с
выпускаемой версией C время выполнения и MFC библиотеки.
Это позволяет использование MFC или C отладку время выполнения средств, но не позволяет шагать в
Microsoft MFC отлаживающий исходный текст.

Управление ресурсами
Управление ресурсами - важное соображение{*рассмотрение*} при проектировании Приложения 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_DECLARE_EXTENSION_MODULE и


AC_IMPLEMENT_EXTENSION_MODULE, помогать определять и осуществляют классы в вашем приложении.

Следующий код иллюстрирует, как использовать классы CAcExtensionModule и CAcModuleResourceOverride в


ObjectARX-приложении:

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
}

Встроенная MFC Поддержка Интерфейса пользователя


ObjectARX имеет набор MFC Интерфейса пользователя (UI) связанные классы, которые легко позволяют Вам
обеспечивать непротиворечивый UI. Это означает, что ваш UI может вести себя и иметь появление{*вид*}
AutoCAD UI. Строго рекомендует использовать эти классы, так как они позволяют вашему приложению быть
более сильно интегрированными с AutoCAD UI. Autodesk MFC система разделен на две библиотеки. Первый
вызван{*назван*} AdUi и не Определенный автохамом. Второй вызван{*назван*} AcUi и содержит
Определенное автохамом появление{*вид*} и поведение.
AdUi - MFC динамически компонуемая библиотека расширения{*продления*}, имел обыкновение
расширять{*продлевать*} некоторых из UI-имеющихся отношение классов MFC. Библиотека была
разработана для использования с AutoCAD и другими изделиями{*программами*} Autodesk и содержит
основные функциональные возможности. Библиотека компаньонов, AcUi, формирует на AdUi структуру и
обеспечивает AutoCAD- определенное появление{*вид*} и поведение. AdUi и AcUi библиотеки обеспечивают
классы, которые расширяют{*продлевают*} обеспеченный MFC способами, которые позволяют ARX

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 обеспечивают классы, которые осуществляют следующие особенности:


 изменение размеров Диалога
 постоянство данных Диалога
 Табулированные диалоги
 Расширяемые табулированные диалоги
 Контекстно-зависимая справка и справка F1
 взаимодействие Диалога с редактором рисунка AutoCAD
 кнопки Bitmap, которые являются удобными
 Статические растровые кнопки
 кнопки Bitmap, которые являются, перетащат и опустить узлы
 кнопки точечного рисунка Стиля инструментальной панели
 кнопки Owner-draw, которые являются удобными
 Диалог и управление поддерживают для стандарта ToolTips
 Диалог и управление поддерживают для TextTips (которые отображают обрезанный текст)
 Диалог и поддержка управления для DrawTips (владелец - тянут TextTips)
 Заказная передача сообщений, включая проверку правильности данных
 Поля со списком, которые отображают и позволяют выбор многого AutoCAD определенные элементы
 Состыковывающиеся окна строки управления для использования с AutoCAD
 Определенные в AutoCAD растровые кнопки (кнопки Pick и Select)
 Специализированные средства редактирования, которые могут исполнять Определенную AutoCAD
проверку правильности данных
 Заказная передача сообщений, включая проверку правильности данных

Иерархия Классов
Следующее - поддержанные классы в AdUi и AcUi библиотеках. Имеется подарок{*настоящее*} классов в
файлах заголовка, которые не показываются и - для внутреннего использования только и не поддержаны для
использования с ObjectARX.

98
AdUi Передача сообщений
AdUi библиотека использует внутреннюю схему передачи сообщений облегчить связь между объектами.
Типично это вовлекает контейнер (типа диалога) отвечающий на уведомление от содержащегося окна (типа
управления).
Расширенные приложения могут приспосабливать встроенную систему к их потребностям, или добавлять
AdUi поддержку передачи сообщений к другому CWND полученные классы.

AdUi Окна подсказок


AdUi обеспечивает три типа окон совета{*предупреждения*}: ToolTips, TextTips, и DrawTips.
ToolTips представляют готовый Windows ToolTips, как предусмотрено обычным Средством управления DLL
установленный на системе пользователя. TextTips - основанные на тексте окна совета, которые выскочат по
управлению, обычно показать данные, которые пользователь был бы иначе должен листать в представление.
DrawTips – расширение TextTips.
Управление ниже совета обычно ответствено за закрашивание содержания совета (аналогичное владельцу -
тянущемуся совету).
Большинство приложений редко вовлекает эти классы непосредственно, так как AdUi обычно обрабатывает
все требования. AdUi использует его внутреннюю систему передачи сообщений, чтобы вести переговоры
между контейнерами и средством управления и решать когда и как отобразить совет.
CAdUiTipWindow Класс
CAdUiTipWindow - основной AdUi класс окна совета{*предупреждения*}. Эти объекты обрабатывают
универсальный совет{*предупреждение*}, отображают и знают, когда автоматически скрыть себя (типа
обнаружения движения курсора, краткой блокировки времени, или деятельности клавиатуры).
CAdUiTextTip Класс
CAdUiTextTip специализирует CADUITIPWINDOW, чтобы отобразить TextTip.
CAdUiDrawTipText Класс
CAdUiDrawTipText используется внутренне AdUi системой передачи сообщений, чтобы сообщить управлению,
что окно совета{*предупреждения*} нуждается в перекрашивании. Управление имеет опцию
изменения{*замены*} атрибутов контекста устройства окна совета{*предупреждения*} и рисунка текста.

AdUi Диалоговые классы


Диалоговые классы AdUi пригодны для использования в приложениях других чем AutoCAD.
CAdUiBaseDialog Класс
CAdUiBaseDialog обеспечивает основную поддержку для окон совета{*предупреждения*} (ToolTips и TextTips)
и AdUi системы обработки сообщения. Это также поддерживает контекстную справку и справку F1 в диалогах.
Это - общий{*обычный*} базовый класс для всех диалогов кроме, те базировались на общем{*обычном*}
диалоге файла.
CAdUiDialog Класс
CAdUiDialog - универсальный класс, который обеспечивает набор функций члена, учитывающих диалоги
изменяемого размера и постоянство данных.
CAdUiFileDialog
CAdUiFileDialog специализирует CFILEDIALOG аналогичный путь, поскольку CAdUiBaseDialog специализирует
CDIALOG. Класс обеспечивает основную поддержку для окон совета{*предупреждения*} (ToolTips и TextTips),
контекстной справки и AdUi обработки сообщения в общем{*обычном*} диалоге файла. В отличие от
CADUIBASEDIALOG, не имеется никакой встроенной поддержки для постоянства размера и позиции.
CAdUiTabMainDialog Класс
CAdUiTabMainDialog представляет основной контейнерный диалог в табулированном диалоге.
CAdUiTabMainDialog и CADUITABMAINDIALOG используются на месте CPROPERTYSHEET и
CPROPERTYPAGE, чтобы создать табулированные диалоги.
CAdUiTabChildDialog Класс
CAdUiTabChildDialog представляет позицию табуляции в табулированном диалоге.
CAdUiTabMainDialog и CADUITABCHILDDIALOG используются на месте CPROPERTYSHEET и
CPROPERTYPAGE, чтобы создать табулированные диалоги. Каждая позиция табуляции в табулированном
диалоге - CADUITABCHILDDIALOG.

AcUi Диалоговые классы


Диалоговые классы AcUi формируют на диалоговые классы AdUi и пригодны для использования только с
AutoCAD.
CAcUiDialog Класс
CAcUiDialog - класс общего назначения, который обеспечивает набор функций члена, учитывающих диалоги
изменяемого размера и постоянство данных в AutoCAD.
CAcUiTabMainDialog Класс

99
CAcUiTabMainDialog представляет основной контейнерный диалог в AutoCAD табулированный диалог.
CAcUiTabMainDialog и CACUITABMAINDIALOG используются на месте CPROPERTYSHEET и
CPROPERTYPAGE, чтобы создать табулированные диалоги в AutoCAD.
CAcUiTabChildDialog Класс
CAcUiTabChildDialog представляет позицию табуляции в табулированном диалоге.
CAcUiTabMainDialog и CACUITABCHILDDIALOG используются на месте CPROPERTYSHEET и
CPROPERTYPAGE, чтобы создать табулированные диалоги в AutoCAD. Каждая позиция табуляции
в AutoCAD табулировала диалог - CACUITABCHILDDIALOG.
CAcUiAlertDialog Класс
CAdUiAlertDialog представляет аварийный диалог с тремя кнопками. Одна кнопка - кнопка CANCEL,
и другие два текста командной кнопки установлены программистом. Это - аварийный диалог
общего назначения.
CAcUiFileDialog Класс
CAcUiFileDialog обеспечивает Определенное автохамом образование из CADUIFILEDIALOG.

AdUi Расширяемость Позиции табуляции Поддержки Классов


Следующие классы обеспечивают поддержку для диалогов позиции табуляции.
CAdUiTabExtensionManager Класс
CAdUiDialogManager - класс, который управляет добавлением и удалением позиций табуляции от
табулированного диалога, который является расширяемым. Если диалог - расширяемая позиция
табуляции, образец этого класса найден в CADUITABMAINDIALOG.
CAdUiTab Класс
CAdUiTab формирует MFC CTabCtrl и добавляет функциональные возможности к этому. Один из
этих объектов найден в основном объекте диалога.

AdUi и AcUi Классы Строки управления


Следующие классы обеспечивают поддержку для состыковывающихся окон.
CAdUiDockControlBar Класс
CADUIDOCKCONTROLBAR класс, часть системы стыковки, добавляет
расширенные{*продленные*} возможности к MFC CControlBar класс. Основная особенность,
обеспеченная - изменение размеров строк управления когда состыковано{*закреплено*}. Больше
чем одна строка управления можно закреплять вместе, каждый из них являющийся способным
быть измененными, индивидуально используя расщепители, созданные системой стыковки.
CAdUiDockControlBar также идет с областью механизма захвата и близкой кнопкой когда
состыковано{*закреплено*}. Управляйте состоянием областей, может переключаться
состыкованным{*закрепленным*} с несостыкованным{*незакрепленным*} или наоборот, дважды
нажимая на механизме захвата когда состыковано{*закреплено*}, или области заголовка когда
несостыковано{*незакреплено*}, или, перемещая их с мышью. Система стыковки обрабатывает
постоянство строк управления, сохранение их позиция и состояние поперек сеансов. Наконец,
CAdUiDockControlBar обеспечивает заданное по умолчанию контекстное меню, чтобы управлять
поведением области, с возможностью для разработчика, чтобы настроить это меню.
CAcUiDockControlBar Класс
CACUIDOCKCONTROLBAR класс добавляет к CADUIDOCKCONTROLBAR, классифицируют
поведение, обычное к AutoCAD dockable инструментальные средства: когда пользователь
перемещает курсор мыши из области{*региона*} строки управления, фокус автоматически отдается
обратно к AutoCAD.

AdUi и AcUi Средства редактирования


Следующие классы обеспечивают специализированное средство управления редактирования, включая
поддержку для определенных типов данных.
CAdUiEdit Класс
CAdUiEdit получен из CEDIT класса, чтобы обеспечить средство управления окна редактирования.
Этот класс обеспечивает поддержку для окон совета{*предупреждения*} за обрезанные текстовые
элементы{*пункты*} (TextTips).
Этот класс берет разрядные флажки, чтобы добавить желательное поведение проверки
правильности, основанное на следующих типах ввода: Числовой, Строковый, Угловой, и
названия{*имена*} Символа. Вообще Вы должны использовать один из классов, полученных из
Определенного автохамом класса CAcUiComboBox, который добавляет определенную проверку
правильности типа данных и постоянство к управлению. Они - CACUISTRINGEDIT,
CAcUiSymbolEdit, CAcUiNumericEdit, и CACUIANGLEEDIT.
CAcUiEdit Класс

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).

AdUi и AcUi Средство управления Поля со списком


Следующие классы обеспечивают поддержку для средства управления поля со списком.
CAdUiComboBox Класс
CAdUiComboBox получен из CCOMBOBOX класса, чтобы обеспечить средство управления поля со
списком. Этот класс обеспечивает поддержку для окон совета{*предупреждения*} за обрезанные
текстовые элементы{*пункты*} (TextTips), и проверку правильности данных в средствах
редактирования. Этот класс берет разрядные флажки, чтобы добавить желательное поведение
проверки правильности, основанное на следующих типах ввода: числовой, строковый, угловой, и
названия{*имена*} символа. Вообще, Вы должны использовать один из классов, полученных из
Определенного автохамом класса CAcUiComboBox, который добавляет определенную проверку
правильности типа данных и постоянство к управлению. Они - CACUISTRINGCOMBOBOX,
CAcUiSymbolComboBox, CAcUiNumericComboBox, и CACUIANGLECOMBOBOX. В поддержку для
нарисованного пользователем средства управления также встраивают.
CAcUiAngleComboBox Класс
CACUIANGLECOMBOBOX конструктор автоматически создает CACUIANGLEEDIT, чтобы
подклассифицировать окно редактирования управления. Это учитывает проверку правильности
углов, определенных к параметрам настройки AutoCAD.
CAcUiNumericComboBox Класс

101
CACUIANGLECOMBOBOX конструктор автоматически создает CACUINUMERICEDIT, чтобы
подклассифицировать окно редактирования управления. Это учитывает проверку правильности
чисел{*номеров*}, определенных к параметрам настройки AutoCAD.
CAcUiStringComboBox Класс
CACUISTRINGCOMBOBOX конструктор автоматически создает CACUISTRINGEDIT, чтобы
подклассифицировать окно редактирования управления. Любой ввод приемлем.
CAcUiSymbolComboBox Класс
CACUISYMBOLCOMBOBOX конструктор автоматически создает CACUISYMBOLEDIT, чтобы
подклассифицировать окно редактирования управления. Правильные{*допустимые*}
названия{*имена*} символа AutoCAD - приемлемый ввод.

AcUi MRU Поля со списком


AcUi расширяет{*продлевает*} поддержку поля со списком, чтобы управлять MRU (наиболее
недавно используемый) список автоматически в пределах управления. Основные функциональные
возможности обеспечиваются классом CAcUiMRUComboBox (полученный из CACUICOMBOBOX).
Класс компаньона, CAcUiMRUListBox, обеспечивает поддержку DrawTip для combo поля
ComboLBox. Это необходимо из-за MRU выполнения поля со списком как владелец - тянущееся
управление.
Пять специализировался, MRU классы поля со списком также обеспечиваются:
CAcUiArrowHeadComboBox, CAcUiColorComboBox, CAcUiLineWeightComboBox,
CAcUiPlotStyleTablesComboBox, и CACUIPLOTSTYLENAMESCOMBOBOX. Они обеспечивают
стандартные интерфейсы пользователя для управления dimensioning стрелками - указателями,
цветными и lineweight выборами, и составляют график таблицы стиля и составляют график стиля,
называет выбор.
CAcUiMRUComboBox Класс
CAcUiMRUComboBox наследует CACUICOMBOBOX и служит, поскольку базовый класс для
владелец - тянет поля со списком, которые осуществляют список MRU. Каждый элемент{*пункт*} в
списке может содержать маленькое изображение{*образ*}, сопровождаемое некоторым текстом.
Каждый элемент{*пункт*} также прослеживает уникальное значение, упомянутое как груз, и
поддерживаемый как стандартный Windows ® ITEMDATA в пределах управления. Класс показывает
встроенную поддержку для до двух универсальных, необязательных элементов{*пунктов*},
упомянутых как Option1 и Option2. Они обычно соответствуют{*переписываются*} “ByLayer” и
“ByBlock” и часто имеют специальное значение.
Два других элемента{*пункта*}, Other1 и Other2, можно также допускать и появляться только, когда список
понижен вниз. Выбор любого из этих элементов{*пунктов*} вызывает специальный случай в пределах
управления.
CAcUiArrowHeadComboBox Класс
CAcUiArrowHeadComboBox специализирует CACUIMRUCOMBOBOX для dimensioning выбора
стрелки - указателя. Управление отображает точечные рисунки, представляющие стандарт
AutoCAD dimensioning стили стрелки - указателя, которые являются всегда подарком{*настоящим*}
в списке. По умолчанию никакие необязательные или дополнительные элементы{*пункты*} не
присутствуют или добавленный. Груз, связанный с каждым элементом{*пунктом*} - индекс AutoCAD
для связанной готовой стрелки - указателя. Когда MRU элементы{*пункты*} добавлены к списку,
они автоматически назначены уникальное грузовое значение (который будет больший чем индекс
AutoCAD для определяемого пользователем стиля стрелки - указателя).
CAcUiColorComboBox Класс
CAcUiColorComboBox специализирует CACUIMRUCOMBOBOX для цветного выбора. Образчики
цветов дисплея управления, представляющие выборы от палитры AutoCAD.
Готовые элементы{*пункты*} всегда представляют в управлении, отражают номера цвета 1 до 7. Оба
необязательных элемента{*пункта*} используются; Option1 отображает “ByLayer”, и Option2 отображает
“ByBlock”. MRU дисплей элементов{*пунктов*} “ Окрашивают nnn, ”, где nnn - связанный номер цвета. Груз,
связанный с каждым элементом{*пунктом*} указывает, что номер цвета AutoCAD (типа от 1 до 255), “ByBlock”
касается 0, и “ByLayer” соответствует 256. Other1 элемент{*пункт*} допускается и вызывает диалог Выбора
Цвета AutoCAD. Если Other2 допускают, это отображает как “ Windows ... ” и по умолчанию вызывает Выбор
Цвета Windows Общий{*обычный*} диалог. Если пользователь выбирает элемент{*пункт*} от любого из этих
диалогов, выбор появляется в списке MRU и становится текущим элементом{*пунктом*} в управлении.
CAcUiLineWeightComboBox Класс
CAcUiLineWeightComboBox специализирует CACUIMRUCOMBOBOX для lineweight выбора.
Управление отображает маленький предварительный просмотр lineweights AutoCAD, поддерживает,
в пределах от 0.05mm к 2.11mm, и не включает “Ни один” и произвольно “Значение по умолчанию”.
И показатель и имперские значения отображены, в зависимости от установки LWUNITS системной
переменной. Оба необязательных элемента{*пункта*} используются; Option1 отображает “ByLayer”,

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 правильно.

AdUi Классы Кнопки


Это средство управления пригодно для использования в приложениях других чем AutoCAD.
CAdUiOwnerDrawButton Класс
Этот класс обеспечивает основным, владелец - тянут кнопку. Класс может использоваться, где-
нибудь CBUTTON может использоваться. Когда используется в AdUi-полученном диалоге (или
класс, который поддерживает, AdUi передача сообщений) CAdUiOwnerDrawButton автоматически
обеспечивает для дисплея AdUi окна совета{*предупреждения*}. Класс также поддерживает,
перетащат и опустить, Статический и Дисплей Инструмента, и эффекты PointedAt. В Режиме
визуального отображения Инструмента, кнопка кажется плоской и выскочит когда направлено в
(типа того, когда мышь перемещается поверх кнопки). Щелчок кнопки заставит это поместить вниз.
В Статическом Режиме визуального отображения, кнопка кажется плоской и ведет себя скорее статический
элемент управления чем кнопка команды. Комбинация предоставления перетащит и опустить, и Статический
Дисплей соответствующий созданию узлов, которые получают файлы через, перетащат и опустить.
CAdUiBitmapButton Класс
Этот класс специализирует CADUIOWNERDRAWBUTTON, чтобы обеспечить кнопку, которая
отображает точечный рисунок (изображение{*образ*} оттянуто очевидно в кнопке). По умолчанию,
объекты этого класса автоматически изменяют размеры, чтобы приспособить связанное растровое
изображение. В отличие от CBITMAPBUTTON MFC'S, только один точечный рисунок необходим,
чтобы определить все государства кнопки (класс MFC'S требует четырех точечных рисунков).
CAdUiBitmapStatic Класс
CAdUiBitmapStatic специализирует CADUIBITMAPBUTTON, чтобы обеспечить кнопку, которая
допускает Статическому Дисплею по умолчанию. Это средство управления действует скорее
статика чем кнопки.
CAdUiDropSite Класс
CAdUiDropSite специализирует CADUIBITMAPSTATIC, чтобы обеспечить кнопку, которая допускает,
перетащат и опустить также как Статический Дисплей. Это средство управления может получать
файлы через, перетащат и опустить.
CAdUiToolButton Класс
CAdUiToolButton специализирует CADUIBITMAPBUTTON, чтобы обеспечить кнопку, которая
допускает Дисплею Инструмента по умолчанию. Это средство управления появляется скорее
кнопки инструментальной панели чем регулярные кнопки.

AcUi Классы Кнопки


Это средство управления формирует на классы AdUi и пригодно для использования только с AutoCAD.
CAcUiPickButton Класс
CAcUiPickButton специализирует CACUIBITMAPBUTTON, который является оберткой для класса
CAdUiBitmapButton. CAcUiPickButton обеспечивает кнопку, которая отображает стандартный
точечный рисунок кнопки указки.
CAcUiSelectButton Класс

103
CAcUiSelectButton специализирует CACUIPICKBUTTON. Это обеспечивает кнопку, которая
отображает стандартный точечный рисунок кнопки выбора.

Постоянство Данных Диалога


CAcUiDialog и классы CACUITAB автоматически наследуют постоянство. Постоянство, как
определено диалогами и средством управления в AcUi15.dll, означает, что память{*хранение*} для
любого и всего пользователя модальные диалоги в AutoCAD, полученном из этих классов сохранит
данные с текущим параметром пользователя, делая это виртуальное предпочтение.
Ваш диалог должен иметь уникальное имя, потому что это будет использовать общедоступную область
пространства{*пробела*} системного реестра параметра пользователя. Учитывая, что разработчики обычно
создают их приложения, использующие их зарегистрированный префикс разработчика, следующий метод
рекомендуется:

Module-name:dialog-name

Например, если бы ваше ObjectARX-приложение названо AsdkSample, и Вы имеете диалог названные


Координаты, Вы назвали бы это AsdkSample:Coordinates.
Имеются два типа постоянства данных диалога: из -the-box и определенный разработчиком.
Из -the-box постоянства обращается{*относится*} к позиции диалога, размеру, и размерам столбца
представления{*вида*} списка. Определено разработчиком обращается{*относится*} к любым данным,
которые разработчик выбирает сохранять в параметре пользователя или в течение срока
службы{*продолжительности жизни*} или смещения диалога и который может быть восстановлен{*отыскан*}
поперек обращений диалога.

Использование и распространение Системы Диалога Позиции табуляции AdUi


Все табулированные диалоги, которые используют CADUITABMAINDIALOG и
CADUITABCHILDDIALOG, могут быть легко сделаны расширяемой позицией табуляции. Не
имеется никакого предела для числа позиций табуляции, которые могут быть добавлены к
расширяемому по позиции табуляции диалогу. Если основной диалог изменяемого размера,
добавленные позиции табуляции могут участвовать в этом, изменяя размеры использования тех
же самых директив, выделенных в документации по диалогам изменяемого размера. Все диалоги в
использовании AutoCAD, листающем позиции табуляции в противоположность помещенным в стек
позициям табуляции.
Это важно для Вас, чтобы установить грязный бит для расширенной{*продленной*} позиции
табуляции, используя SetDirty () функция члена CADUITABCHILDDIALOG, когда данные должны
быть инициализированы или модифицирован через DoDataExchange.

Построение заказного диалога с табуляторами, расширяемого


Создайте ваш табулированный диалог, используя CAcUiTabMainDialog для основной
структуры{*рамки*} диалога и CACUITABCHILDDIALOG для каждой позиции табуляции. В
OnInitDialog () или конструкторе CACUITABMAINDIALOG немедленно вызывают SetDialogName () с
изданным именем вашего расширяемого диалога. ObjectARX-приложения будут использовать это
имя, чтобы добавить позиции табуляции к вашему диалогу. После того, как Вы добавляете, что
ваши позиции табуляции с звонят к AddTab (), в OnInitDialog, вызывать AddExtendedTabs ().
Помните, что ваш табулированный диалог может иметь любое число добавленных позиций
табуляции в этом, так что не примите установленное число позиций табуляции в другом месте в
коде диалога.

Например

BOOL CPrefTabFrame:: OnInitDialog ()


// Инициализация Диалога для моей табулированной структуры{*рамки*} диалога.
{
SetDialogName ("Предпочтение");
CAcUiTabMainDialog:: OnInitDialog ();
...
// Добавить мои позиции табуляции здесь.
m_tab.AddTab(0,IDS_FILES_TABNAME,IDD_FILES_TAB,&m_filesTab);
m_tab.AddTab(1,IDS_PERF_TABNAME,IDD_PERF_TAB,&m_performTab);
m_tab.AddTab(2,IDS_COMP_TABNAME,IDD_COMP_TAB,&m_compatTab);
// Добавить любые расширенные{*продленные*} позиции табуляции. Этот запрос состоит в том то, что делает это
// Расширяемая позиция табуляции диалога
AddExtendedTabs ();
}

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 ().

Например

extern "C" AcRx::AppRetCode acrxEntryPoint(


AcRx::AppMsgCode msg, void* appId)
{
switch (msg) {
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(appId);
acrxDynamicLinker->registerAppMDIAware(appId);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
case AcRx::kInitDialogMsg:
// A dialog is initializing that we are interested in adding
// tabs to.
addMyTabs((CAcUiTabExtensionManager*)pkt);
break;
default:
break;
}
return AcRx::kRetOK;
}

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");
}

// CMyTab1 is subclassed from CAcUiTabExtension.


static CMyTab1* pTab1;
void addMyTabs(CAcUiTabExtensionManager* pXtabManager)
{
// Allocate an extended tab if it has not been done already
// and add it through the CAcUiTabExtensionManager.
pTab1 = new CMyTab1;
pXtabManager->AddTab(_hdllInstance, IDD_TAB1,
"My Tab1", pTab1);
// If the main dialog is resizable, add your control
// resizing directives here.

105
pTab1->StretchControlXY(IDC_EDIT1, 100, 100);
}

Тогда для CMYTAB1 выполнения класса:

void CMyTab1::PostNcDestroy()
// Override to delete added tab.
{
delete pTab1;
pTab1 = NULL;
CAcUiTabExtension::PostNcDestroy();
}

Использование AdUi и AcUi с VC ++ AppWizard


Теперь, когда Вы видели краткий обзор для AdUi и AcUi поддержки диалога, мы представим пример
использования этих систем. Диалог, который мы создадим, будет появляться следующим образом. Исходный
текст для этого примера может быть найден в ObjectARX SDK docsamps\AsdkAcUiSample каталогом. Этот
пример, однако, опишет, как установить ваш проект с начала.

Создайте ObjectARX MFC Прикладной Скелет


1 Создают новый проект в Microsoft Visual C++, используя Прикладного Мастера. Выберите MFC AppWizard
(dll) проектный{*строительный*} тип. Назначите проект имя (для этой выборки, мы будем использовать имя
AsdkAcUiSample) и каталог и нажимать OK. На следующем экране, выберите Расширение{*продление*} MFC
DLL, затем нажмите Finish. Мы теперь имеем основное MFC Расширение{*продление*} DLL проект.
2 Мы теперь добавим необходимый код, чтобы поддержать ObjectARX. Откройте
AsdkAcUiSample.cpp файл. Удалите запрос AFX_EXTENSION_MODULE и также функция DllMain.
3 Добавляют следующее объявление:
AC_IMPLEMENT_EXTENSION_MODULE(theArxDLL);
4 Добавляют следующий код, чтобы установить команду AutoCAD и acrxEntryPoint:

void dialogCreate()
{
acutPrintf("\nAcUi Dialog Sample");
}

Следующий запрос addCommand использует образец ресурса модуля от


AC_IMPLEMENT_EXTENSION_MODULE макрокоманда:

static void initApp()


{
theArxDLL.AttachInstance();
CAcModuleResourceOverride resOverride;
acedRegCmds->addCommand(
"ASDK_ACUI_SAMPLE",
"ASDKACUISAMPLE",
"ACUISAMPLE",
ACRX_CMD_MODAL,
dialogCreate,
NULL,
-1,
theArxDLL.ModuleResourceInstance());
}

Следующий unloadApp () функция вызвана, когда приложение разгружается.


В это время важно отделить образец ресурса:

static void unloadApp()


{
// Do other cleanup tasks here
acedRegCmds->removeGroup("ASDK_ACUI_SAMPLE");
theArxDLL.DetachInstance();
}

// 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;
}

Создайте AsdkAcUiSample.h файл заголовка, и добавьте следующие линии к file:

#include "resource.h" // main symbols


#define PI 3.14159265359
// Forward declaration for the entry point function of
// our application
void testCreate();

Тогда добавьте следующие файлы для включения к AsdkAcUiSample.cpp:

#include "AsdkAcUiSample.h"
#include "AcExtensionModule.h"

Вы будете также должны добавить ObjectARX библиотеки к проектному файлу, заменять .dll расширение к
.arx, и изменять .def файл надлежащим экспортом. Тогда Вы должны быть способны компилировать и
загрузить приложение.

Создание MFC-диалога, используя Visual Studio


1 В Visual C++ добавляют ресурс диалога.
2 Создают следующее диалоговое окно, используя средство управления Студии Приложения:

3 Удостоверятся ресурс, ИДЕНТИФИКАТОРЫ соответствуют{*согласовывают*} этой диаграмме, или


остающийся код не будет работать.

Создание классов и средств управления


1 Использование ClassWizard, создайте диалоговый класс. Если Вы запускаете ClassWizard с экрана создания
диалога, это запросит Вас создавать новый класс. Нажмите OK для нового класса, и затем дайте диалогу имя.
Для этого примера используют AsdkAcUiDialogSample.
2 Выключатель к позиции табуляции member variable.
3 Для IDC_BUTTON_ANGLE и IDC_BUTTON_POINT ресурсов добавляют, что средство управления CBUTTON
вызвало m_ctrlAngleButton и m_ctrlPickButton, соответственно.
4 Для IDC_EDIT_ANGLE, IDC_EDIT_XPT, IDC_EDIT_YPT, и IDC_EDIT_ZPT ресурсов добавляют, что средство
управления CEDIT вызвало m_ctrlAngleEdit, m_ctrlXPtEdit, m_ctrlYPtEdit, и m_ctrlZPtEdit, соответственно.
5 Для IDC_LIST_BLOCKS ресурса добавляют, что управление CLISTBOX вызвало m_ctrlBlockList.
6 Для IDC_COMBO_REGAPPS ресурса добавляют, что управление CCOMBOBOX вызвало
m_ctrlRegAppComboBox.
7 Теперь открывают AsdkAcUiDialogSample.h файл заголовка и заменяют образование из нового диалогового
класса. Это должно быть получено из CACUIDIALOG:

class AsdkAcUiDialogSample : public CAcUiDialog

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();

Создайте Обработчики для Диалога


1 Возвращаются в ClassWizard и выбирают позицию табуляции Message Maps.
2 Высвечивают объект AsdkAcUiDialogSample ИДЕНТИФИКАТОР и добавляют функцию для WM_INITDIALOG.
Тогда выберите код редактирования, чтобы брать Вас в AsdkAcUiDialogSample.cpp исходный файл.
3 Изменяют{*заменяют*} родителя ОнИнитДиалога, чтобы быть CACUIDIALOG:
CAcUiDialog:: OnInitDialog ();
4 Изменяют{*заменяют*} конструктор, чтобы также инициализировать CACUIDIALOG:

AsdkAcUiDialogSample::AsdkAcUiDialogSample
(CWnd* pParent /*=NULL*/)
: CAcUiDialog(AsdkAcUiDialogSample::IDD, pParent)

Следующий шаг должен добавить обработчики сообщения для IDC_BUTTON_ANGLE,


IDC_BUTTON_POINT, IDC_COMBO_REGAPPS, IDC_EDIT_ANGLE, и IDC_OK ресурсы. Использование
ClassWizard, добавьте обработчики, отображенные следующим образом:

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

Добавьте Код к Обработчикам


Как только Вы добавили обработчики, Вы готовы добавить код, чтобы иметь дело с вашим диалогом. Этот
раздел суммирует то, что каждый обработчик делает с законченной распечаткой.
1 Сначала мы добавляем несколько сервисных функций, чтобы конвертировать{*преобразовывать*},
отображать, и проверить правильность значений.
Примечание мы использует CACUINUMERIC и средство управления CACUIANGLEEDIT, чтобы делать это:

// 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, и наконец или отменять или
восстанавливать изображение диалога, основанного на как выбранный пользователь:

// AsdkAcUiDialogSample обработчики сообщения


void AsdkAcUiDialogSample::OnButtonPoint()
{
// Hide the dialog and give control to the editor
//
BeginEditorCommand();
ads_point pt;
// Get a point
//
if (acedGetPoint(NULL, "\nPick a point: ", pt) == RTNORM) {
// If the point is good, continue
//
CompleteEditorCommand();
m_strXPt.Format("%g", pt[X]);
m_strYPt.Format("%g", pt[Y]);
m_strZPt.Format("%g", pt[Z]);
DisplayPoint();
} else {
// otherwise cancel the command (including the dialog)
CancelEditorCommand();
}
}

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();
}
}

5 Теперь обработчики окна редактирования осуществлены. В основном мы только хотим


конвертировать{*преобразовать*} значения к текущим параметрам настройки Модулей:

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();
}

8 Наконец, OnInitDialog () функция заботится о всей инициализации, включая изменение размеров и


требования постоянства данных:

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
}

Глава 9. Наборы выборов, примитивы и функции


таблиц идентификаторов
Глобальные функции, описанные в этой главе обрабатывают наборы выбора, рисуют примитивы и таблицы
идентификаторов. См. Руководство Настройки AutoCAD для основной информации на этих темах.
 Набор выборов и имена примитивов
 Обработка Наборов Выбора
 Имя Примитива и Функции Данных
 Доступ Таблицы идентификаторов

112
Набор Выборов и имена Примитива
Большинство функций ObjectARX, которые обрабатывают наборы выбора и примитивы,
идентифицирует{*выделяет*} набор или примитив его именем, которое является парой longs, назначенного и
поддерживаемого AutoCAD. В ObjectARX, названия{*имена*} наборов выбора и примитивов имеют
соответствующий тип ads_name.
Прежде, чем это может управлять набором выборов или примитивом, приложение ObjectARX должно
получить текущее имя набора или примитива, вызывая одну из библиотечных функций, который возвращает
набор выборов или имя примитива.
ОБРАТИТЕ ВНИМАНИЕ на набор Выборов, и названия{*имена*} примитива энергозависимы; они
применяются только, в то время как Вы работаете над рисунком к AutoCAD, и они потеряны при выходе от
AutoCAD или переключения к другому рисунку.
Для наборов выбора, которые также применяются только к текущему сеансу, энергозависимость
названий{*имен*} не излагает никакую проблему, но для примитивов, которые сохранены в базе данных
рисунка, это делает. Приложение, которое должно обратиться{*отнестись*} в разное время к тем же самым
примитивам в том же самом рисунке (или рисунки), может использовать маркеры{*дескрипторы*} примитива,
описанные в “ Маркеры{*дескрипторы*} Примитива и Их Использования ” на странице 216.

Обработка Наборов Выбора


Функции ObjectARX, которые обрабатывают наборы выбора, подобны тем в AutoLISP. AcedSSGet () функция
обеспечивает большинство общих средств создания набора выборов. Это создает набор выборов способом
из трех путей:
 Подсказка пользователя, чтобы выбрать объекты.
 Явно определяющий примитивы, чтобы выбрать, используя набор PICKFIRST или Пересечение,
Многоугольник Пересечения, Заграждающую метку, Последнюю{*прошлую*}, Предыдущую, Окно, или
опции Window Polygon (как в интерактивном использовании AutoCAD), или, определяя одиночную
точку или заграждающую метку точек.
 Фильтрация базы данных текущего рисунка, определяя список атрибутов и условий, которым
выбранные примитивы должны соответствовать. Вы можете использовать фильтры с любой из
предыдущих опций.

int
acedSSGet (
const char *str,
const void *pt1,
const void *pt2,
const struct resbuf *entmask,
ads_name ss);

Первый параметр к acedSSGet () - строка, которая описывает которые опции выбора использовать, как
получено в итоге в следующей таблице.

Selection options for acedSSGet


Selection Code Description
NULL Single-point selection (if pt1 is specified) or user
selection (if pt1 is also NULL)
# Nongeometric (all, last, previous)
:$ Prompts supplied
. User p ick
:? Other callbacks
A All
B Box
C Crossing
CP Crossing Polygon
:D Duplicates OK
:E Everything in aperture
F Fence
G Groups
I Implied
:K Keyword callbacks
L Last
M Multiple
P Previous
:S Force single object selection only
W Window
WP Window Polygon
X Extended search (search whole database)

Следующие два параметра определяют значения точки для уместных опций. (Они должны быть NULL, если
они не применяются.) Если четвертый параметр, entmask, - не NULL, это указывает на список значений поля
примитива, используемых в фильтрации. Пятый параметр, ss, идентифицирует имя набора выбора.

113
Следующий код показывает представителю, вызывает к acedSSGet (). Как acutBuildList () запрос
иллюстрирует, для “CP” опций многоугольника, и “ПОДГОТОВКА ТЕКСТОВ” (но не для “F”), acedSSGet ()
автоматически закрывает список точек. Вы не должны формировать список, который определяет конечную
точку, идентичную первому.

ads_point pt1, pt2, pt3, pt4;


struct resbuf *pointlist;
ads_name ssname;
pt1[X] = pt1[Y] = pt1[Z] = 0.0;
pt2[X] = pt2[Y] = 5.0; pt2[Z] = 0.0;

// Get the current PICKFIRST set, if there is one;


// otherwise, ask the user for a general entity selection.
acedSSGet(NULL, NULL, NULL, NULL, ssname);

// Get the current PICKFIRST set, if there is one.


acedSSGet("I", NULL, NULL, NULL, ssname);

// Selects the most recently selected objects.


acedSSGet("P", NULL, NULL, NULL, ssname);

// Selects the last entity added to the database.


acedSSGet("L", NULL, NULL, NULL, ssname);

// Selects entity passing through point (5,5).


acedSSGet(NULL, pt2, NULL, NULL, ssname);

// Selects entities inside the window from (0,0) to (5,5).


acedSSGet("W", pt1, pt2, NULL, ssname);

// Selects entities enclosed by the specified polygon.


pt3[X] = 10.0; pt3[Y] = 5.0; pt3[Z] = 0.0;
pt4[X] = 5.0; pt4[Y] = pt4[Z] = 0.0;
pointlist = acutBuildList(RTPOINT, pt1, RTPOINT, pt2,
RTPOINT, pt3, RTPOINT, pt4, 0);
acedSSGet("WP", pointlist, NULL, NULL, ssname);

// Selects entities crossing the box from (0,0) to (5,5).


acedSSGet("C", pt1, pt2, NULL, ssname);

// Selects entities crossing the specified polygon.


acedSSGet("CP", pointlist, NULL, NULL, ssname);
acutRelRb(pointlist);

// Selects the entities crossed by the specified fence.


pt4[Y] = 15.0; pt4[Z] = 0.0;
pointlist = acutBuildList(RTPOINT, pt1, RTPOINT, pt2,
RTPOINT, pt3, RTPOINT, pt4, 0);
acedSSGet("F", pointlist, NULL, NULL, ssname);
acutRelRb(pointlist);

Дополнение acedSSGet () - acedSSFree (), который выпускает набор выборов, как только приложение
закончило использовать это. Набор выборов определен по имени. Следующий кодовый фрагмент использует
ads_name объявление от предыдущего примера.

acedSSFree(ssname);

ПРИМЕЧАНИЕ AutoCAD не может иметь больше чем 128 наборов выбора, открытые сразу. Этот предел
включает наборы выбора, открытые всего одновременно выполняющиеся приложения ObjectARX и AutoLISP.
Предел может быть отличен на вашей системе. Если предел достигнут, AutoCAD отказывается создавать
большее количество наборов выбора. Одновременно управление большим количеством наборов выбора не
рекомендуется. Вместо этого, сохраните разумное число наборов, открытых в любое данное время, и
вызовите acedSSFree () чтобы освободить неиспользованные наборы выбора как можно скорее. В отличие от
AutoLISP, ObjectARX среда не имеет никакой автоматической сборки "мусора", чтобы освободить наборы
выбора после того, как они использовались. Приложение должно всегда освобождать его открытые наборы
выбора, когда это получает kUnloadDwgMsg, kEndMsg, или kQuitMsg сообщение.

Списки Фильтра Набора Выбора


Когда entmask параметр определяет, что список значений поля примитива, acedSSGet () просматривает
выбранные примитивы и создает набор выборов, содержащий названия{*имена*} всех основных примитивов,
которые соответствуют{*согласовывают*} указанным критериям. Например, используя этот механизм, Вы
можете получить набор выборов, который включает все примитивы данного типа, на данном уровне, или
данного цвета.

114
Вы можете использовать фильтр вместе с любой из опций выбора. Опция “X” говорит, что создала набор
выборов, используя только фильтрация; как в предыдущих версиях AutoCAD, если Вы используете, опция “X”,
acedSSGet () просматривает полную базу данных рисунка.

ОБРАТИТЕ ВНИМАНИЕ, определена ли только фильтрация (“X”) но entmask параметр - NULL, acedSSGet ()
выбирает все примитивы в базе данных.

Entmask параметр должен быть список буфера результата. Каждый буфер определяет свойство, чтобы
проверить{*отметить*} и значение, которое составляет соответствие; restype поле буфера - код группы DXF,
который указывает вид свойства, чтобы смотреть для, и его resval поле определяет значение, чтобы
соответствовать{*согласовать*}.
Следующее - некоторые примеры.

struct resbuf eb1, eb2, eb3;


char sbuf1[10], sbuf2[10]; // Buffers to hold strings
ads_name ssname1, ssname2;

eb1.restype = 0;// Entity name


strcpy(sbuf1, "CIRCLE");
eb1.resval.rstring = sbuf1;
eb1.rbnext = NULL; // No other properties

// Retrieve all circles.


acedSSGet("X", NULL, NULL, &eb1, ssname1);
eb2.restype = 8; // Layer name
strcpy(sbuf2, "FLOOR3");
eb2.resval.rstring = sbuf2;
eb2.rbnext = NULL; // No other properties

// Retrieve all entities on layer FLOOR3.


acedSSGet("X", NULL, NULL, &eb2, ssname2);

ОБРАТИТЕ ВНИМАНИЕ resval, указанный в каждом буфере должен иметь соответствующий тип.
Например, типы имени - строки (resval.rstring); повышение и толщина - с двойной точностью с плавающей
точкой значения (resval.rreal); цвет, признаки - следуйте, и пометьте значения - короткие целые числа
(resval.rint); векторы вытеснения - трехмерные точки (resval.rpoint); и т.д.

Если entmask определяет больше чем одно свойство, примитив включен в выбор, устанавливают только, если
это соответствует всем указанным условиям{*состояниям*}, как показано в следующем примере:

eb3.restype = 62; // Entity color


eb3.resval.rint = 1; // Request red entities.
eb3.rbnext = NULL; // Last property in list

eb1.rbnext = &eb2; // Add the two properties


eb2.rbnext = &eb3; // to form a list.

// Retrieve all red circles on layer FLOOR3.


acedSSGet("X", NULL, NULL, &eb1, ssname1);

Примитив проверен против всех полей, указанных в списке фильтрации, если список не содержит
относительные или условные операторы, как описано в “ Относительные Испытания ” на странице 207 и “
Фильтрация Условного выражения ” на странице 208.

AcedSSGet () функциональные возвращения RTERROR, если никакие примитивы в базе данных не


соответствуют{*согласовывают*} указанным критериям фильтрации.
Предыдущий acedSSGet () примеры используют опцию “X”, которая просматривает полную базу данных
рисунка. Если списки фильтра используются вместе с другими опциями (выбор пользователя, окно, и т.д),
фильтр применяется только к примитивам, первоначально выбранным.
Следующее - пример фильтрации выбранных пользователем примитивов.

eb1.restype = 0; // Entity type group


strcpy(sbuf1, "TEXT");
eb1.resval.rstring = sbuf1; // Entity type is text.
eb1.rbnext = NULL;

// Ask the user to generally select entities, but include


// only text entities in the selection set returned.
acedSSGet(NULL, NULL, NULL, &eb1, ssname1);

Следующий пример демонстрирует фильтрацию предыдущего набора выборов.

eb1.restype = 0; // Entity type group

115
strcpy(sbuf1, "LINE");
eb1.resval.rstring = sbuf1; // Entity type is line.
eb1.rbnext = NULL;

// Select all the lines in the previously created selection set.


acedSSGet("P", NULL, NULL, &eb1, ssname1);

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 () - тот же самый как признанные функцией
acutWcMatch ().

Следующий типовой код отыскивает анонимный блок, названный *U2.

eb2.restype = 2; // Block name


strcpy(sbuf1, "’*U2"); // Note the reverse quote.
eb2.resval.rstring = sbuf1; // Anonymous block name
eb2.rbnext = NULL;

// Select Block Inserts of the anonymous block *U2.


acedSSGet("X", NULL, NULL, &eb2, ssname1);

Фильтрация для Расширенных Данных


Расширенные данные (xdata) - текстовые строки, числовые значения, трехмерные точки, расстояния,
названия уровня, или другие данные, приложенные к объекту, типично внешним приложением.
Размер расширенных данных - байты 16КБ.
Вы можете отыскивать расширенные данные для специфического приложения, определяя его имя
в списке фильтра, используя -3 код группы. AcedSSGet () функциональные примитивы
возвращений с расширенными данными, зарегистрированными к указанному имени; acedSSGet ()
не отыскивает индивидуума, расширил элементы данных (с кодами группы в диапазоне 1000-
2000).
Следующий типовой кодовый фрагмент выбирает все круги, которые расширили данные,
зарегистрированные на приложение, чей ИДЕНТИФИКАТОР - “APPNAME”.

eb1.restype = 0; // Entity type


strcpy(sbuf1, "CIRCLE");
eb1.resval.rstring = sbuf1; // Circle
eb1.rbnext = &eb2;

eb2.restype = -3; // Extended data


eb2.rbnext = &eb3;
eb3.restype = 1001;
strcpy(sbuf2, "APPNAME");
eb3.resval.rstring = sbuf2; // APPNAME application
eb3.rbnext = NULL;

// Select circles with XDATA registered to APPNAME.


acedSSGet("X", NULL, NULL, &eb1, ssname1);

Если больше чем одно прикладное имя включены в список, acedSSGet () включает примитив в
выбор, устанавливают только, если это расширило{*продлило*} данные для всех указанных
приложений. Например, следующий код выбирает круги расширенными{*продленными*} данными,
зарегистрированными к “APP1” и “APP2”.

eb1.restype = 0; // Entity type


strcpy(sbuf1, "CIRCLE");

116
eb1.resval.rstring = sbuf1; // Circle
eb1.rbnext = &eb2;

eb2.restype = -3; // Extended data


eb2.rbnext = &eb3;
eb3.restype = 1001;
strcpy(sbuf2, "APP1");

eb2.resval.rstring = sbuf2; // APP1 application


eb2.rbnext = &eb4;
eb4.restype = 1001; // Extended data
strcpy(sbuf3, "APP2");
eb4.resval.rstring = sbuf3; // APP2 application
eb4.rbnext = NULL;

// Select circles with XDATA registered to APP1 & APP2.


acedSSGet("X", NULL, NULL, &eb1, ssname1);

Вы можете определить прикладные названия, использующие строки подстановочных знаков, так


что Вы можете искать данные множественных приложений в одно время. Например, следующий
код выбирает все круги расширенными данными, зарегистрированными к “APP1” или “APP2” (или
оба).

eb1.restype = 0; // Entity type


strcpy(sbuf1, "CIRCLE");
eb1.resval.rstring = sbuf1; // Circle
eb1.rbnext = &eb2;

eb2.restype = -3; // Extended data


eb2.rbnext = &eb3;
eb3.restype = 1001; // Extended data
strcpy(sbuf2, "APP1,APP2");
eb3.resval.rstring = sbuf2; // Application names
eb3.rbnext = NULL;

// Select circles with XDATA registered to APP1 or APP2.


acedSSGet("X", NULL, NULL, &eb1, ssname1);

Следующая строка находит расширенные данные того же самого приложения.

strcpy(sbuf2, "APP[12]");

Относительные Испытания
Если Вы не определяете иначе, имеется подразумеваемый ", “равняется" испытанию между примитивом и
каждым элементом{*пунктом*} в списке фильтра. Для числовых групп (целые числа, реальные значения,
точки, и векторы), Вы можете определить другие отношения включением относительных операторов в списке
фильтра. Относительные операторы пропускают как специальные -4 группа, чей значение - строка, которая
указывает испытание, которое нужно применить к следующей группе в списке фильтра.

Следующий типовой код выбирает все круги, чей радиус больший чем или равняются 2.0:

eb3.restype = 40; // Radius


eb3.resval.rreal = 2.0;
eb3.rbnext = NULL;
eb2.restype = -4; // Filter operator
strcpy(sbuf1, ">=");
eb2.resval.rstring = sbuf1; // Greater than or equals
eb2.rbnext = &eb3;
eb1.restype = 0; // Entity type
strcpy(sbuf2, "CIRCLE");
eb1.resval.rstring = sbuf2; // Circle
eb1.rbnext = &eb2;
// Select circles whose radius is >= 2.0.
acedSSGet("X", NULL, NULL, &eb1, ssname1);

Условная Фильтрация
Относительные операторы, только описанные - двоичные операторы. Вы можете также проверять группы,
создавая вложенные выражения 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);

Условные операторы не чувствительны к регистру; Вы можете использовать эквиваленты нижнего регистра.

ОБРАТИТЕ ВНИМАНИЕ на выражения Conditional, которые проверяют на расширенные данные,


использующие -3 группа, может содержать только -3 группы. См. “ Фильтрующий для Расширенных Данных ”
на странице 206.

К выделите всё кругам, которые расширили{*продлили*} данные, зарегистрированные или на “APP1” или
“APP2”, но не оба, Вы могли использовать следующий код.

eb1 = acutBuildList(-4, "<xor", -3, "APP1", -3, "APP2", -4, "xor>", 0);
acedSSGet("X", NULL, NULL, &eb1, ssname1);

Манипуляция наборами выборов


Вы можете добавлять примитивы к набору выборов или удалять их из этого, вызывая функции acedSSAdd ()
и acedSSDel (), которые являются подобными опциям Add и Remove, когда AutoCAD в интерактивном режиме
запрашивает пользователя выбирать объекты или удалять объекты.

ОБРАТИТЕ ВНИМАНИЕ На acedSSAdd () функция может также использоваться, чтобы создать новый набор
выборов, как показано в следующем примере. Как с acedSSGet (), acedSSAdd () создает новый выбор,
устанавливают только, если это возвращает RTNORM.

Следующий типовой кодовый фрагмент создает набор выборов, который включает первые и последние
примитивы в текущий рисунок.

ads_name fname, lname; // Entity names


ads_name ourset; // Selection set name
// Get the first entity in the drawing.
if (acdbEntNext(NULL, fname) != RTNORM) {
acdbFail("No entities in drawing\n");
return BAD;
}
// Create a selection set that contains the first entity.
if (acedSSAdd(fname, NULL, ourset) != RTNORM) {
acdbFail("Unable to create selection set\n");
return BAD;
}
// Get the last entity in the drawing.
if (acdbEntLast(lname) != RTNORM) {
acdbFail("No entities in drawing\n");
return BAD;
}
// Add the last entity to the same selection set.
if (acedSSAdd(lname, ourset, ourset) != RTNORM) {
acdbFail("Unable to add entity to selection set\n");
return BAD;
}

Пример выполняется правильно, даже если имеется только один примитив в базе данных (когда и
acdbEntNext () и acdbEntLast () устанавливают их параметры в то же самое имя примитива). Если acedSSAdd
() пропускают имя примитива, который является уже в наборе выборов, это игнорирует запрос и не сообщает
о ошибке.
Поскольку пример также иллюстрирует, вторые и третьи параметры к acedSSAdd () можно пропускать как то
же самое имя набора выбора. То есть если запрос успешен, набор выборов, названный обоими параметрами
содержит дополнительного члена после acedSSAdd () возвращения (если указанный примитив не был уже в
наборе выборов).
Следующий запрос удаляет примитив, с которым выбором установленный был создан в предыдущем
примере.

AcedSSDel (fname, ourset);

Если имеются больше чем один примитив в рисунке (то есть если fname и lname не равны), выбор
устанавливает ourset, теперь содержит только lname, последний{*прошлый*} примитив в рисунке.
Функция acedSSLength () возвращает число примитивов в наборе выборов, и acedSSMemb ()
испытания,является ли специфический примитив членом набора выборов. Наконец, функция acedSSName ()
возвращает имя специфического примитива в наборе выборов, используя индекс в набор (примитивы в
наборе выборов пронумерованы от 0).

118
ОБРАТИТЕ ВНИМАНИЕ, поскольку наборы выбора могут быть весьма большие, len параметр, возвращенный
acedSSLength () должен быть объявлен как длинное целое число. Я параметр, используемый как индекс в
звонит к acedSSName () должен также быть длинное целое число. (В этом контексте, стандартные
компиляторы C правильно преобразуют простое целое число.)

Следующий типовой код показывает несколько, вызывает к acedSSName ().

ads_name sset, ent1, ent4, lastent;


long ilast;
// Create the selection set (by prompting the user).
acedSSGet(NULL, NULL, NULL, NULL, sset);
// Get the name of first entity in sset.
if (acedSSName(sset, 0L, ent1) != RTNORM)
return BAD;
// Get the name of the fourth entity in sset.
if (acedSSName(sset, 3L, ent4) != RTNORM) {
acdbFail("Need to select at least four entities\n");
return BAD;
}
// Find the index of the last entity in sset.
if (acedSSLength(sset, &ilast) != RTNORM)
return BAD;
// Get the name of the last entity in sset.
if (acedSSName(sset, ilast-1, lastent) != RTNORM)
return BAD;

Преобразование Наборов Выбора


Функция acedXformSS () преобразовывает выбор, установленный, применяя матрицу
преобразования (типа ads_matrix) к примитивам в наборе. Это обеспечивает эффективную
альтернативу к вызову ВРАЩАЮЩЕГОСЯ, МАСШТАБУ, ЗЕРКАЛУ, или командам ПЕРЕМЕЩЕНИЯ
с acedCommand () (или acedCmd ()) или к изменению{*замене*} значений в базе данных с
acdbEntMod (). Набор выборов может быть получен способом из обычных путей. Матрица должна
делать однородное масштабирование. То есть элементы в векторе масштабирования S X S Y S Z
должны весь быть равными; в матричном примечании, М. 00 М. 11 М. 22.
Если вектор масштаба - не, униформа, acedXformSS () сообщает о ошибке.
Следующий типовой код устанавливает выбор, используя поле пересечения, и затем применяет следующую
матрицу к этому.
| 0.5 0.0 0.0 20.0 |
| 0.0 0.5 0.0 5.0 |
| 0.0 0.0 0.5 0.0 |
| 0.0 0.0 0.0 1.0 |

Применение{*обращение*} этой матрицы масштабирует примитивы половиной (который перемещает их к


началу координат) и транслирует их местоположение (20.0,5.0).

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 dragsample(usrpt, matrix)


ads_point usrpt
ads_matrix matrix;
{
ident_init(matrix); // Initialize to identity.
// Initialize translation vector.
matrix[0][T] = usrpt[X];
matrix[1][T] = usrpt[Y];
matrix[2][T] = usrpt[Z];
return RTNORM; // Matrix was modified.
}

Наоборот, следующая версия dragsample () масштабирует набор выборов в текущем XY плане, но не


перемещает это.

int dragsample(usrpt, matrix)


ads_point usrpt
ads_matrix matrix;
{
ident_init(matrix); // Initialize to identity.
matrix[0][0] = userpt[X];
matrix[1][1] = userpt[Y];
return RTNORM; // Matrix was modified.
}

Запрос к 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)
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

Более сложные преобразования могут вращать примитивы, комбинировать{*объединять*} преобразования


(как в acedXformSS () пример), и т.д.
Объединение матриц преобразования известно как матричный состав. Следующая функция составляет две
матрицы преобразования, возвращая их изделие{*программу*} в resmat.

void xformcompose(ads_matrix xf1, ads_matrix xf2,


ads_matrix resmat)
{
int i, j, k;
ads_real sum;
for (i=0; i<=3; i++) {
for (j=0; j<=3; j++) {
sum = 0.0;
for (k=0; k<3; k++) {
sum += xf1[i,k] * xf2[k,j];
}
resmat[i,j] = sum;
}
}
}

Имя Примитива и Функции Данных


Обрабатывающие примитив функции организованы в две категории: функции, которые
восстанавливают{*отыскивают*} имя специфического примитива и функций, которые
восстанавливают{*отыскивают*} или изменяют данные примитива.

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 () функция восстанавливает{*отыскивает*} названия{*имена*} примитива последовательно. Если


его первый параметр - NULL, это возвращает имя первого примитива в базе данных рисунка; если его первый
параметр - имя примитива в текущем рисунке, это возвращает имя преуспевающего примитива.
Следующий типовой кодовый фрагмент иллюстрирует, как acedSSAdd () может использоваться вместе с
acdbEntNext () чтобы создать наборы выбора и добавлять членов к существующему набору.

Ads_name ss, e1, e2;


// Set e1 to the name of first entity.
if (acdbEntNext(NULL, e1) != RTNORM) {
acdbFail("No entities in drawing\n");
return BAD;
}
// Set ss to a null selection set.
acedSSAdd(NULL, NULL, ss);
// Return the selection set ss with entity name e1 added.
if (acedSSAdd(e1, ss, ss) != RTNORM) {
acdbFail("Unable to add entity to selection set\n");
return BAD;
}
// Get the entity following e1.
if (acdbEntNext(e1, e2) != RTNORM) {
acdbFail("Not enough entities in drawing\n");
return BAD;
}
// Add e2 to selection set ss
if (acedSSAdd(e2, ss, ss) != RTNORM) {
acdbFail("Unable to add entity to selection set\n");
return BAD;
}

Следующий типовой кодовый фрагмент использует acdbEntNext () чтобы “идти” через базу данных, один
примитив одновременно.

ads_name ent0, ent1;


struct resbuf *entdata;
if (acdbEntNext(NULL, ent0) != RTNORM) {
acdbFail("Drawing is empty\n");
return BAD;
}
do {
// Get entity’s definition data.
entdata = acdbEntGet(ent0);
if (entdata == NULL) {
acdbFail("Failed to get entity\n");
return BAD;
}
.
. // Process new entity.
.
if (acedUsrBrk() == TRUE) {
acdbFail("User break\n");
return BAD;
}
acutRelRb(entdata); // Release the list.

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.

Метки примитива и их использования


AcdbHandEnt () функция отыскивает имя примитива с определенной меткой. Подобно именам примитива,
метки уникальны в пределах рисунка. В отличие от имен примитива, метка примитива постоянна повсюду его
жизни. ObjectARX приложения, которые управляют определенной базой данных, могут использовать
acdbHandEnt () чтобы получить текущее имя примитива, который они должны использовать.
Следующий типовой кодовый фрагмент использует acdbHandEnt () чтобы получить имя примитива и
распечатывать это.

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 ().

Примитивы в рисунках перекрестно ссылались с внешних ССЫЛОК, присоединяются не фактически часть


текущего рисунка; их метки неизменны, и нельзя обращаться acdbHandEnt (). Однако, когда рисунки
объединены посредством ВСТАВКИ, ВСТАВЬТЕ *, XREF Связывает (XBIND), или частичный DXFIN, метки
примитивов в рисунке прихода потеряны, и входящие примитивы назначены новые значения
маркера{*дескриптора*} гарантировать, что каждый маркер{*дескриптор*} в рисунке оригинала остается
уникальным.

ОБРАТИТЕ ВНИМАНИЕ, что расширенные данные могут включать метки примитива, чтобы сохранить
относительные структуры в рисунке. В некоторых обстоятельствах, эти метки требуют трансляции или
обслуживания. См. “ Использование метки в Расширенных Данных ” на странице 240.

Контекст примитива и координатное преобразовывание данных


AcedNEntSelP () функция подобна acedEntSel (), за исключением того, что это передает два дополнительных
параметра результата, чтобы облегчить обработку примитивов, которые вложены в пределах блок-ссылок.

ОБРАТИТЕ ВНИМАНИЕ На другое различие между 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 М01 М02 М03 X


Y’ = М10 М11 М12 М13 x Y
Z’ М20 М21 М22 М23 Z
1.0 0.0 0.0 0.0 1.0 1.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.

Индивидуальные координаты преобразованной точки получены от уравнений, где М. mn - Модель к Мировой


Матрице преобразования, координирует, (X, Y, Z) - точка данных определения примитива, выраженная в
координатах MCS, и (X ’, Y ’, Z ’) - заканчивающаяся точка данных определения примитива, выраженная в
координатах WCS. См. “ Матрицы Преобразования ” на странице 535.

ПРИМЕЧАНИЕ, чтобы преобразовать вектор скорее чем точка, не добавьте вектор сдвига [М. 03 М. 13 М. 23]
(от четвертого столбца матрицы преобразования).
Следующий типовой код определяет функцию, mcs2wcs (), который исполняет преобразования, описанные
предшествующими уравнениями. Требуется матрица преобразования, возвращенная acedNEntSelP () и
одиночной точкой (возможно от данных определения вложенного примитива), и возвращает
оттранслированную точку.

Если третий параметр к mcs2wcs (), is_pt, установлен в 0 (ЛЖИ), последний столбец матрицы преобразования
— вектор сдвига, или смещение — не добавлено к результату. Это дает возможность функции транслировать
вектор также как точку.

void mcs2wcs(xform, entpt, is_pt, worldpt)


ads_matrix xform;
ads_point entpt, worldpt;
int is_pt;
{
int i, j;
worldpt[X] = worldpt[Y] = worldpt[Z] = 0.0;
for (i=X; i<=Z; i++)
for (j=X; j<=Z; j++)
worldpt[i] += xform[i][j] * entpt[j];
if (is_pt) // If it’s a point, add in the displacement
for (i=X; i<=Z; i++)
worldpt[i] += xform[i][T];
}

Следующий кодовый фрагмент показывает, как mcs2wcs () мог бы использоваться в конъюнкции с


acedNEntSelP () чтобы транслировать значения точки в поток WCS.

ads_name usrent, containent;


ads_point usrpt, defpt, wcspt;
ads_matrix matrix;
struct resbuf *containers, *data, *rb, *prevrb;
status = acedNEntSelP(NULL, usrent, usrpt, FALSE, matrix,
&containers);
if ((status != RTNORM) || (containers == NULL))
return BAD;
data = acdbEntGet(usrent);
// Extract a point (defpt) from the data obtained by calling

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);

AcedNEntSel () функция обеспечивается для совместимости с существующими ObjectARX-приложениями.


Новые приложения должны быть написаны, используя acedNEntSelP ().

Модель к Мировой Матрице преобразования, возвращенной запросом к acedNEntSel () имеет ту же самую


цель как возвращенное acedNEntSelP (), но это - 4x3, матрица — прошла как массив четырех точек —,
который использует соглашение, что точка - строка скорее чем столбец. Преобразование описано следующим
матричным умножением:

М00 М01 М02 М03


X' Y' Z' 1.0 = X Y Z 1.0 x М10 М11 М12 М13
М20 М21 М22 М23
0.0 0.0 0.0 1.0

Хотя матричный формат различен, формулы эквивалентны, те для типа ads_matrix, и единственного
изменения{*замены*}, требуемого, чтобы приспособить mcs2wcs () для использования с acedNEntSel ()
должны объявить матричный параметр как массив четырех точек.

void mcs2wcs(xform, entpt, is_pt, worldpt);


ads_point xform[4]; // 4x3 version
ads_point entpt, worldpt;
int is_pt;

Форма тождества 4x3 матрица следующие:

1 0 0
0 1 0
0 0 1
0 0 0

В дополнение к использованию различного матричного соглашения, acedNEntSel () не позволяет программе


определять точку указки.

Контекстные Данные
Функция acedNEntSelP () обеспечивает параметр для контекстных данных, refstkres. (Это - другая
особенность, не обеспеченная acedEntSel ()). Refstkres параметр - указатель на список связей буферов
результатов, который содержит названия{*имена*} контейнерных блоков примитива. Список
заказывается{*упорядочивает*} от самого низкого до самого высокого. Другими словами, имя в списке - имя
блока, содержащего выбранный примитив, и фамилия в списке - имя блока, который был непосредственно
вставлен в рисунок. Следующий рисунок показывает формат этого списка.

124
Если выбранный примитив entres - не, вложенный примитив, refstkres - указатель NULL. Это - удобный способ
проверить, действительно ли координаты примитива должны быть оттранслированы. (Поскольку xformres
возвращен как единичная матрица для примитивов, которые не вложены, применяя это к координатам таких
примитивов не никакой вред, но стоит некоторое бесполезное время выполнения.)
Используя объявления от предыдущего acedNEntSelP () пример, имя блока, который немедленно содержит
выбранный пользователем примитив, может быть найден следующим кодом (в acedNEntSelP () запрос,
pickflag параметр - FALSE для интерактивного выбора).

status = acedNEntSelP(NULL, usrent, usrpt, FALSE, matrix,


&containers);
if ((status != RTNORM) || (containers == NULL))
return BAD;
containent[0] = containers->resval.rlname[0];
containent[1] = containers->resval.rlname[1];

Имя наиболее удаленного контейнера (то есть примитив, первоначально вставленный в рисунок) может быть
найдено последовательностью типа следующего:

// Проверить это, контейнеры не уже NULL.


rb = containers;
while (rb != NULL) {
prevrb = rb;
rb = containers->rbnext;
}
// Буфер результатов, указанный prevrb теперь содержит имя наиболее удаленного блока.

В следующем примере, текущая система координат - 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

Тогда вставьте блок в UCS, вращал 45 градусов относительно Z оси.

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

ads_nentselp() result ads_nentsel() result

Функции Данных Примитива


Некоторые функции работают на данных примитива и могут использоваться, чтобы изменить базу данных
текущего рисунка. AcdbEntDel () функция удаляет указанный примитив. Примитив не очищен от базы данных,
пока Вы не оставляете текущий рисунок.
Так, если приложение вызывает acdbEntDel () второй раз в течение того сеанса и определяет тот же самый
примитив, примитив восстановлен. (Вы можете использовать acdbHandEnt () чтобы восстановить{*отыскать*}
названия{*имена*} удаленных примитивов.)

ОБРАТИТЕ ВНИМАНИЕ На использование acdbEntDel (), атрибуты, и вершина ломаной линии не может быть
удалена независимо от их родительских примитивов; acdbEntDel () работает только на основных примитивах.
Чтобы удалять атрибут или вершину, используйте acedCommand () или acedCmd () чтобы вызвать AutoCAD
ATTEDIT или команды PEDIT, используйте acdbEntMod () чтобы переопределить примитив без нежелательных
подпримитивов, или откройте вершину, или припишите, и используйте ее стирание () метод стереть это.

AcdbEntGet () функция возвращает данные определения указанного примитива.


Данные возвращены как список связей буферов результатов. Тип каждого элемента (буфер) в списке
определен кодом группы DXF. Первый элемент в списке содержит текущее имя примитива (restype == -1).
ObjectARX-приложение могло отыскивать и печатать данные определения для примитива,
используя следующий две функции. (Printdxf () функция не обрабатывает расширенные данные.)

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;
}

В следующем примере, следующие (заданные по умолчанию) условия{*состояния*} обращаются к текущему


рисунку.
 текущий уровень - 0
 linetype - НЕПРЕРЫВЕН
 текущее повышение - 0
 маркеры примитива заблокированы
Также, пользователь рисовал линию со следующей последовательностью команд:

Command: line
From point: 1,2
To point: 6,6
To point: ENTER

Тогда запрос к getlast () печатал бы следующий (значение имени изменится).


Результат выполнения acdbEntGet () для последнего примитива:

(-1 . <Entity name: 60000014>)


(0 . "LINE")
(8 . "0")
(10 1.0 2.0 0.0)
(11 6.0 6.0 0.0)
(210 0.0 0.0 1.0)

ОБРАТИТЕ ВНИМАНИЕ На printdxf () функция печатает вывод в формате ассоциативного списка


AutoLISP, но элементы сохранены в списке связей буферов результатов.

Буфер результатов в начале списка (с -1 кодом стража) содержит имя примитива, который этот
список представляет. AcdbEntMod () функциональные использования это, чтобы идентифицировать
примитив, который нужно изменить.
Коды для компонентов примитива (сохраненный в restype поле) - используемые DXF. Как с DXF,
элементы заголовка примитива возвращены только, если они имеют значения другие чем значение
по умолчанию. В отличие от DXF, необязательные поля определения примитива возвращены
независимо от того, равняются ли они их значениям по умолчанию. Это упрощает обработку;
приложение может всегда предполагать, что эти поля присутствуют. Также в отличие от DXF,
связанного X, Y, и координат Z возвращены как одиночная переменная точки (resval.rpoint), не как
отдельный X (10), Y (20), и Z (30) групп. Значение restype содержит номер группы координаты X (в
диапазоне 10-19).

127
Чтобы находить группу с определенным кодом, приложение может пересекать список. Entitem ()
функция, показанная здесь ищет список буфера результата группу указанного типа.

static struct resbuf *entitem(rchain, gcode)


struct resbuf *rchain;
int gcode;
{
while ((rchain != NULL) && (rchain->restype != gcode))
rchain = rchain->rbnext;
return rchain;
}

Если код группы DXF, указанный gcode параметром - не подарок{*настоящее*} в списке (или если
gcode - не, правильная{*допустимая*} группа DXF), entitem () “ уменьшается конец ” и возвращает
NULL. Обратите внимание, что entitem () эквивалентен функции AutoLISP (assoc).
AcdbEntMod () функция изменяет примитив. Это передает список, который имеет тот же самый
формат как список, возвращенный acdbEntGet (), но с некоторыми из значений группы примитива
(возможно) изменяемых приложением. Эти функциональные дополнения acdbEntGet (); первичные
средства, которыми ObjectARX-приложение модифицирует базу данных -
восстанавливая{*отыскивая*} примитив с acdbEntGet (), изменяя его список примитива, и затем
пропуская список назад к базе данных с acdbEntMod ().

ОБРАТИТЕ ВНИМАНИЕ, чтобы восстановить значение по умолчанию цвета примитива или linetype,
использовать acdbEntMod () чтобы установить цвет в 256, который является BYLAYER, или linetype
к BYLAYER.

Следующий кодовый фрагмент отыскивает данные определения первого примитива в рисунке, и


изменяет его свойство уровня к MYLAYER.
ads_name en;
struct resbuf *ed, *cb;
char *nl = "MYLAYER";
if (acdbEntNext(NULL, en) != RTNORM)
return BAD; // Error status
ed = acdbEntGet(en); // Retrieve entity data.
for (cb = ed; cb != NULL; cb = cb->rbnext)
if (cb->restype == 8) { // DXF code for Layer
// Check to make sure string buffer is long enough.
if (strlen(cb->resval.rstring) < (strlen(nl)))
// Allocate a new string buffer.
cb->resval.rstring = realloc(cb->resval.rstring,
strlen(nl) + 1);
strcpy(cb->resval.rstring, nl);
if (acdbEntMod(ed) != RTNORM) {
acutRelRb(ed);
return BAD; // Error
}
break; // From the for loop
}
acutRelRb(ed); // Release result buffer.

Управление памятью - ответственность ObjectARX-приложения.


Код в примере гарантирует, что строковый буфер - правильный размер, и это выпускает буфер
результатов, возвращенный acdbEntGet () (и прошло к acdbEntMod ()) как только операция
закончена, действительно ли запрос к acdbEntMod () преуспевает.

ОБРАТИТЕ ВНИМАНИЕ, используете ли Вы acdbEntMod () чтобы изменить примитив на блочном


определении, это воздействует на всю ВСТАВКУ или XREF к тому блоку; также, примитивы на
блочных определениях не могут быть удалены acdbEntDel ().

Приложение может также добавлять примитив к базе данных рисунка, вызывая 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;
}

И acdbEntMod () и acdbEntMake () исполняют, те же самые проверки последовательности на


данных примитива прошли к ним, поскольку команда DXFIN AutoCAD исполняет при чтении DXF
файлы. Они терпят неудачу, если они не могут создавать правильные{*допустимые*} примитивы
рисунка.

Сложные примитивы
Сложный примитив (ломаная линия или блок) должен быть создан множителем, вызывает к
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).

basept[X] = basept[Y] = basept[Z] = 0.0;


entlist = acutBuildList(
RTDXF0, "INSERT",
2, newblkname, // From acedGetInput
10, basept,
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 insert anonymous block\n");
return BAD;
}

Функции Данных Примитива и Графический Экран


Изменяется к рисунку, сделанному функциями данных примитива, отражен на графическом
экране, при условии, что удаляемый примитив, восстановлен, изменяется, или сделан, находится в
области и находится на уровне, который является в настоящее время видимым. Имеется одно
исключение: когда acdbEntMod() изменяет подпримитив, это не модифицирует изображение
сложного примитива. Причина должна быть ясна. Если, например, приложение должно было
изменить 100 вершин сложной ломаной линии с 100 выполняемый с помощью итераций, вызывает
acdbEntMod(), время, требуемое, чтобы повторно вычислять и восстановить изображение полной
ломаной линии, поскольку каждая вершина была изменена, будет неприемлемо медленно. Вместо
этого, приложение может исполнять ряд модификаций подпримитива и затем восстанавливать
изображение полного примитива с одиночным запросом к acdbEntUpd () функция.

131
В следующем примере, первый примитив в текущем рисунке - ломаная линия с несколькими вершиной.
Следующий код изменяет вторую вершину ломаной линии и затем восстанавливает его отображаемое
изображение.

ads_name e1, e2;


struct resbuf *ed, *cb;
if (acdbEntNext(NULL, e1) != RTNORM) {
acutPrintf("\nNo entities found. Empty drawing.");
return BAD;
}
acdbEntNext(e1, e2);
if ((ed = acdbEntGet(e2)) != NULL) {
for (cb = ed; cb != NULL; cb = cb->rbnext)
if (cb->restype == 10) { // Start point DXF code
cb->resval.rpoint[X] = 1.0;// Change coordinates.
cb->resval.rpoint[Y] = 2.0;
if (acdbEntMod(ed) != RTNORM) { // Move vertex.
acutPrintf("\nBad vertex modification.");
acutRelRb(ed);
return BAD;
} else {
acdbEntUpd(e1); // Regen the polyline.
acutRelRb(ed);
return GOOD; // Indicate success.
}
}
acutRelRb(ed);
}
return BAD; // Indicate failure.

Параметр acdbEntUpd() может определить или основной примитив или - tity; в любом случае, acdbEntUpd()
восстанавливает полный примитив. Хотя его первичное использование - для сложных примитивов,
acdbEntUpd() может восстанавливать любой примитив в текущем рисунке.

ОБРАТИТЕ ВНИМАНИЕ, находится ли изменяемый примитив на блочном определении, то acdbEntUpd()


функция не достаточен. Вы должны восстановить рисунок, вызывая команду REGEN AutoCAD (с acedCmd()
или acedCommand()) чтобы гарантировать, что все образцы блок-ссылок модифицированы.

Примечания относительно Расширенных Данных


Несколько функций ObjectARX обеспечиваются, чтобы обработать расширенные данные. Расширенные
данные примитива следуют за нормальными данными определения примитива. Это иллюстрировано
следующим рисунком, которое показывает схеме списка буфера результата для примитива, содержащего
расширенные данные.
Расширенные данные примитива могут быть отысканы, вызывая acdbEntGetX (), который является подобным
acdbEntGet (). AcdbEntGetX () функция отыскивает нормальные данные определения примитива и
расширенные данные для приложений, указанных в acdbEntGetX () запрос.

ОБРАТИТЕ ВНИМАНИЕ, когда расширенные данные отысканы acdbEntGetX (), начало расширенных данных
обозначено -3 кодом стража; -3 страж находится в буфере результатов, который предшествует первой 1001
группе. 1001 группа содержит прикладное имя первого отысканного приложения, как показано в рисунке.

132
Организация Расширенных Данных
Расширенные данные состоят из одного или большее количество 1001 групп, каждая из которых начинается с
уникального прикладного имени. Прикладные названия - строковые значения. Расширенные группы данных
возвратились acdbEntGetX () следуют за данными определения в порядке, в котором они сохранены в базе
данных.

В пределах группы каждого приложения, содержания, значение, и организация данных определено


приложением; AutoCAD поддерживает информацию, но не использует это. Коды Группы для расширенных
данных находятся в 1000-1071 диапазоне, следующим образом:

Строка 1000. Строки в расширенных данных могут быть до длиной 255 байтов (с 256-ым байтом,
зарезервированным для нулевого символа).
Прикладно 1001 (также строковое значение). Прикладные названия могут быть до длиной 31 байтов
е имя (32-ой байт зарезервирован для нулевого символа) и должен твердо придержаться правил
для названий таблицы идентификаторов (типа названий уровня). Прикладное имя может
содержать символы, цифры, и специальные символы $ (долларовый признак), - (дефис), и
_ (символ подчеркивания). Это не может содержать пробелы. Символы на имя
преобразованы к верхнему регистру.

Группа расширенных данных не может состоять из прикладного имени с noother данными.

Удалять расширенные данные


1 Запрос acdbEntGet () чтобы отыскать примитив.
2 Добавляют к концу списка, возвращенного acdbEntGet () resbuf с restype -3.
3 Добавляют к концу списка другой resbuf с restype 1001 и набором resval.rstring к <appname>.

Если Вы пытаетесь добавлять 1001 группу, но никакие другие расширенные данные к существующему
примитиву, попытка игнорируется. Если Вы пытаетесь делать примитив, чей только расширенная группа
данных - сингл 1001 группа, сбои попытки.

Имя Уровня 1003. Имя уровня, связанного с расширенными данными.


Маркер Базы данных 1005. Маркеры примитивов в базе данных рисунка. При некоторых условиях AutoCAD
транслирует их.
Трехмерная точка 1010.Три реальных значения, содержащиеся в точке.
Real 1040. Реальное значение.
Integer 1070.16-разрядное целое число (подписал или без знака).
Long 1071.32-разрядное подписанное (длинное) целое число. Если значение, которое
появляется в 1071 группе - короткое целое число или реальное значение, это
преобразовано к длинному целому числу; если это недопустимо (например, строка),
это преобразовано к длинному нулю (0L).
Control String 1002. Расширенные данные управляют строкой, может быть или “{” или “}”. Эти
фигурные скобки дают возможность приложению организовать его данные,
подразделяя это в списки. Левая фигурная скобка начинает список, и правая
фигурная скобка заканчивает самый современный список. (Списки могут быть

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 ().

#define APPNAME "Local_Operation_App_3-2"


struct resbuf *rbp;
static char *local_appname = APPNAME;
// The static declaration prevents a copy being made of the string
// every time it’s referenced.
.
.
.
if ((rbp = acdbTblSearch("APPID", local_appname, 0)) == NULL) {
if (acdbRegApp(APPNAME) != RTNORM) { // Some other
// problem
acutPrintf("Can’t register XDATA for %s.",
local_appname);
return BAD;
}
} else {
acutRelRb(rbp);
}

Поиск расширенных данных


Приложение может получить зарегистрированные расширенные данные, вызывая acdbEntGetX () функция,
которая является подобной acdbEntGet (). В то время как acdbEntGet () возвращает только данные
определения, acdbEntGetX () возвращает оба
Данные определения и расширенные данные для приложений это запрашивают. Это требует дополнительного
параметра, приложений, который определяет прикладные названия (это отличается от AutoLISP, в котором
(entget) функция была расширена на ввод необязательный параметр, который определяет прикладные
названия).
Названия прошли к acdbEntGetX () должен соответствовать приложениям, зарегистрированным предыдущим
запросом к acdbRegApp (); они могут также содержать групповые символы. Если параметр приложений -
указатель NULL, запрос к acdbEntGetX () идентичен acdbEntGet () запрос.

134
Следующий типовой кодовый фрагмент показывает типичной последовательности для
восстановления{*поиска*} расширенных{*продленных*} данных для двух указанных приложений. Обратите
внимание, что параметр приложений передает прикладные названия в связанных буферах результатов.

static struct resbuf appname2 = {NULL, RTSTR},


appname1 = {&appname2, RTSTR},
*working_ent;

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 () возвращать все расширенные данные, приложенные примитиву.

Управление использованием памяти расширенными данными


Расширенные данные ограничены 16 килобайтами в примитив. Поскольку расширенные данные примитива
могут быть созданы и поддерживаться множественными приложениями, это может вести к проблемам, когда
размер расширенных данных приближается к его пределу.
ObjectARX обеспечивает две функции, acdbXdSize () и acdbXdRoom (), помогать в управлении памятью,
которая простиралась, данные занимают. Когда acdbXdSize () пропускают список буфера результата
расширенных данных, это возвращает объем памяти (в байтах) который данные займут; когда acdbXdRoom ()
пропускают имя примитива, это возвращает остающееся число свободных байтов, которые могут все еще
быть добавлены в конец к примитиву.
AcdbXdSize () функция должна читать расширенный список данных, который может быть большой.
Следовательно, эта функция может быть медленна, так что рекомендуется, чтобы Вы не вызвали
это часто. Лучший подход состоит в том, чтобы использовать это (вместе с acdbXdRoom ()) в
обработчике ошибки. Если запрос к acdbEntMod () сбои, Вы можете использовать acdbXdSize () и
acdbXdRoom () чтобы выяснить, потерпел ли запрос неудачу, потому что примитив исчерпал
расширенные данные, и затем брать соответствующее действие, если это - причина для
отказа{*неудачи*}.

Использование Меток в Расширенных данных


Расширенные данные могут содержать метки (группа 1005) чтобы сохранить относительные
структуры в пределах рисунка. Один примитив может ссылка другая, сохраняя метку другого
примитива в ее расширенных данных. Метка может быть возвращена{*восстановлена;отыскана*}
позже и проходить к acdbHandEnt () чтобы получить другой примитив. Поскольку больше чем один
примитив могут, ссылка другой, метки расширенных данных не обязательно уникальна; команда
AUDIT требует, чтобы метки в расширенных данных были или NULL или допустимые метки
примитива (в пределах текущего рисунка). Лучший способ гарантировать, который расширил метки
примитива, допустим, должен получить метку упомянутого примитива непосредственно от ее
данных определения, посредством acdbEntGet (). ( Значение метки находится в группе 5 или 105.)
К примитивам ссылки в других рисунках (например, примитивы, которые приложены посредством
таблицы перекрестных ссылок), Вы могут избегать протестов от РЕВИЗИИ, используя
расширенные строки примитива (группа 1000) скорее чем метки (группа 1005), потому что метки
перекрестно сосланных примитивов или не допустимы в текущем рисунке или конфликте с

135
допустимыми метками. Однако, если XREF Присоединяется, изменения{*замены*} к XREF
Связывают, или объединен с текущим рисунком в другим способом, это - до приложения, чтобы
пересмотреть ссылки примитива соответственно.

ОБРАТИТЕ ВНИМАНИЕ, когда рисунки объединены посредством ВСТАВКИ, ВСТАВЬТЕ *, XREF


Связывает (XBIND), или частичный DXFIN, метки оттранслированы так, чтобы они стали
правильными{*допустимыми*} в текущем рисунке. (Если рисунок прихода не
использовал{*нанимал*} метки, новые назначены.) Расширенные метки примитива, которые
обращаются{*относятся*} к входящим примитивам, также оттранслированы, когда эти команды
вызваны.

Когда примитив помещен на блочном определении (посредством команды BLOCK), примитив в


пределах блока назначен новые метки. (Если первоначальный примитив восстановлен с OOPS, это
сохраняет его первоначальные метки.) значение любых меток расширенных данных остается
неизменным. Когда блок вз (с, ВЗРЫВАЮТ), метки расширенных данных оттранслированы,
способом, подобным пути, которым они оттранслированы, когда рисунки объединены. Если метка
расширенных данных обращается{*относится*} к примитиву не в пределах блока, это неизменно;
но если метка расширенных данных обращается{*относится*} к примитиву в пределах блока, это
назначено
Значение метки нового (вырезанного) примитива.

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), или примитивов на закрепемых уровнях.

Приложения теперь способны делать следующее:


 Защищают информацию от неразборчивой чистки или размораживания уровней, который
является всегда угрозой неграфической информации, сохраненной в data.
 Используют новые поля (330-369 ссылки / указателя монопольного использования объекта,
чтобы обслужить{*поддержать*} внутренние ссылки объекта базы данных. Произвольные
значения метки полностью освобожденны от механики трансляции объекта ID. Это
оппозиционно настроено в отношении 1005 xdata групп, которые оттранслированы в
некоторых случаях, но не в других.
 Остаются незатронутым 16КБ в объект xdata предел способности{*вместимости*}. Этот
объект может также использоваться вместо xdata на определенных примитивах и объектах,
если один так пожелания, с пониманием, что независимо от того, где Вы сохраняете xrecord
объекты, они не имеют никакого встроенного предела размера, другого чем предел 2
ГБАЙТА, наложенных подписанным 32-разрядным целочисленным диапазоном.

В случае объектно - определенного состояния, xrecord объекты хорошо удовлетворены для сохранения
больших количеств сохраненной информации, в то время как xdata лучше удовлетворенный для меньших
количеств данных.

136
При монтаже иерархии xrecord объектов (добавление монопольного использования или ссылки
указателя к объекту), тот объект должен уже существовать в базе данных, и, таким образом, иметь
законное имя примитива. Поскольку acdbEntMake () не возвращает имя примитива, и acdbEntLast ()
только признает графические объекты, Вы должны использовать acdbEntMakeX () если Вы
ссылаетесь на неграфические объекты.
AcdbEntMakeX () функция возвращает имя примитива объекта, добавленного к базе данных (или
графический или неграфический). Начальный Выпуск 13 выполнения acdbEntMake () только
поддержанные объекты, чей класс диктовал его определенный объект контейнера владельца в
текущем рисунке (типа входов таблицы идентификаторов, весь снабженный Выпуск 13 типов
примитива, и объекты словаря), и зарегистрировал новый объект с его владельцем. Эти функции
продолжат делать это для того же самого набора встроенных объектных классов, включая
примитивы. Для xrecords и всех классов пользователя, эти функции добавят объект к базе данных,
оставляя это до приложения, чтобы установить его связи{*ссылки*} монопольных использований
снова до словари имен объектов. AcdbEntMakeX () функция добавляет объект к базе данных для
всех типов объекта, включая, которые идут С AutoCAD. Так, даже при использовании этой функции
на существующих типах примитива, ваша программа ответствена за установку монопольного
использования.

Доступ к таблицам идентификаторов


AcdbTblNext() функция последовательно просматривает входы таблицы идентификаторов, и
acdbTblSearch () функция возвращает определенные входы. Названия{*имена*} Таблицы
определены строками. Допустимыеимена - “LAYER”, “LTYPE”, “VIEW”, “STYLE”, “BLOCK”, “UCS”,
“VPORT”, and “APPID”. Обе из этих функций возвращают входы как списки буфера результата с кодами
группы DXF.

Первый запрос к acdbTblNext() возвращает первый вход в указанной таблице.


Последующее звонит, которые определяют, что та же самая таблица возвращает
последовательные входы, если второй параметр к acdbTblNext() (перемотка) не отличный от нуля,
когда acdbTblNext() возвращает первый вход снова.

В следующем примере, функция 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>)

Первый параметр к acdbTblSearch () - строка, которая называет таблицу, но второй параметр -


строка, которая называет специфический символ в таблице. Если символ найден, acdbTblSearch ()
возвращает его данные. Эта функция имеет третий параметр, setnext, который может
использоваться, чтобы координировать операции с acdbTblNext (). Если setnext нулевой,
acdbTblSearch () запрос не имеет никакого эффекта на acdbTblNext (), но если setnext отличный от
нуля, следующий запрос к acdbTblNext () возвращает вход таблицы, который следует за входом,
найденным acdbTblSearch ().

137
Setnext опция особенно полезна, когда имеющий дело с VPORT таблицей идентификаторов,
потому что все области просмотра в специфической конфигурации области просмотра имеют то же
самое имя (типа *ACTIVE).

Имейте в виду, что, если к VPORT таблице идентификаторов обращаются, когда TILEMODE
выключен, изменения{*замены*} не имеют никакого видимого эффекта, пока TILEMODE не
поворачивает обратно на. (TILEMODE установлен или командой SETVAR или, вводя ее имя
непосредственно.) Не путают VPORT таблицу идентификаторов с примитивами области просмотра.

Чтобы находить и обрабатывать каждую область просмотра в конфигурации, названной 4VIEW, Вы


могли бы использовать следующий код:

struct resbuf *v, *rb;


v = acdbTblSearch("VPORT", "4VIEW", 1);
while (v != NULL} {
for (rb = v; rb != NULL; rb = rb->rbnext)
if (rb->restype == 2)
if (strcmp(rb->resval.rstring, "4VIEW") == 0) {
.// Process the VPORT entry
.
.
acutRelRb(v);
// Get the next table entry.
v = acdbTblNext("VPORT", 0);
} else {
acutRelRb(v);
v = NULL; // Break out of the while loop.
break; // Break out of the for loop.
}
}

Глава10. Глобальные Функции для Взаимодействия с


AutoCAD
Глобальные функции, описанные в этой главе позволяют вашему приложению связываться с AutoCAD. Эта
глава обсуждает функции для регистрации команд с AutoCAD, обработка ввода пользователя, обработка
преобразований данных, и установки внешних устройств типа таблетки.
 Запросы AutoCAD и Команды
 Получение Ввода Пользователя
 Преобразования
 Обработка Символьного типа
 Преобразования Системы координат
 Управление Дисплея
 Калибровка Таблетки
 Универсальное сопоставление

Запросы AutoCAD и Команды


Функции, описанные в этом разделе обращаются к командам AutoCAD и услугам.

Общий Доступ
Большинство генерала функций, которые обращаются К AutoCAD - acedCommand () и acedCmd ().
Подобно функции (команды) в AutoLISP, эти функции посылают команды и другой ввод
непосредственно к Приглашению ко вводу команды AutoCAD.

Int
AcedCommand (int rtype, ...);

Int
AcedCmd (struct resbuf *rbp);

В отличие от большинства других функций взаимодействия AutoCAD, acedCommand () имеет


список параметров переменной длины: параметры к acedCommand () обработаны как пары если
бы не RTLE и RTLB, которые необходимы, чтобы передать точку указки. Первый из каждой пары
параметра идентифицирует тип результата параметра, который следует, и второй содержит

138
фактические данные. Заключительный параметр в списке - одиночный параметр, чей значение
является или 0 или RTNONE. Как правило, первый параметр к acedCommand () - тип, закодируют
RTSTR, и второй параметр данных - строка, которая является именем команды, чтобы вызвать.
Следующие пары параметра определяют опции или данные, которых указанная команда требует.
Коды типа в acedCommand () список параметров - типы результата.
Параметры данных должны соответствовать типам данных и значениям, ожидаемым последовательностью
подсказки той команды. Они могут быть строки, реальные значения, целые числа, точки, названия{*имена*}
примитива, или названия{*имена*} набора выбора. Данные типа углов, расстояний, и точек можно пропускать
или как строки (поскольку пользователь мог бы вводить их) или как значения непосредственно (то есть как
целое число, реальное, или направлять значения).
Пустая строка (“ ”) эквивалентна вводу пространства{*пробела*} на клавиатуре.
Из-за идентификаторов типа, acedCommand () список параметров - не тот же самый как список
параметров для AutoLISP подпрограмма (команды). Знайте это, если Вы преобразовываете
подпрограмму AutoLISP в ObjectARX-приложение.
Имеются ограничения на команды, которые acedCommand () может вызывать, которые являются
сопоставимыми ограничениям на AutoLISP функция (команды).

ОБРАТИТЕ ВНИМАНИЕ На acedCommand () и acedCmd () функции могут вызывать команду SAVE


ИЛИ SAVEAS AutoCAD. Когда они делают так, AutoLISP выпускает kSaveMsg сообщение к всем
другим ObjectARX-приложениям, в настоящее время загруженным, но не к приложению, которое
вызвало SAVE. Сопоставимый код послан, когда эти функции вызывают NEW, OPEN, END, или QUIT
от приложения.

Следующая типовая функция показывает несколько, вызывает к acedCommand ().

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 на экране графики потока
(или область просмотра).

struct resbuf *cmdlist;


cmdlist = acutBuildList(RTSTR, "redraw", 0);
if (cmdlist == NULL) {
acdbFail("Couldn’t create list\n");
return BAD;
}
acedCmd(cmdlist);
acutRelRb(cmdlist);

139
Приостановка ввода пользователя
Если команда AutoCAD происходит, и AutoCAD сталкивается с символом ПАУЗЫ как параметр к
acedCommand () или acedCmd (), команда временно приостановлена, чтобы позволить прямой
ввод пользователя, включая перемещение. Символ ПАУЗЫ состоит из строки, которая содержит
одиночную наклонную черту влево. Это подобно наклонной черте влево механизм паузы,
предусмотренный меню.
Следующий запрос к acedCommand () вызывает команду ZOOM и затем использует символ ПАУЗЫ
так, чтобы пользователь мог выбирать одну из опций ZOOM.

result = acedCommand(RTSTR, "Zoom", RTSTR, PAUSE, RTNONE);

Следующий запрос начинает команду CIRCLE, устанавливает среднюю точку как (5,5), и затем
делает паузу, чтобы позволить пользователю перетаскивать радиус круга на экране. Когда
пользователь определяет выбранную точку (или вводит выбранный радиус), функциональные
резюме, тянущий линию от (5,5) до (7,5).

result = acedCommand(RTSTR, "circle", RTSTR, "5,5",


RTSTR, PAUSE, RTSTR, "line", RTSTR, "5,5", RTSTR,
"7,5", RTSTR, "", 0);

Принятие указения точки командой AutoCAD


Некоторые команды AutoCAD (типа TRIM, EXTEND и FILLET) требует, чтобы пользователи определили
точку указки также как примитив. Чтобы передавать такие пары примитива и данных точки
посредством acedCommand (), Вы должны определить имя примитива сначала и включать пару в
RTLB и коды типа результата RTLE.
Следующий типовой кодовый фрагмент создает круг, центрированный в (5,5) и линию, которая
простирается от (1,5) до (8,5); это предполагает, что круг и линия созданы в пустом рисунке. Это
тогда использует точку указки с командой TRIM, чтобы урезать линию в крае круга. AcdbEntNext ()
функция находит следующий примитив в рисунке, и acdbEntLast () функция находит последний
примитив в рисунке.

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.

struct resbuf rb, rb1;


acedGetVar("FILLETRAD", &rb);
rb1.restype = RTREAL;
rb1.resval.rreal = 1.0;
if (rb.resval.rreal < 1.0)
if (acedSetVar("FILLETRAD", &rb1) != RTNORM)
return BAD; // Setvar failed.

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:

Command: (setq testboole t)


T
Command: (setq teststr “HELLO, WORLD”)
“HELLO, WORLD”
Command: (setq sset1 (ssget))
<Selection set: 1>

Тогда следующий типовой код показывает, как acedGetSym() отыскивает новые значения символов.

struct resbuf *rb;


int rc;
long sslen;
rc = acedGetSym("testboole", &rb);
if (rc == RTNORM && rb->restype == RTT)
acutPrintf("TESTBOOLE is TRUE\n");
acutRelRb(rb);
rc = acedGetSym("teststr", &rb);
if (rc == RTNORM && rb->restype == RTSTR)
acutPrintf("TESTSTR is %s\n", rb->resval.rstring);
acutRelRb(rb);
rc = acedGetSym("sset1", &rb);
if (rc == RTNORM && rb->restype == RTPICKS) {
rc = acedSSLength(rb->resval.rlname, &sslen);
acutPrintf("SSET1 contains %lu entities\n", sslen);
}
acutRelRb(rb);

Наоборот, acedPutSym () может создавать или изменять связывание символов AutoLISP,


следующим образом:

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);

Чтобы устанавливать переменную AutoLISP в ноль, делайте следующее назначение и функциональный


запрос:

rb->restype = RTNIL;
acedPutSym("var1", rb);

141
Пользователи могут отыскивать эти новые значения. (Как показано в примере, ваша программа должна
уведомить пользователей относительно любых изменений.)

TESTSTR has been reset.


LONGLIST has been created.
Command: !teststr
(“GREETINGS”)
Command: !longlist
((-1 “The combinations of the world” “are unstable by nature.” 100 (1.4 1.4
10.9923) (“He jests at scars” “that never felt a wound.”)))

Поиск Файла
AcedFindFile () функция дает возможность приложению искать файл специфического имени. Приложение
может определить каталог, чтобы искать, или это может использовать поток путь библиотеки AutoCAD.
В следующем типовом кодовом фрагменте, acedFindFile () ищет требуемое имя файла согласно пути
библиотеки AutoCAD.

char *refname = "refc.dwg";


char fullpath[100];
.
.
.
if (acedFindFile(refname, fullpath) != RTNORM) {
acutPrintf("Could not find file %s.\n", refname);
return BAD;

Если запрос к acedFindFile () успешен, fullpath параметр установлен в полностью квалифицированную строку
имени пути, типа следующего:

/home/work/ref/refc.dwg

Вы можете также запрашивать пользователей вводить имя файла посредством стандарта файловое
диалоговое окно AutoCAD. Чтобы отображать файловое диалоговое окно, вызовите acedGetFileD ().
Следующий типовой кодовый фрагмент использует файловое диалоговое окно, чтобы запросить
пользователей относительно имени ObjectARX-приложения.

struct resbuf *result;


int rc, flags;
if (result = acutNewRb(RTSTR) == NULL) {
acdbFail("Unable to allocate buffer\n");
return BAD;
}
result->resval.rstring=NULL;
flags = 2; // Disable the "Type it" button.
rc = acedGetFileD("Get ObjectARX Application", // Title
"/home/work/ref/myapp", // Default pathname
NULL, // The default extension: NULL means "*".
flags, // The control flags
result); // The path selected by the user.
if (rc == RTNORM)
rc = acedArxLoad(result->resval.rstring);

Объектная Привязка
AcedOsnap () функция находит точку, используя один из Режимов объектной привязки AutoCAD. Поспешные
режимы определены в строковом параметре.
В следующем примере, запрос к acedOsnap () ищет midpoint линии около pt1.

acedOsnap(pt1, "midp", pt2);

Следующий запрос ищет или midpoint или оконечную точку линии, или центра дуги или круга —, какой бы ни -
самый близкий pt1.

acedOsnap(pt1, "midp,endp,center", pt2);

Третий параметр (pt2 в примерах) установлен в поспешную точку, если найдены. AcedOsnap ()
функциональные возвращения RTNORM, если точка найдена.

ОБРАТИТЕ ВНИМАНИЕ, что переменная системы APERTURE определяет допустимую близость выбранной
точки к примитиву при использовании Объектной Привязки.

142
Описатели Области просмотра
Функция acedVports (), подобно функции AutoLISP (vports), получает список описателей текущих областей
просмотра и их местоположений.
Следующий типовой код получает текущую конфигурацию области просмотра и передает это назад к AutoLISP
для дисплея.

struct resbuf *rb;


int rc;
rc = acedVports(&rb);
acedRetList(rb);
acutRelRb(rb);

Например, учитывая конфигурацию с одиночной областью просмотра со включенным TILEMODE,


предшествующий код может возвращать список, показанный в следующем рисунке.

Точно так же, если четыре области просмотра равняться-размера расположены в четырех углах экрана, и
TILEMODE включен, предшествующий код может возвращать конфигурацию, показанную в следующем
рисунке.

Описатель текущей области просмотра - всегда сначала в списке. В списке, показанном в предшествующем
числе{*рисунке*}, номер 5 области просмотра - текущая область просмотра.

Геометрические Утилиты
Одна группа функций дает возможность приложениям получить геометрическую информацию.
AcutDistance () функция находит, что расстояние между двумя точками, acutAngle () находит угол между
линией, и X ось текущих ВЕРХНИХ РЕГИСТРОВ (в КООРДИНАТНОМ плане), и acutPolar () находит точку
посредством полярных координат (относительно начальной точки). В отличие от большинства функций
ObjectARX, эти функции не возвращают значение состояния. AcdbInters () функция находит пересечение двух
линий; это возвращает RTNORM, если это находит точку, которая соответствует спецификации.

ОБРАТИТЕ ВНИМАНИЕ В отличие от acedOsnap (), функции в этой группе просто вычисляют точку, линию,
или угловые значения, и фактически не сделают запрос текущего рисунка.

Следующий типовой кодовый фрагмент показывает некоторый простой, вызывает к геометрическим


сервисным функциям.

ads_point pt1, pt2;


ads_point base, endpt;
ads_real rads, length;
.
. // Инициализирует pt1 и pt2.
.
// Возвратить угол в КООРДИНАТНОМ плане текущих ВЕРХНИХ РЕГИСТРОВ, в радианах.
rads = acutAngle (pt1, pt2);
// Расстояние Возвращения в трехмерном пространстве{*пробеле*}.
length = acutDistance (pt1, pt2);

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 () находит диагональные координаты поля, которое включает текстовый примитив.
Функция берет параметр, ent, который должен определить текстовое определение или строковую группу в
форме списка буфера результата. AcedTextBox() функция устанавливает ее p1 параметр в минимальные
КООРДИНАТНЫЕ координаты поля и ее p2 параметра к максимальным КООРДИНАТНЫМ координатам.
Если текст горизонтален и не вращается, p1 (угол левой нижней части) и p2 (верхний правый угол) описывают
поле ограничения текста. Координаты выражены в Системе координат Примитива (ECS) ent с началом
координат (0,0) в левой оконечной точке опорной линии. (Начало координат - не угол левой нижней части,
если текст содержит символы с подстрочными элементами, типа g и p.) Для примера, следующий рисунок
показывает результатам применения acedTextBox () к текстовому примитиву с высотой 1.0. Рисунок также
показывает опорной линии и началу координат текста.

Следующий рисунок показывает значениям точки, которые acedTextBox () возвращается для


выборок вертикального и выровненного текста. В обеих выборках, высота символов была введена
как 1.0. (Для вращаемого текста, эта высота масштабируется, чтобы приспособить точки
выравнивания.)

Обратите внимание, что с вертикальными текстовыми стилями, точки все еще возвращаются в слева направо,
заказ{*по приказу;порядок*} " основание к вершине ", так что первый список точки содержит отрицательные
смещения от текстового начала координат.
AcedTextBox () функция может также измерять строки в attdef и attrib примитивах. Для attdef,
acedTextBox () измеряет строку отметки (группа 2); для attrib примитива, это измеряет текущее
значение (группа 1).
Следующая функция, которая использует некоторый примитив, обрабатывающий функции,
запрашивает пользователя выбирать текстовый примитив, и затем тянет{*рисует*} поле
ограничения вокруг текста от координат, возвращенных acedTextBox ().

ОБРАТИТЕ ВНИМАНИЕ На выборку tbox () функциональные работы правильно только, если Вы - в


настоящее время в Мировой системе координат (WCS). Если Вы - не, код должен преобразовать

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.rpoin