ObjectARX, AutoCAD. Среда программирования библиотеки C++

         

Контексты Выполнения Документа


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



Контроль Дисплея


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



Контроль Формы Элемента Сети


AcBr:: Element2dShape перечисление управляет формой элементов, сгенерированных 2-ой сетью. Это только уместно фильтру сети. 1d сеть (соответствующий дискретизации граничных кривых первоначального лица) может быть эмулирована,  определяя kAllPolygons.



Контроль Графических и Текстовых Экранов низкого уровня


На единственно - экранных инсталляциях AutoCAD, ObjectARX-приложение может вызывать acedGraphScr () чтобы отобразить графический экран или acedTextScr () чтобы отобразить текстовый экран. Эти функции эквивалентны AutoCAD GRAPHSCR и командам TEXTSCR или переключению Зеркально отражающейся Экранной функциональной клавиши. Функция acedTextPage () - подобно acedTextScr (), но это очищает текстовый экран перед отображением этого (поскольку команда STATUS AutoCAD делает).

AcedRedraw () функция подобна команде REDRAW AutoCAD, но это обеспечивает большее количество контроля над, что отображено: это может перерисовывать полный графический экран и также определять единственный{*отдельный*} объект, чтобы быть или повторно оттянутым или неоттянутым (blanked из). Если объект - сложный объект типа ломаной линии, или блок, acedRedraw () может тянуть{*рисовать*} (или нетянуть{*нерисовать*}) или полный объект или только его заголовок. AcedRedraw () функция может использоваться также, чтобы высвечивать или невысветить отобранные объекты.



Контроль относительно Графики Нижнего уровня и Ввода пользователя


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

AcedGrText () функциональный текст дисплеев в состоянии или областях меню, с или без высвечивания{*увеличения яркости*}. AcedGrDraw () функция тянет{*рисует*} вектор в текущей области просмотра, с контролем над цветом и высвечиванием{*увеличением яркости*}. AcedGrVecs () функция тянет{*рисует*} множественные векторы. AcedGrRead () функциональные возвращения ввод пользователя “сырья”, ли от клавиатуры или устройства управления позицией; если запрос к acedGrRead () позволяет трэкинг, функция возвращает цифровые координаты, которые могут использоваться для перемещения.

ПРЕДУПРЕЖДЕНИЕ! Поскольку эти функции зависят от кода в AutoCAD, их операция может изменяться от выпуска. Приложения, которые вызывают эти функции, не могут быть восходяще совместимы. Также, они зависят от текущей аппаратной конфигурации. В частности приложения, которые вызывают acedGrText () и acedGrRead (), вряд ли,  будут работать тот же самый на всех конфигурациях, если разработчик не использует их как описано ранее, чтобы избежать аппаратно-зависимых особенностей.



Эти функции не делают почти никакое сообщение ошибки и могут повреждать графическое экранное устройство отображения (см. пример для способа установить эту проблему).

Следующее повреждение при смене графического экранного устройства отображения вызвано неправильным обращением к acedGrText (), acedGrDraw (), или acedGrVecs ().

acedGrText (-3, NULL, 0);

acedRedraw (NULL, 0);

Параметры к acedGrText () имеют следующие значения: -3 восстановление стандартного текста, NULL == никакой новый текст, и 0 == никакое высвечивание. Параметры к acedRedraw() имеют следующие значения: NULL == все примитивы, и 0 == вся область просмотра.



Контроль Точки ввода


Мониторы Точки ввода вызваны для всей строки и событий цифрового преобразователя, когда точка приобретается, или когда принудительный выбор примитива позволяется. Мониторы Точки ввода могут рассматривать конечную точку, позиционируются и может отображать ToolTip строку.

ToolTip строка может быть установлена,  используя appendToTooltipStr и additionalTooltipString параметры при создании монитора точки ввода.

Мониторы Точки ввода обработаны, в конце концов другие вычисления точки ввода выполнены в соответствии с AutoCAD, включая заказную фильтрацию точки ввода, если фильтр существует. Точки вывода все еще подчиненны к AutoCAD XYZ

фильтрация точки.

Может иметься любое число мониторов точки ввода, активных в данное время, так как они только позволяют рассматривать точек ввода.



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


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

Acad::ErrorStatus

AcDbDatabase::wblock(AcDbDatabase*& newDb,

const AcDbObjectIdArray& idArray,

const AcGePoint3d* point);

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



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


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

Acad:: ErrorStatus

 AcDbDatabase::wblock(AcDbDatabase*& NewDb,

AcDbObjectId recordId);

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

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



Краткий обзор


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

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

§         Все документы должен быть блокирован, чтобы измениться. Основной документ блокировка обработана автоматически для AutoCAD, командует, ObjectARX команды, и функции AutoLISP. Немодальный диалог и код инструментальной панели, и любые команды, которые должны работать вне активного документа, должны вручную исполнить документ блокировка.

§         приложение должен обслужить{*поддержать*} отношения между документами и базами данных. Библиотека баз данных AutoCAD (AcDb) не сознает документы и MDI, и должна остаться так.

Несколько архитектурных особенностей ObjectARX

делают поддержку возможного MDI.

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


Объектная модель программных компонентов Microsoft (COM) была первоначально разработана, чтобы поддержать связь и внедрение объектов (OLE); это также стало основанием ActiveX Автоматизации. Как стандарт на стадии становления для развития компонента Windows, COM имеет уместность вне OLE и ActiveX. Составляющая архитектура отделяет интерфейс от выполнения, позволяя приложения состоять из динамически связанных компонентов скорее чем отдельная двоичная выполнимая программа.

Разработчики могут записывать программы, которые воспользуются преимуществом существующих компонентов COM, или они могут использовать COM, чтобы создать их собственные компоненты.

ObjectARX-приложения могут быть разработаны как клиенты COM. Например, ObjectARX-приложение, которое должно связаться с другой программой, могло осуществлять COM, обращаются к той программе. В зависимости от интерфейсов COM, которые другое приложение обеспечивает, ObjectARX-приложение могло тогда обменивать информацию с прикладным обеспечением или даже драйвером.

ObjectARX-приложение может также действовать как сервер автоматизации. Вы можете записывать обертки COM, чтобы выставить дополнительные элементы или заказные объекты ObjectARX. Новые API, шаблоны, классы, и поддержка для Microsoft Активная Библиотека Шаблонов (ATL) делают это проще чем когда-либо, чтобы добавить к AutoCAD ActiveX

модель Автоматизации.




ObjectDBX включает набор DLLS, который может использоваться, чтобы осуществить заказные объекты, содержащиеся в чертежном файле AutoCAD 2000, и осуществлять приложения, которые управляют DWG файлами без присутствия AutoCAD. Часть этой возможности была прежде представлена в DWG, отключенное изделие{*программа*}, но ObjectDBX SDK заменяет и идет вне DWG

Отключенная технология,  обеспечивая поддержку, необходимую для интеллектуальных объектных систем. ObjectDBX SDK позволяет Вам создавать приложения главного компьютера не-автохама, которые могут читать и записывать DWG файлы.




Программирование Диалогового окна возводит в степень две стадии:

§         Проектирование диалогового окна dialog box определены текстовыми файлами, написанными на языке контроля диалогов (DCL). Описание DCL диалогового окна определяет, как поле появляется и что это содержит. Для подробной информации, см. Часть III, “ Программируемая Ссылка Диалогового окна, ” в Руководстве Настройки AutoCAD.

§         Поддержка диалогового окна в ваших частях приложения диалогового окна определяют, как это ведет себя; однако, использование и поведение диалогового окна зависят от приложения, которое использует это.



Краткий обзор AcGe Библиотеки


AcGe библиотека включает широкий набор классов для представления обычно используемая геометрия, типа точек, линий, кривых, и поверхностей. Это обеспечивает общее представление для геометрии, которая может использоваться любым приложением Autodesk. Библиотека вполне математическая; хотя его классы не имеют дело непосредственно с базой данных или с графикой, многие из его классов используются AcDb и AcGi библиотеками.

Иерархия классов для AcGe библиотеки показывается следующим образом:

AcGe библиотека обеспечивает, и простые и комплексные классы геометрии. Простые линейные классы алгебры включают точку, вектор, матрицу, 2-ые и трехмерные линейные классы примитива, и плоские классы примитива. Комплексные классы включают классы кривой, типа сплайнового примитива, и поверхностных классов, типа поверхностей НЕОДНОРОДНОГО РАЦИОНАЛЬНОГО В-СПЛАЙНА.

Иерархия классов предлагает отдельные классы для 2-ой и трехмерной геометрии. Это упрощает программирование,  ясно отличая 2-ую параметрически - пространственную геометрию от трехмерной геометрии пространства моделирования. Из-за этого различия, Вы не можете неосторожно смешивать 2-ые и трехмерные примитивы в той же самой операции.

Библиотека включает множество основных типов, типа AcGePoint3d, AcGeVector3d, и AcGeMatrix3d, которые имеют общественные компоненты данных для быстрого и эффективного доступа. Эти простые классы обычно используются другими библиотеками также как классами AcGe, полученными из AcGeEntity2d и AcGeEntity3d.

Контроль соответствия типов Во время выполнения предусмотрен все классы, полученные из AcGeEntity2d и AcGeEntity3d. Каждый класс обеспечивает type() функцией, которая возвращает класс объекта и isKindOf () функция, которая возвращается, имеет ли объект специфический класс (или класс, полученный из того класса).

Два примитива рассматриваются равными, если они имеют тот же самый тип и представляют то же самое точечное множество. Кривые и поверхности рассматриваются равными только, если их параметризация - тот же самый.



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


Рисунок AutoCAD - коллекция объектов, сохраненных в базе данных. Некоторые из основных объектов базы данных - объекты, таблицы идентификаторов, и словари. Объекты - специальный вид базы данных, имеют графическое представление в пределах рисунка AutoCAD. Строки, круги, дуги, текст, solids, области(регионы), сплайны, и эллипсы - примеры объектов. Пользователь может видеть объект на экране и может управлять им.

Таблицы идентификаторов и словари - контейнеры, имел обыкновение сохранять объекты  базы данных. Оба контейнерных объекта отображают строку имени к объекту базы данных. База данных AutoCAD включает фиксированный набор таблиц идентификаторов, каждая из которых содержит образцы специфического класса отчета таблицы идентификаторов. Вы не можете прибавлять новую таблицу идентификаторов к базе данных. Примеры таблиц идентификаторов - таблица уровня (AcDbLayerTable), который содержит отчеты таблицы уровня, и блочную таблицу (AcDbBlockTable), который содержит блочные отчеты таблицы. Все объекты AutoCAD принадлежат блочным отчетам таблицы.

Словари обеспечивают более универсальный контейнер для сохранения объектов, чем таблицы идентификаторов. Словарь может содержать любой объект типа AcDbObject или подкласса этого. База данных AutoCAD создает словарь называемый названным объектным словарем, когда это создает новый рисунок. Названный объектный словарь может просматриваться как главное “оглавление” для всех словарей, связанных с базой данных. Вы можете создавать новые словари в пределах названного объектного словаря и прибавлять новая база данных. Следующий рисунок показывает ключевые компоненты базы данных AutoCAD.

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

acdbHostApplicationServices()->workingDatabase()



Краткий обзор управления транзакциями


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

Действие на объектах, использующих эту парадигму имеет несколько преимуществ по регулярному открытому и близкому механизму, описанному в главе 5, “ Объекты Базы данных. ” Открытый и близкий механизм подходящий для простых операций на единственном{*отдельном*} объекте или маленькой группе объектов. Однако, имеются некоторые ограничения на открывающиеся объекты этот путь. Например, если объект открытый для чтения, Вы не можете открывать это для записи в то же самое время. Если объект открытый для записи, Вы не можете открывать это для записи второй раз. Для списка ошибок конфликта, связанных с открытым и близким механизмом, см. главу 5, “ Объекты Базы данных. ” Операционная модель более снисходительна, и получение объектных указателей от объекта IDs для специфического режима обычно преуспевает, если объект связан с транзакцией.

В зависимости от вашего приложения, могут иметься другие недостатки к использованию открытого и закрывать механизм. Если ваше приложение открывает и закрывает тот же самый объект неоднократно в ходе одной операции — например, команда — вы будете нести серьезные неэффективность из-за этого множителя, открывает и закрывается. Множество отнимающих много времени операций связано с закрытием объекта. Если Вы открываете объект для записи, измените это, и затем закройтесь, это, записи отмены модификации совершено{*передано*} файлу отмены, графика для объекта сгенерирована, и уведомления обстреляны. Все эти операции

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

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



Краткий обзор уведомлений


Когда событие происходит в системе, некоторых объектах, вызванных{*названных*} уведомителях, автоматически передайте событие к другим объектам. Например, когда копии пользователя, стирания, или изменяют объект или когда пользователь выпускает команду UNDO ИЛИ REDO, соответствующее уведомление для каждого события автоматически вызвано.

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

Использовать реактор в приложении

1 Получают новый реакторный класс и осуществляют функции уведомления для событий, ваш реактор ответит на.

2 Инициализируют реактор.

3 Добавляют реактор к реакторному списку уведомителя.

При закончено использование реактора

1 Удаляют реактор из реакторных списков всех уведомителей, к которым это было добавлено.

2 Удаляют реактор (если это не объект резидента базы).

Использование реакторов требует подклассов создания реакторных классов или классов AcDbObject. Эта глава предполагает, что Вы знакомы с материалом, представленным в главе 11, при Наследовании Заказного ObjectARX Класса, ” и главы 12, “ Происходящий от AcDbObject. ”



Кривые


Кривые и поверхности в AcGe библиотеке параметрические. Кривая - результат отображения интервала реальной линии в 2D

или 3D пространстве  и моделируется  использованием функции вычислителя с одним параметром, типа f (u). Точно так же поверхность - отображение 2D

области  в пространство моделирования 3D

использование функции вычислителя, основанной на двух параметрах например, f (u, v). Каждый 2D и 3D

класс кривой  имеют getInterval () функция, которая возвращает параметрический интервал. Эта функция имеет две формы: первая возвращения интервал; вторая возвращает интервал также как точку начала и оконечную точку кривой.

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



Linetype Масштаб, указанный В Примитив


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

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

Acad::ErrorStatus

AcDbEntity::setLinetypeScale(double newVal);

double

AcDbEntity::linetypeScale() const;



Linetype примитива


Значение linetype указывает на вход таблицы идентификаторов, который определяет ряд точек и подчеркивает штриховой линией используемый для рисунка строк. Когда примитив - instantiated, его linetype установлен в NULL. Когда примитив добавлен к базе данных, если linetype не был определен для примитива, linetype установлен в поток базы данных linetype значение. Это значение по умолчанию сохранено в CELTYPE системной переменной.

Linetype может быть определен по имени, строкой, или объектом ID AcDbLineTypeTableRecord в целевой базе данных примитива.

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

CONTINUOUS - Значение по умолчанию linetype, который автоматически создан в linetype таблице идентификаторов

BYLAYER Linetype значение уровня примитива

BYBLOCK Linetype значение примитива окружающий блочный поток определения блокирует ссылку{*справочники*}

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

Следующие функции дают возможность Вам установить 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;



LOAD


Загружает .arx файл, который Вы определяете в стандартном файловом диалоговом окне. Если FILEDIA установлен в 0, диалоговое окно не отображено, и Вы вводите название{*имя*} файла, чтобы загрузиться в ответ на следующую подсказку:

Файл расширения{*продления*} Во время выполнения: Введите название{*имя*}



Локализация и XMX Файлы


С тех пор acdb.xmx оттранслирован для всех ограниченных версий AutoCAD, pretrans-lated XMX файлы теперь отправлены как часть ObjectDBX SDK, так что Вы можете создавать полностью ограниченное языком конечное изделие. Это позволит, Вы, чтобы создать несколько версий языка вашего приложения, или вашего приложения можете сделать запрос пользователя с выбором нескольких языков.

Выбор языка будет ответственность вашего приложения. К тому концу, загрузка XMX файла находится в функции acdbValidateSetup ().

Эта функция берет параметр LCID, чтобы определить выбор приложения языка. Функция будет пытаться загружать это XMX файл сначала,  используя AcDbHostApplicationServices:: findFile () метод и, если это терпит неудачу, смотря в каталоге, который содержит AcDb15.dll.

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

Acad::ErrorStatus

acdbValidateSetup( long lcid );

Acdb.xmx файл теперь назван acdbLLL.xmx, где ЯЗЫК НИЗКОГО УРОВНЯ - сокращение локализации языка с тремя символами, которое может быть получено из LCID.

Autodesk поддерживает, и в конечном счете отправит или иначе обеспечит, acdbLLL.xmx файлы на следующих языках.

XMX файлы типа

Language

Language Abbreviation

Language ID from LCID

English (USA)

ENU

0409

Chinese (Taiwan)

CHT

0404

Chinese (Simplified)

CHS

0804

Czech

CSY

0405

French (Default)

FRA

040c

German (Default)

DEU

0407

Greek

ELL

0408

Hungarian

HUN

040e

Italian

ITA

0410

Japanese

JPN

0411

Korean

KOR

0412

Polish

PLK

0415

Portuguese (Brazilian)

PTB

0416

Portuguese (Default)

PTG

0816

Russian (Default)

RUS

0419

Spanish (Default)

ESP

040a

Как ObjectDBX разработчик, Вы должны делать две вещи создать ограниченный языком конечный продукт:

§         Вы должен отправить соответствующие acdbLLL.xmx файлы наряду с вашим изделием{*программой*}.

§         Вы должен сообщить ObjectDBX который acdbLLL.xmx файл загрузиться, пропуская соответствующий LCID к acdbValidateSetup ().

Если LCID не соответствует одному из сокращений с тремя символами выше, или если соответствующий XMX файл не был отправлен, ваше приложение ObjectDBX будет не в состоянии загружаться должным образом.

Если неспособно найти,  желательный acdb.xmx файл, acdbValidateSetup () будет пытаться загружать Английский язык как по умолчанию. Снова, это будет сначала использовать findFile (), и затем принимать тот же самый путь как AcDb15.dll. Если это находит Английский язык, но Английский язык не был,  требуемый язык, Acad:: eFileNotFound возвращен. Если функция неспособна найти любой acdb.xmx файл, это остановится с fatalError (), и ваше приложение не будет загружаться.



LoopType


AcBr:: LoopType перечисление классифицирует цикл как внутренняя область, внешняя область, и так далее.

Периферийные циклы - kLoopExterior, и имеется только один такой цикл в лицо (в соответствии с соглашением промышленности). Отверстия возвращены как kLoopInterior, и может иметься несколько в лицо (если имеется также внешний цикл). Конусы и цилиндры (имеют ли с эллиптическим или круговым ядром) по крайней мере два основных цикла (если они полны, и в u и v), который,  возвращены как kLoopWinding в противоположность kLoopExterior из-за ограничения туда являющийся только что один внешний цикл (наряду с фактом, что никакой основной цикл не является отверстием). Особенности (типа вершины конуса) возвращены как kLoopUnclassified. Все циклы на сферических и toric

поверхностях, также как закрытом периодическом НЕОДНОРОДНОМ РАЦИОНАЛЬНОМ В-СПЛАЙНЕ, возвращают kLoopUnclassified.



Макрокоманда Объявления Класса


Файл заголовка для заказного класса может использовать ACRX_DECLARE_MEMBERS (CLASS_NAME) макрокоманда ObjectARX, чтобы объявить desc(), cast(), и isA() функции.

Эта макрокоманда используется в общем разделе объявления класса, следующим образом:

class myClass : public AcRxObject

{

                public:

                ACRX_DECLARE_MEMBERS(myClass);

                ...

};

Для AsdkPoly, следующая строка расширяется до одиночной длинной строки программы.

ACRX_DECLARE_MEMBERS (AsdkPoly);

Когда переформатировано к множественным строкам для ясности, строка напоминает это:

virtual AcRxClass* isA() const;

static AcRxClass* gpDesc;

static AcRxClass* desc();

static AsdkPoly* cast(const AcRxObject* inPtr)

{

                return ((inPtr == 0) || ! inPtr->isKindOf(AsdkPoly::desc())) ? 0 : (AsdkPoly*)inPtr;

};

static void rxInit();

Статический rxInit () функция и статический gpDesc указатель, объявленный этой макрокомандой используется, чтобы осуществить isA (), desc (), и cast() функции.



Макрокоманды Выполнения Класса


Чтобы осуществлять ваш заказной класс, используйте одну из этих трех макрокоманд в источнике file:

·          ACRX_NO_CONS_DEFINE_MEMBERS(CLASS_NAME, PARENT_CLASS)

 Использование для абстрактных классов и любых других классов, которые не должны быть instantiated.

·          ACRX_CONS_DEFINE_MEMBERS(CLASS_NAME, PARENT_CLASS, VERNO)

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

·          ACRX_DXF_DEFINE_MEMBERS(CLASS_NAME, PARENT_CLASS, DWG_VERSION,\

MAINTENANCE_VERSION, PROXY_FLAGS, DXF_NAME, APP)

 Использование для классов, которые могут быть записаны в, или читать от, DWG и DXF файлы.

Каждая из этих макрокоманд определяет следующее:

·         объект описателя Класса

·         функция инициализации Класса (см. “ Функция Инициализации Класса ” на странице 289)

·         desc () функция для этого класса

·         виртуальный isA () функция (унаследованный от AcRxObject) который этот заказной класс отменит

Для AsdkPoly, следующая строка расширяется до очень длинной одиночной линии кода:

ACRX_DXF_DEFINE_MEMBERS(AsdkPoly, AcDbCurve, AcDb::kDHL_CURRENT,\

AcDb::kMReleaseCurrent, 0, POLYGON, /*MSG0*/"AutoCAD");

Когда переформатировано к множественным строкам для ясности, строка напоминает это:

AcRxClass* AsdkPoly::desc()

{

                if (AsdkPoly::gpDesc != 0)

                               return AsdkPoly::gpDesc;

                return AsdkPoly::gpDesc =

                               (AcRxClass*)((AcRxDictionary*)acrxSysRegistry()->

                                               at("ClassDictionary"))->at("AsdkPoly");


}

AcRxClass* AsdkPoly::isA() const

{

                return AsdkPoly::desc();

}

AcRxClass* AsdkPoly::gpDesc = 0;

static AcRxObject * makeAsdkPoly()

{

                return new AsdkPoly();

}

void AsdkPoly::rxInit()

{

                if (AsdkPoly::gpDesc != 0)

                return;

                AsdkPoly::gpDesc = newAcRxClass("AsdkPoly",

                                                               "AsdkCurve", AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,

                                                               0, &makeAsdkPoly, "POLYGON", "\"AutoCAD\"");

};

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

Если Вы хотите записать ваш собственный rxInit () функция, использовать ACRX_DEFINE_MEMBERS () макрокоманда отдельно, которая определяет desc (), cast (), и isA () для вашего класса, но не определяет rxInit () функция. Эта макрокоманда также не создает связанный объект AcRxClass, который является ответственностью rxInit () функция.


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


Вы можете добавлять примитивы к набору выборов или удалять их из этого,  вызывая функции 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).

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

Когда 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;

}

}

}


Матрицы Преобразования


Функции acedDragGen (), acedGrVecs (), acedNEntSelP (), и acedXformSS () умножают входные векторы на матрицу преобразования, определенную как 4x4 массив реальных значений.

typedef ads_real ads_matrix [4] [4];

Первые три столбца матрицы определяют масштабирование и вращение. Четвертый столбец матрицы - вектор сдвига. ObjectARX определяет символ T, чтобы представить координату этого вектора, следующим образом:

 #define T 3

Матрица может быть выражена следующим образом:

М. 00

 М. 01

М. 02

 М. 03

М. 10

М. 11

 М. 12

 М. 13

М. 20

 М. 21

 М. 22

М. 23

0.0

0.0

0.0

1.0

Следующая функция инициализирует единичную матрицу.

void ident_init(ads_matrix id)

{

int i, j;

for (i=0; i<=3; i++)

for (j=0; j<=3; j++)

id[i][j] = 0.0;

for (i=0; i<=3; i++)

id[i][i] = 1.0;

}

Функции, которые передают параметры типа ads_matrix, обращаются с точкой как вектор столбца измерения 4. Точка выражена в гомогенных координатах, где четвертый элемент вектора точки - коэффициент масштаба, который обычно устанавливается в 1.0. Конечная{*заключительная*} строка матрицы имеет номинальное значение [0,0,0,1]; это игнорируется функциями тот проход ads_matrix параметры. В этом случае, следующие матричные результаты умножения от приложения преобразования к точке:

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

Y ' = М. 10 X + М. 11 Y + М. 12 Z + М. 13 (1.0)

Z ' = М. 20 X + М. 21 Y + М. 22 Z + М. 23 (1.0)

Как этот показ уравнений, коэффициент масштаба и последняя строка матрицы не имеет никакой эффект и игнорируется. Это известно как афинное преобразование.


ПРИМЕЧАНИЕ, чтобы преобразовать вектор скорее чем точка, не добавьте в векторе сдвига М3 М13 М23 (от четвертого столбца матрицы преобразования).

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

void xformpt(xform, pt, newpt)

ads_matrix xform;

ads_point pt, newpt;

{

int i, j;

newpt[X] = newpt[Y] = newpt[Z] = 0.0;

for (i=X; i<=Z; i++) {

for (j=X; j<=Z; j++)

newpt[i] += xform[i][j] * pt[j];

// Add the translation vector.

newpt[i] += xform[i][T];

}

}

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

( Значения в ads_matrix - фактически ads_real, но им показывают здесь как целые числа для удобочитаемости и соответствовать математическому соглашению.)

1

0

0

0

1

0

0

TX

SX

0

0

0

cos

-sin

0

0

0

1

0

0

0

1

0

TY

0

SY

0

0

sin

cos

0

0

0

0

1

0

0

0

1

TZ

0

0

SZ

0

0

0

1

0

0

0

0

1

0

0

0

1

0

0

0

1

0

0

0

1

Translation                               scaling                      2D rotation (in the XY plane)

AcedXformSS () функция — в отличие от acedDragGen(), acedGrVecs(), или acedNEntSelP() функции — требует, чтобы  матрица делала однородное масштабирование. То есть в матрице преобразования, которую Вы проходите к acedXformSS (), элементы в векторе масштабирования S X S Y S Z, должны весь быть равными; в матричном примечании, М. 00 = М. 11 = М. 22. Трехмерное вращение - слегка различный случай, как показано в следующем рисунке:

cos

-sin

0

0

1

0

0

0

cos

0

sin

0

sin

cos

0

0

0

cos

-sin

0

0

1

0

0

0

0

1

0

0

sin

cos

0

-sin

0

cos

0

0

0

0

1

0

0

0

1

0

0

0

1

<


rotation in the XY plane               rotation in the YZ plane               rotation in the XY plane

Для однородных вращений, 3x3 субматрица, разграниченная [0,0] и [2,2] - orthonormal. То есть каждая строка - вектор модуля и перпендикулярна к другим строкам; скалярное (точечное) программа двух строк нулевое. Столбцы - также векторы модуля, которые являются перпендикулярными к друг другу. Программа orthonormal

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

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

ОБРАТИТЕ ВНИМАНИЕ На acedTablet () функция использует 3x3 матрицу, чтобы преобразовать 2-ые точки. AcedNEntSel () функция использует 4x3 матрицу преобразования, которая является подобной 4x4 матрица преобразования, но это обращается с точкой как строка.


MDI-РАСШИРЕННЫЙ Уровень


Эти дополнительные шаги будут заставить ваше приложение интегрировать полностью с МНОГОДОКУМЕНТАЛЬНЫМ ИНТЕРФЕЙСОМ.

§         Рассматривают перемещение вашего AcEditorReactor:: commandXxx () и AcEditorReactor:: LispXxx () повторные вызовы, чтобы работать вместо этого от AcDocMananagerReactor::documentLockModeWillChange () и AcDocMananagerReactor::documentLockModeChanged () уведомления. Тогда они объяснят прикладные операции контекста выполнения, которые были предварительно трудны обнаружить ObjectARX-приложениями.

Избегают использовать acedCommand (). Используйте AcApDocManager:: setStringToExecute () вместо этого, потому что это имеет параметр документа.

Избегают использовать kLoadDwg и kUnloadDwg случаи, и использовать documentToBeCreated () и documentToBeDestroyed () реакторы вместо этого.

Поддерживают документированную - независимую особенность базы данных. Для большего количества информации, см. " Документированные - независимые Базы данных " на странице 439.

команды много-документа Поддержки. Для подробной информации, см. " Команды Много-документа " на странице 432.

Поддерживают все события, которые происходят в пределах прикладного контекста выполнения. Для подробной информации, см. " Прикладной Контекст Выполнения " на странице 436.



MDI-совместимый


ObjectARX-приложения (и приложения ActiveX и COM, но не обязательно Визуальные приложения LISP) которые выполняют все критерии, необходимые, чтобы быть успешно выполненными в MDI AutoCAD. Эти критерии перечислены в секции “ MDI-ЗНАЮЩИЙ Уровень ” на странице 424. ObjectARX-приложения могут регистрировать себя как MDI-ЗНАЮЩИЕ,  вызывая

 acrxDynamicLinker->registerAppMDIAware(pkt);

При получении kInitAppMsg в пределах их acrxEntryPoint () функция.



MDI-СПОСОБНЫЙ Уровень


Достижение этого уровня согласия вовлекает создание вашей работы кода так эффективно и естественно в режиме MDI, как это делает (или делало) в режиме SDI.

§

переключение документа поддержки.

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

§         поддерживают хорошую работу.

Когда это становится временем, чтобы смотреть на выполнение{*работу*}, много разыменования указателя резидента динамическая к тому, что было прежде статические адреса, может трясина вниз выполнения{*работы*} программы. В этом случае, альтернатива была бы должна обслужить{*поддержать*} статический буфер памяти элементов текущего документа, который будет просмотрен в от и выписан к документированным - определенным элементам динамической памяти.



MDI-ЗНАЯ Уровень


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

ObjectARX-приложение должно встретить{*выполнить*} требования этого уровня совместимости перед способностью законно установить SDI

переменную системы в 0.

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

N Приложения не может сохранять данные " в документ " в глобальных или статических переменных.

N, если команда выполнена от прикладного контекста, это должно обеспечить явный документ блокировка.

N Автошепелявящиеся - зарегистрированные команды должен быть подготовлен, чтобы действовать в пределах множественных государств AutoLISP.

N Приложения должен регистрировать себя как MDI-ЗНАЮЩИЕ в течение их AcRx:: kInitAppMsg обработчик в acrxEntryPoint ().

Каждое требование описано подробно в следующих секциях.



Менеджер профилей


Менеджер профилей позволяет Вам исполнять все операции, обеспеченные в позиции табуляции Profiles Диалога Опций. Этот API состоит из двух классов, и несколько методов имели обыкновение управлять параметрами пользователя легко.



Менеджер Размещения


Вы можете управлять объектами AcDbLayout,  используя AcApLayoutManager класс.

AcApLayoutManager класс позволяет Вам

§         Создают размещения

§         Удаляют размещения

§         Переименовывают размещения

§         Копия и размещения аналога

§         Набор текущее размещение

§         Находят специфическое размещение

§         Набор графические характеристики размещения

Имеется один образец менеджера размещения в приложение. Менеджер размещения всегда работает на текущем размещении.



Менеджер Свойства объекта API


Менеджер Свойства объекта (OPM) - инструмент, который позволяет пользователям рассматривать и изменять свойства примитивов и объектов легко. См. Руководство программиста AutoCAD для подробной информации относительно особенностей OPM и интерфейса пользователя.

OPM поддерживает два вида свойств. Первый - свойства, которые определены для объекта статически во времени компиляции, названных статических свойствах.

Динамические свойства, которые являются свойствами, которые могут быть добавлены и конфигурирован во время выполнения, также поддержаны. Для статических свойств, ObjectARX-приложения могут обеспечивать COM классами “обертки” для их заказных объектов. OPM будет использовать эти классы, чтобы определить, который статические свойства являются ли доступным для того объекта и как к “flavorize” те свойства для дисплея (типа, свойство требуют заказного поля со списком в OPM, или должны поднять диалог для редактирования свойства?). Для динамических свойств, ObjectARX, VB, или приложений VBA может создавать “ свойство plug-ins

” использование OPM

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



Менеджер точки ввода


ObjectARX обеспечивает  менеджера ввода точки классом, AcEdInputPointManager.

Один входной менеджер точки инициализирован для каждого активного документа в AutoCAD.

Следующая функция возвращает входного менеджера точки для документа:

virtual AcEdInputPointManager *

AcApDocument::inputPointManager() const;

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

AcEdInputPointManager обеспечивает функцию, disableSystemCursorGraphics(), который отключает курсор системы.

ObjectARX поддерживает индекс,  вызывает, чтобы отключить курсор системы для каждого документа, так, если ваше приложение вызывает disableSystemCursorGraphics() множественные времена, это должно вызвать enableSystemCursorGraphics() то же самое число раз, чтобы восстановить курсор системы.

ПРЕДУПРЕЖДЕНИЕ! Отключение графики курсора системы должно быть сделано экономно, обычно только, когда определенная приложением команда запрашивает ввод пользователя.

Вы должны обеспечить заказную графику курсора, если Вы отключаете графику курсора системы.

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

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

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

Принудительный выбор примитива можно позволять при следующих условиях:

§         в течение входного приобретения точки без активного режима объектной привязки

§         в течение выбора отдельного примитива точки

§         в течение неподвижности команды

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



Менеджер транзакции


Операционный менеджер - глобальный менеджер объект, подобный редактору, который отвечает за транзакции поддержания. Это - образец AcTransactionManager и поддержан в системном реестре системы. Вы можете получить это от системного реестра системы, используя макрокоманду actrTransactionManager, который расширяется до

#define actrTransactionManager \

AcTransactionManager::cast ( acrxSysRegistry()->at(AC_TRANSACTION_MANAGER_OBJ) )

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

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

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

Операционный менеджер объект создан и управляется системой. Вы не должны удалить это.



Метки для Диалоговых окон и Неперекрывающих расположений


Adsdlg.h файл определяет два типа метки:

§

ads_hdlg идентифицирует диалоговые окна. Ads_new_dialog () функция назначает новое диалоговое окно,  метка ads_hdlg для идентификации диалогового окна в наиболее последующий вызывает к функциям PDB, пока ads_done_dialog () не вызван.

§         ads_htile идентифицирует отобранное неперекрывающее расположение в пределах функций повторного вызова.

Если ads_new_dialog () сбои, это устанавливает метку в NULL или BAD_DIALOG.



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


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.



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;

}



Мировая система координат


Мировая система координат (WCS) - система координат “ссылки”.

WCS - установленная система координат; все другие системы координат определены относительно WCS. Это - система координат, в которую вся образцовая координатная геометрия была помещена согласно ее блочной вставке. Если любая из образцовой координатной геометрии не была включена в блочную вставку, то модель и мировые координаты идентичны.



Мягкие Указатели


Мягкий указатель - просто указатель на объект. Это не защищает упомянутый объект от чистки.

Примеры мягких ссылок указателя

§         Xdata ссылки - мягкие указатели.

§         Постоянные реакторы - мягкие указатели.

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



Мягкое Монопольное использование


Мягкое монопольное использование ИДЕНТИФИКАТОР (типа AcDbSoftOwnershipId) не защищает находящийся в собственности объект от чистки. Следующее - примеры мягкого монопольного использования:

§         В большинстве случаев, таблицы идентификаторов - мягкие владельцы их элементов (исключения включают блок, *PAPER_SPACE, *PAPER_SPACE0, и уровень 0; для этих элементов, таблица идентификаторов обслуживает{*поддерживает*} жесткую ссылку{*справочники*}).

§         Словари - мягкие владельцы их входов (но Вы можете помечать словарь, чтобы быть жестким владельцем его входов).



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


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



Много-документные команды


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

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

Чтобы синхронизировать действия множественных команд, осуществьте реактор, который перегружает следующие AcApDocManager реакторные функции:

virtual void

documentActivated( AcApDocument* pActivatedDoc );

virtual void

documentToBeDeactivated( AcApDocument* pDeActivatedDoc );

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

Эти повторные вызовы вызваны всякий раз, когда пользователь нажимает на различный документ, чтобы активизировать это. Реакторы должны только использоваться на AcApDocManager, когда в начальной команде как раз перед запросом ввода пользователя, в точке, когда переключение документа должно быть поддержано. Реактор должен быть удален, когда любой или все такие подсказки закончены или отменены. От повторного вызова, вызовите:


virtual Acad::ErrorStatus

sendStringToExecute(

AcApDocument* pAcTargetDocument,

const char * pszExecute,

bool bActivate = true,

bool bWrapUpInactiveDoc = false) = 0;

Эта функция стоит в очереди строка, которую нужно интерпретировать следующий раз,  указанный документ активизирован. Строка должна типично быть обращение команды (мы назовем это вторичной командой), но можем также быть выражение AutoLISP, фрагмент команды, или лексема меню. Строковый предел - 296 байтов, так что более длинные последовательности должны быть осуществлены как команда SCRIPT, выполняющая временный сценарий, или как выражение AutoLISP, чтобы загружать и выполнить программу AutoLISP. Новый документ будет блокирован согласно уровню блокировок новой команды как определено в течение его регистрации.

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

ОБРАТИТЕ ВНИМАНИЕ, поскольку эта методика вовлекает запрос от documentActivated () метод, Вы должны передать kFalse в bActivate параметр, чтобы избежать ошибок или бесконечных циклов.

Также, чтобы управлять потоком контроля поперек документов, этот повторный вызов должен поддержать любой переход, заявляют прикладные потребности. Например, неповторно используемый вариант мог помнить оригинал документа, и флажок для каждого документа, чтобы указать,является ли это уже активным, и поэтому не должны вызвать sendStringToExecute ().

Когда команда много-документа заканчивает, приложение управления должно убедиться, что  команда не оставила никакие ждущие обработки состояния команды в предыдущих документах. Приложение может делать это,  посылая ESC или ВВОДИТЬ в документы, которые это пересекло через, используя bWrapUpInactiveDoc параметр sendStringToExecute (). Если это не сделано, документы могут быть оставлены в не-статическом состоянии.

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



И начальные и вторичные команды должны быть зарегистрированы через acedRegCmds () или acedDefun (). Начальная команда должна быть закодирована, чтобы закончить успешно на ее собственный, в случае, если пользователь решает исполнять полную команду без того, чтобы переключить документы. Вторая команда не должна быть полная команда, только часть команды, которая может быть вызвана, чтобы накопить информацию (внедренный в статической структуре) из различных открытых документов, и применять результатов. Вторую команду, вероятно, также придется закодировать такой, что это может быть повторно введено во все же другом документе, если именно так команда, как предполагается,  будет структурирована.

Помните ту ОТМЕНУ, выполняет отдельно в каждом документе при проектировании этих конструкций.

ОБРАТИТЕ ВНИМАНИЕ, что  "нормальная" acedSSGet() не жизнеспособна, потому что это может запрашивать множественные времена, таким образом не возвращая любой набор выборов в продвижении. Вместо этого, acedEntSel() используется, потому что это или возвращает примитив, или RTNONE, означая пользователя действительно сделан, или RTCAN, который может быть или реальная отмена или "перемещенный в другой документ" сигнал. Установите местный "done" флажок, исполните действие, затем стойте в очереди ESC к каждому другому активному документу так, чтобы команда была закончена в том документе следующий раз,  пользователь идет к щелчку в это.


Модификация Системного реестра при Инсталляции Приложения 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.



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


Объект, который неявно принадлежит базе данных скорее чем другой объект базы данных,  называется корневым объектом. База данных содержит десять корневых объектов: эти девять таблиц идентификаторов и названный объектный словарь. Все файловые операции начинаются,  регистрируя из корневых объектов базы данных. См. “ Запись в файл Объекта ” на странице 95.

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

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

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

Каждая таблица идентификаторов имеет специфический тип отчета{*записи*} таблицы идентификаторов.

объект AcDbDictionary может иметь любой объект AcDbObject.

объект Any AcDbObject может иметь словарь расширения{*продления*}; объект имеет его словарь расширения{*продления*}.

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



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


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

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

Примитивы 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



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


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

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

ОБРАТИТЕ ВНИМАНИЕ на набор Выборов, и названия{*имена*} примитива энергозависимы; они применяются только, в то время как Вы работаете над рисунком к AutoCAD, и они потеряны при выходе от AutoCAD или переключения к другому рисунку.

Для наборов выбора, которые также применяются только к текущему сеансу, энергозависимость названий{*имен*} не излагает никакую проблему, но для примитивов, которые сохранены в базе данных рисунка, это делает. Приложение, которое должно обратиться{*отнестись*} в разное время к тем же самым примитивам в том же самом рисунке (или рисунки), может использовать маркеры{*дескрипторы*} примитива, описанные в “ Маркеры{*дескрипторы*} Примитива и Их Использования ” на странице 216.



Начало с ObjectDBX


Следующее - некоторые общие пункты, Вы должны знать перед использованием ObjectDBX.



Наследование Нового Класса от AcEdJig


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

§         AcEdJig:: дискретизатор (), который приобретает геометрическое значение (угол, расстояние, или пункт{*точка*})

§         AcEdJig:: модификация (), который анализирует,  геометрическое значение и сохраняет это или модифицирует объект

§         AcEdJig:: объект (), который возвращает указатель на объект, который будет восстановлен



Наследование Заказных примитивов


AcDbEntity - базовый класс для всех объектов базы данных, имеющих графическое представление.

AcDbEntity получен из AcDbObject. Создание заказного объекта возводит в степень следующие шаги.

Создавать заказной объект

1 Получают класс пользователя из AcDbEntity.

2 Перегружаемый все необходимые функции AcDbObject. См. главу 12, “ Происходящий от AcDbObject. ”

3 Перегрузят требуемые функции AcDbEntity. Это будет обсуждено в следующих разделах.

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

5, если Вы хотите поддержать,  команда MATCHPROP, осуществляет AcDbMatchProperties как расширение{*продление*} протокола.

6, если Вы хотите создать заказной, перемещаетесь{*перетаскиваете*} последовательность для вашего объекта, осуществляете вашу собственную версию AcEdJig.

Следующие разделы обсуждают эти темы{*разделы*} более подробно.



Настройка Дизайн-центра AutoCAD


Относительно просто создать приложение, чтобы обеспечить заказное содержание для Дизайн-центра AutoCAD, используя ATL AppWizard. Этот пример доступен в ObjectARX SDK, но это может быть создано на пустом месте после шагов ниже. Выборка добавляет текстовые файлы (с .txt расширениями{*продлениями*}) как содержание. Одиночный щелчок на текстовом файле покажет содержание в окне описания (если это активно). Двойной щелчок будет брать содержание файла и вставлять это как mtext в пространство модели в центре текущей области просмотра, используя текущий текстовый стиль.



Недавно созданные объекты и транзакции


Имеются два способа иметь дело недавно с созданными объектами в операционном контексте управления.

Рекомендуемый подход состоит в том, чтобы закрыть () объект после добавления этого к базе данных или соответствующему контейнеру и сохранять ИДЕНТИФИКАТОР, который возвращен Вам. Право после закрытия объекта, который передает{*совершает*} это базе данных, Вы может использовать getObject () функция, чтобы получить новый указатель для ваших операций.

Даже если Вы вызываете близко () на объекте после добавления этого к базе данных, ее создание будет уничтожено, если содержащая транзакция прервана. См. “ Смешивание Модели Транзакции с Открытым и Близким Механизмом ” на странице 455.

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

Тогда добавьте это к самой современной транзакции, использующей AcTransactionManager::addNewlyCreatedDBRObject () или AcTransaction:: addNewlyCreatedDBRObject. Теперь, когда это связано с транзакцией, это будет совершено{*передано*} или несоздан в зависимости от того, заканчиваются ли транзакции успешно или аварийное прекращение работы.



Немедленная и задержанная передача событий


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

cancelled()

                Уведомление послано, когда AcDbObject::cancelled()

вызван.

openedForModify()

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

copied()

Уведомление послано, когда объект скопирован.

goodbye()

Уведомление послано, когда объект собирается быть удаленным из памяти.

Немедленные уведомления вызваны в то же самое время как соответствующее событие. Например, когда assertWriteEnabled () вызван первый раз на объекте, openedForModify () уведомление немедленно послано всем реакторам на том объекте.

Следующие события посланы с задержкой:

n modified()

n subObjModified()

n erased()

n modifyUndone()

n modifiedXData()

n unappended()

n reappended()

n graphicsModified()

modified() уведомление о AcDbObjectReactor - пример передавать-разового уведомления. Предположим, что объект открыт, и функция модификации - обратился к этому. Функция модификации вызывает assertWriteEnabled() и все реакторы получают openedForModify() реакция. Последующие функции модификации на объекте не приводят к любому дальнейшему уведомлению. Когда объект наконец закрыт, modified() уведомление послано. Однако, если новичок хотел называть cancel()

на объекте вместо cancelled(), cancel()

уведомление будет послано вместо cancelled() уведомление.

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

При попытке изменять объект прежде, чем совершающийся процесс закончен, есть причины AutoCAD, чтобы прерваться с сообщением об ошибках eWasNotOpenForWrite или eInProcessOfCommitting.


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

 AcDbObjectReactor::objectClosed(AcDbObjectId ObjId);

 AcTransactionReactor::transactionEnded(int NumActiveAndSuccessful);

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

В transactionEnded() уведомление, Вы можете использовать numActiveTransactions(), чтобы сделать запрос операционного менеджера, чтобы видеть, сколько сделок активны. Если не имеется никаких активных сделок, то сделка закончилась, и все объекты в сделке были совершены.

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

 AcTransactionReactor::endCalledOnOutermostTransaction()

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

Вместо этого, ждите, пока целая сделка не закончена прежде, чем Вы исполняете любые операции на этих объектах.


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


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

Acad::ErrorStatus

AcDbDatabase::setCecolor(const AcCmColor& color);

AcCmColor AcDbDatabase::cecolor() const;



NullObjectId ()


Этот метод используется, чтобы сообщить объекту COM, что это больше не представляет объект резидента базы.



Объектная Привязка


AcedOsnap () функция находит точку,  используя один из Режимов объектной привязки AutoCAD. Поспешные режимы определены в строковом параметре.

В следующем примере, запрос к acedOsnap () ищет midpoint линии около pt1.

acedOsnap(pt1, "midp", pt2);

Следующий запрос ищет или midpoint или оконечную точку линии, или центра дуги или круга —, какой бы ни - самый близкий pt1.

acedOsnap(pt1, "midp,endp,center", pt2);

Третий параметр (pt2 в примерах) установлен в поспешную точку, если найдены. AcedOsnap () функциональные возвращения RTNORM, если точка найдена.

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



Объектные Ссылки


Объектная ссылка может быть или интенсивно или программное обеспечение, и это может быть или ссылка монопольного использования или ссылка указателя. Жесткое или мягкое различие указывает,является ли упомянутый объект необходимым для существования объекта, который обращается{*относится*} к этому. Жесткая ссылка указывает, что объект зависит от упомянутого объекта для его выживания. Мягкая ссылка указывает, что объект имеет некоторые отношения к упомянутому объекту, но это - не существенное{*необходимое*}.

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

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

Например, в следующем числе{*рисунке*}, сдвоенные линии указывают ссылки{*справочники*} монопольного использования.

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



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


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

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

Mode

Description

kOsModeEnd

Endpoint

kOsModeMid

Midpoint

kOsModeCen

Center

kOsModeNode

Node

kOsModeQuad

Quadrant

kOsModeIns

Insertion

kOsModePerp

Perpendicular

kOsModeTan

Tangent

kOsModeNear

Nearest

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



Объекты Размещения


Информация относительно размещений сохранена в образцах 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 словаре.



Объявление и определение классов расширения протокола


Пример, включенный в конце этой главы обеспечивает простую иллюстрацию расширения протокола. Это определяет “температурный” класс расширения протокола собственности. Заданное по умолчанию выполнение определено для AcDbEntity, и определенные выполнение определены для AcDbCircle и AcDbRegion.

Пример обслуживает как модель для более сложный (и реалистический) использования ObjectARX механизма расширения протокола. Базовый класс для этого расширения протокола, названного AsdkEntTemperature, получен из AcRxObject. Этот класс определяет виртуальные функции, которые будут унаследованы полученными классами расширения протокола, AsdkDefaultTemperature, AsdkCircleTemperature, и AsdkRegionTemperature. В этом примере, имеется только одна функция: reflectedEnergy().

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

Первый шаг в использование расширения протокола должен объявлять и определить каждый из классов расширения протокола. Базовый класс, AsdkEntTemperature, является абстрактным классом, который определен, используя ACRX_NO_CONS_DEFINE_MEMBERS () макрокоманда. Этот класс будет в конечном счете зарегистрирован как часть ObjectARX

иерархии классов.

Дочерние классы определены, используя стандартный синтаксис C++ для наследования новых классов. Эти классы не должны быть зарегистрированы в ObjectARX

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

для них.

Для каждого класса, Вы осуществляете функции, которые составляют расширение протокола. В этом примере, каждый класс имеет только одну функцию, reflectedEnergy(), который вычисляет температуру для примитива.



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


Поскольку объекты созданы в AutoCAD, они добавлены к соответствующему контейнерному объекту в его базе данных. Объекты добавлены к записям в блочной таблице. Записи Таблицы идентификаторов добавлены к соответствующим таблицам идентификаторов. Все другие объекты добавлены к словарю имен объектов или к объектам, которые принадлежат другим объектам (и, в конечном счете, тем же словарям), или к словарю расширения. Сценарий в следующем разделе – “Создании Объектов в AutoCAD, ” детализирует этот процесс. Словари Расширений обсуждены в разделе “Словарь Расширения” на странице 89.

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

·         набор девяти таблиц идентификаторов, который включает блочную таблицу, таблицу уровня, и linetype таблицу. Блочная таблица первоначально содержит три записи: *MODEL_SPACE, и два пространства листа, называемые *PAPER_SPACE и *PAPER_SPACE0. Эти блочные записи таблицы представляют модельное пространство и два предопределенных бумажных пространственных размещения. Таблица уровня первоначально содержит одну запись - уровень 0. Linetype таблица первоначально содержит тип линии CONTINUES.

·         объектный словарь имен. Когда база данных создана, этот словарь уже содержит четыре словаря баз данных: словарь GROUP, MLINE, LAYER, и PLOT. В пределах словаря стиля MLINE, стиль STANDART - всегда существует.

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



ObjectARX функциональные коды типа результата


Следующие коды типа результата - коды состояния, возвращенные большинством ObjectARX глобальные функции, чтобы указать успех, отказ{*неудачу*}, или специальные условия (типа отмены пользователя):

Коды результата Библиотечной функции

Код

 Описание

RTNORM

 Пользователь ввел имеющее силу значение

RTERROR

 Функциональный запрос потерпел неудачу

RTCAN

 Пользователь ввел ESC

RTREJ

 AutoCAD отклонил запрос как недействительный

RTFAIL

 Связь AutoLISP потерпела неудачу

RTKWORD

 Пользователь ввел клавиатуру или произвольный текст

Значения этих кодов, полученных в итоге в таблице, следующие:

RTNORM

 Библиотечная функция преуспела.

RTERROR

 Библиотечная функция не преуспевала; это столкнулось с восстанавливаемой ошибкой.

Условие RTERROR исключительно из следующих специальных случаев:

RTCAN

 Пользователь AutoCAD ввел ESC, чтобы отменить запрос. Этот код возвращен вводом пользователя (acedGetxxx) функции и следующими функциями: acedCommand, acedCmd, acedEntSel, acedNEntSelP, acedNEntSel, и acedSSGet.

RTREJ

 AutoCAD отклонил операцию как недействительный. Запрос операции может быть неправильно сформирован, типа недействительного acdbEntMod () запрос, или это просто не может иметь силу для текущего рисунка.

RTFAIL

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

RTKWORD

 Пользователь AutoCAD ввел ключевое слово или произвольный ввод вместо другого значения (типа точки). Ввод пользователя acedGetxxx () функции, также как acedEntSel, AcedEntSelP, acedNEntSel, и acedDragGen, возвращают этот код результата.

ОБРАТИТЕ ВНИМАНИЕ Не, все ObjectARX глобальные функции возвращают эти коды состояния; некоторые возвращаемые значения непосредственно. Также, ввод пользователя (acedGetxxx, acedEntSel, acedEntSelP, acedNEntSel, и acedDragGen) функции могут возвращать код типа результата RTNONE, и acedDragGen () указывает произвольный ввод,  возвращая RTSTR вместо RTKWORD.



ObjectARX-эксклюзивный тип данных


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

Для подробной информации, см. Руководство Настройки AutoCAD, приложение D, при Рисунке Форматов файла Обмена. ”



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


Основные классы, вовлеченные в создание и управление размещениями - следующее:

AcDbLayout

AcDbPlotSettings

AcDbPlotSettingsValidator

AcDbLayoutManager

AcApLayoutManager

AcDbLayoutManagerReactor

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



ObjectDBX Библиотечные Изменения


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

ObjectDBX библиотеки

Release 14 Library Name

AutoCAD 2000 Library Name

acfirst.dll

ac1st15.dll

ism.lib

acISMobj15.lib

libacge.lib

acge15.lib

libacgex.lib

acgex15.lib

libacbr.lib

acbr15.lib

Not present

achapi15.lib

Not present

acdb15.lib

Not present

acrx15.lib

Not present

acutil15.lib

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

Класс сервиса приложения

Когда ObjectDBX используется, чтобы создать ведущее приложение, код в ObjectDBX библиотеке ожидает, что  ведущее приложение обеспечит это некоторыми услугами; например, файл находит механизм. Когда Вы записываете ObjectDBX

ведущее приложение, Вы требованы, чтобы осуществить эти услуги, которые будут использоваться и,  ObjectDBX

непосредственно, и потенциально другими приложениями DBX.

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

Файл заголовка для прикладных услуг - dbapserv.h. Классы и методы в этом файле заголовка относятся к одной из трех категорий:

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

§         Те Вы можете перегружать, но это имеет заданное по умолчанию выполнение, которое минимально удовлетворит код базы данных. Они объявлены виртуальными.

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

Это требовано, что любое ObjectDBX ведущее приложение должно обеспечить класс, полученный из AcDbHostApplicationServices. Это отличается от пути DWG Отключенный, работал, где заданное по умолчанию обслуживание обеспечивалось. Детальное описание класса существует в ObjectARX Ссылке, где каждый метод описан с его заданным по умолчанию выполнением (если это имеет один), что Вы должны делать, чтобы перегрузить метод успешно, и как вызвать метод. Когда ваше приложение инициализирует, это должно создать образец вашего класса, полученного из AcDbHostApplicationServices. Конфигурируйте это, по мере необходимости и делайте объект доступным приложению,  вызывая глобальную функцию acdbSetHostApplicationServices ().



ObjectDBX Библиотеки


ObjectDBX библиотеки содержат сведения, которые позволяют заказным объектам (геометрия, компоненты, не-графические объекты, и так далее) работать как расширения или заказные объекты внутреннего AutoCAD. Файлам, которые осуществляют эти объекты,  дают расширение .dbx, который замещает расширение Базы данных. DBX файл - в основном ObjectARX-приложение, которое было написано, чтобы работать с ObjectDBX библиотеками вместо с ObjectARX библиотеками (AutoCAD).



Оболочка (Shell)


Оболочка - список лиц, которые могли бы быть связаны и могут иметь отверстия в них.

Оболочка определена числом уникальной вершины, список вершины (pVertexList), число лиц (faceListSize), и списка лица, который состоит из числа точек в данном лице, сопровождаемом индексом в списке вершины каждой вершины для того лица. Cигнатура для Shell () функция

virtual Adesk::Boolean

AcGiWorldGeometry::shell(

const Adesk::UInt32 nbVertex,

const AcGePoint3d* pVertexList,

const Adesk::UInt32 faceListSize,

const Adesk::Int32* pFaceList,

const AcGiEdgeData* pEdgeData = NULL,

const AcGiFaceData* pFaceData = NULL,

const AcGiVertexData* pVertexData = NULL

const struct

resbuf*pResBuf = NULL) const = 0;

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

AcGi многоугольники и оболочки с лицами пять или большим количеством сторон также разрушены в треугольники прежде, чем послались, чтобы быть отображенным. Наличие AcGi триангулирует многоугольник, или лицо оболочки может быть дорогостоящее в терминах памяти и скорости, так что это рекомендует, чтобы Вы использовали три - или четыре - sided лица в оболочках, чтобы создать лица или многоугольники с пять или большее количество сторон. Тем путем, примитив не будет помещен через медленный шаг триангуляции.

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

Вершина в данном лице должна быть компланарна. Не имеется никакой подразумеваемой связности между лицами.

Данные Края для оболочки перечислены в порядке, подразумеваемом списком лица. Например, в первом лице, vertex0 к vertex1 определяет,  первый край, vertex1 к vertex2 определяет второй край, и так далее до последней вершины лица, которое соединяется с первой вершиной, как показано ниже.




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

Порядок данных лица, если есть, следует за упорядочением списка лица для оболочки.

Следующее - пример оболочки с цветными данными, приложенными к граням и стоит и данным видимости, приложенным к граням. Оболочка составлена из двух треугольников в различных планах, которые совместно используют общий край. Общий край имеет видимость силуэта. Это означает, что, когда команда HIDE - в действительности и переменная AutoCAD DISPSILH равняется 1 (силуэты дисплея включены), общий край между лицами оттянут только, если оба лица в области просмотра находятся на той же самой стороне общего края. В этом случае, одно лицо - позади другой, так что это не рисует:

Adesk::Boolean

AsdkShellSamp::worldDraw(AcGiWorldDraw* pW)

{

// Fill the faces with the current color.

//

pW->subEntityTraits().setFillType(kAcGiFillAlways);

// Create vertices.

//

Adesk::UInt32 numVerts = 4;

AcGePoint3d *pVerts = new AcGePoint3d[numVerts];

pVerts[0] = AcGePoint3d(0.0, 0.0, 0.0);

pVerts[1] = AcGePoint3d(0.0, 1.0, 0.0);

pVerts[2] = AcGePoint3d(1.0, 1.0, 0.0);

pVerts[3] = AcGePoint3d(1.0, 0.0, 2.0);

// Create two faces.

//

Adesk::UInt32 faceListSize = 8;

Adesk::Int32 *pFaceList

= new Adesk::Int32[faceListSize];

// Assign vertices for face 1.

//

pFaceList[0] = 3; // Three vertices in the face

pFaceList[1] = 0; // pVerts[0]

pFaceList[2] = 1; // pVerts[1]

pFaceList[3] = 2; // pVerts[2]

// Assign vertices for face 2.

//

pFaceList[4] = 3; // Three vertices in the face

pFaceList[5] = 0; // pVerts[0]

pFaceList[6] = 2; // pVerts[2]

pFaceList[7] = 3; // pVerts[3]

// Apply colors to edges.

//

AcGiEdgeData edgeData;

int numEdges = 6;

short *pEdgeColorArray = new short[numEdges];

pEdgeColorArray[0] = kRed;

pEdgeColorArray[1] = kYellow;

pEdgeColorArray[2] = kGreen;



pEdgeColorArray[3] = kCyan;

pEdgeColorArray[4] = kBlue;

pEdgeColorArray[5] = kMagenta;

edgeData.setColors(pEdgeColorArray);

// Apply visibility to edges and make the common edge

// between two faces have silhouette visibility during

// the HIDE command with AutoCAD variable DISPSILH = 1.

//

Adesk::UInt8 *pEdgeVisArray

= new Adesk::UInt8[numEdges];

edgeData.setVisibility(pEdgeVisArray);

pEdgeVisArray[0] = kAcGiVisible;

pEdgeVisArray[1] = kAcGiVisible;

pEdgeVisArray[2] = kAcGiSilhouette;

pEdgeVisArray[3] = kAcGiSilhouette;

pEdgeVisArray[4] = kAcGiVisible;

pEdgeVisArray[5] = kAcGiVisible;

// Apply colors to faces.

//

AcGiFaceData faceData;

int numFaces = 2;

short *pFaceColorArray = new short[numFaces];

pFaceColorArray[0] = kBlue;

pFaceColorArray[1] = kRed;

faceData.setColors(pFaceColorArray);

pW->geometry().shell(numVerts, pVerts, faceListSize,

pFaceList, &edgeData, &faceData);

delete [] pVerts;

delete [] pFaceList;

delete [] pEdgeColorArray;

delete [] pFaceColorArray;

return Adesk::kTrue;

}

Объект AcGiVertexData содержит единственный флажок, который определяет, как вершина в оболочке упорядочивается. Этот флажок установлен и делается запрос со следующими функциями:

virtual void

AcGiVertexData::setOrientationFlag(AcGiOrientationType oflag);

virtual AcGiOrientationType

AcGiVertexData::orientationFlag() const;

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

§         kAcGiClockwise

§         kAcGiCounterClockwise

§         kAcGiNoOrientation

Ориентация вершины в списке лица оболочки указывает видимую сторону лица. Например, если вершина определена как, по часовой стрелке и вершина для данного лица перечислена в по часовой стрелке порядке, то то лицо видимо. В этом случае, лица с вершиной в против часовой стрелки порядке невидимы.


Обрабатывающие примитив Функции


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

§

acdbEntMod ()

§          acdbEntMake ()

§          acdbEntDel ()

§          acedEntSel ()

§          acedNEntSel ()

§          acedNEntSelP ()

§          acdbEntUpd ()



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


Функции 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, идентифицирует имя набора выбора.


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


Обработка окна редактирования


Действия и повторные вызовы, чтобы обработать окна редактирования подобны тем для слайдеров.

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

Следующие типовые проверки программы значение но не восстанавливают изображение этого:

static void CALLB

edit_action(ads_callback_packet *cbpkt)

{

int reason = cbpkt->reason;

if ((reason == CBR_LOST_FOCUS) || (reason == CBR_SELECT)) {

// Check range, syntax, etc. on transient value.

//

...

}

}

Чтобы показывать альтернативу, этот пример проверяет CBR_LOST_FOCUS скорее чем CBR_DOUBLE_CLICK.



Обработка ошибок


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

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;

}


Обработка Ошибок от Вызванных Функций


Когда acedInvoke() возвращает RTNORM, это подразумевает, что внешняя функция была вызвана и возвращена успешно. Это не подразумевает, что внешняя функция успешно получила результат; чтобы получить эту информацию, ваша программа должна осмотреть параметр результата. Если внешняя функция успешна и предполагается к возвращаемым значениям, результат указывает на список буфера результата, содержащий один или большее количество значений. Если внешняя функция потерпела неудачу, параметр результата установлен в NULL.

Параметр результата - также NULL, если внешняя функция не возвращает результат.

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

struct resbuf *xfcnlist, *xresults;

// Build the invocation list, xfcnlist.

rc = acedInvoke(xfcnlist, &xresults);

if (rc != RTNORM) {

// Couldn't call the function—report this error (or even abort).

return BAD;

}

if (xresults == NULL) {

// Function was called but returned a bad result.

return BAD;

}

// Look at return results and process them.



Обработка полей ввода


Ваша программа имеет некоторый контроль над полями ввода в текущем диалоговом окне при инициализации время и действие (повторный вызов) время. Этот раздел представляет обрабатывающие поля ввода функции.



Обработка Радио-Кластеров


"Радио" кнопки появляются в кластерах радио. Значение каждой индивидуальной "радио" кнопки является или “1” для на или “0” для от; значение кластера радио - ключевой атрибут в настоящее время отобранной кнопки. Пакет PDB управляет значениями "радио" кнопок в кластере, и гарантирует, что только каждый находится на одновременно.

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

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

ads_action_tile(hdlg, "view_sel", pick_view);

...

static void CALLB

pick_view(ads_callback_packet *cbpkt)

{

char value[TILE_STR_LIMIT];

strcpy(value, cbpkt->value);

if (strcmp(value, "front") == 0)

show_which = 0;

else if (strcmp(value, "top") == 0)

show_which = 1;

else if (strcmp(value, "left") == 0)

show_which = 2;

else if (strcmp(value, "right") == 0)

show_which = 3;

}

Предшествующие примеры показывают каждую "радио" кнопку, связанную с единственной переменной, которая берет множественные значения. Они могут также вызывать дополнительные действия, типа отключения выборов в вашем диалоговом окне. Если кластер радио - большой, удобно сохранить связанные значения в таблице. Если Вы используете таблицу, структурируете это так, чтобы это не зависело от порядка кнопок в пределах кластера. Пакет PDB не налагает это ограничение, и порядок может изменяться, если DCL изменяется.



Обработка Символьного типа


ObjectARX обеспечивает пакет обрабатывающих символа функций, как показано в таблице, которая следует. Преимущество этого пакета по пакету стандартной библиотеки для C, ctype.h, состоит в том, что эти функции являются независимыми от любого определенного набора символов и не связаны к ASCII. Они настроены к потоку конфигурация языка AutoCAD. В других отношениях, они ведут себя подобно их стандартным копиям C.

Функции Символьного типа

Имя функции

Цель

AcutIsAlpha

 Проверяет, что символ алфавитный

AcutIsUpper

 Проверяет, что символ верхнего регистра

AcutIsLower

 Проверяет, что символ - нижний регистр

AcutIsDigit

 Проверяет, что символ - цифра

AcutIsXDigit

 Проверяет, что символ - шестнадцатеричная цифра

AcutIsSpace

 Проверяет, что символ - символ незаполненного пространства

AcutIsPunct

 Проверяет, что символ - символ пунктуации

AcutIsAlNum

 Проверяет, что символ алфавитно-цифровой

AcutIsPrint

 Проверяет, что символ печатаем

AcutIsGraph

 Проверяет, что символ графический

AcutIsCntrl

 Проверяет, что символ - управляющий символ

AcutToUpper

 Преобразовывает символ к верхнему регистру

AcutToLower

 Преобразовывает символ к нижнему регистру

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

int cc = 0x24;

cc = acutToUpper (cc);



Обработка Слайдеров


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

Хотя Вы не требованы, чтобы проверить код причины, рекомендуется, чтобы Вы делали так, чтобы привести обработку. Частота повторных вызовов, что слайдеры генерируют, зависит от платформы, но некоторые платформы генерируют CBR_DRAG повторный вызов для каждого движения мыши поиски слайдера.

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

Это вызвано от выражения действия, связанного с полем ввода слайдера. Slider_info поле ввода, используемое функцией отображает текущее значение слайдера в десятичной форме. Часто такое поле ввода - окно редактирования также, которое дает пользователю выбор или управления слайдером или печатанием его значения непосредственно. Если пользователь напечатает значение в slider_info, повторный вызов окна редактирования должен (наоборот) модифицировать значение слайдера:

static void CALLB

slider_action(ads_callback_packet *cbpkt)

{

ads_hdlg hdlg = cbpkt->dialog;

int reason = cbpkt->reason;

char interim[TILE_STR_LIMIT];

// Save the interim result.

//

strcpy(interim, cbpkt->value);/

// Display the result.

//

ads_set_tile(hdlg, "slider_info", interim);

}

static void CALLB

ebox_action(ads_callback_packet *cbpkt)

{

ads_hdlg hdlg = cbpkt->dialog;

int reason = cbpkt->reason;

char interim[TILE_STR_LIMIT];

// Save the interim result.

//

strcpy(interim, cbpkt->value);

// Display the result.

//

ads_set_tile(hdlg, "myslider", interim);

}



Обработка Внешних Приложений


ObjectARX-приложения могут загружать и разгружать другие ObjectARX-приложения и получать,  список которого внешние приложения в настоящее время загружены, также, как программы AutoLISP могут (использование arxloaded). Следующий запрос загружается,  программа вызвала myapp:

if (acedArxLoad ("myapp") != RTERROR) {

// Use acedInvoke() to call functions in "myapp".

}

Когда ваша программа закончена с myapp, это может разгрузить это,  вызывая

acedArxUnload("myapp");

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

struct resbuf *rb1, *rb2;

for (rb2 = rb1 = acedArxLoaded(); rb2 != NULL; rb2 = rb2->rbnext) {

if (rb2->restype == RTSTR)

acutPrintf("%s\n", rb2->resval.rstring);

}

acutRelRb(rb1);

Вы можете вызывать функции acedArxLoaded () и acedArxUnload () в конъюнкции друг с другом. Следующий пример разгружает все приложения кроме текущего:

struct resbuf *rb1, *rb2;

for (rb2 = rb1 = acedArxLoaded(); rb2 != NULL; rb2 = rb2->rbnext) {

if (strcmp(ads_appname, rb2->resval.rstring) != 0)

acedArxUnload(rb2->resval.rstring);

}

acutRelRb(rb1);



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


Если обращение и упомянутые примитивы всегда существуют в том же самом AcDbBlockTableRecord, это достаточно для обращающегося перегруженного примитива wblock () чтобы отправить isPrimary, оценивают полученное, чтобы вызвать wblock упомянутого примитива (). Это воспользуется преимуществом заданного по умолчанию поведения из всех трех форм WBLOCK, как отмечено в предыдущей секции. Мы не должны быть обеспокоены, с которым тип WBLOCK встречается.

Имеются два способа перегрузить заданное по умолчанию поведение клона wblock для этого случая. Сначала, Вы могли записывать поверх полный wblockClone () для обращающегося примитива. В типовом коде для заданного по умолчанию выполнения wblockClone () (в предыдущей секции), вы будете видеть цикл на getNextHardObject (). В пределах этого цикла Вы были бы должны прервать упомянутый объект ID и изменять значение isPrimary от Adesk:: kFalse, чтобы быть тем же самый, поскольку значение isPrimary прошло в.

Однако, намного более простой способ делать это состоит в том, чтобы продолжить использовать по умолчанию wblockClone () для вашего заказного примитива, но клонировать упомянутый примитив сначала, с правильными назначениями, когда настройка по умолчанию isPrimary не была бы правильна. Как только вы клонировали упомянутый примитив, когда Вы вызываете ваш собственный wblockClone (), это будет видеть, что упомянутый примитив уже клонирован и не будет пытаться клонировать это, используя настройки по умолчанию. Следующая выборка демонстрирует это. Компонент данных, mRefEnt, является ссылкой AcDbHardPointerId.

Acad::ErrorStatus

AsdkEntity::wblockClone(AcRxObject* pOwner,

AcDbObject*& pClone,

AcDbIdMapping& idMap,

Adesk::Boolean isPrimary) const

{

// If isPrimary is kTrue, then override the default cloning

// within our own cloning, which would set it to kFalse,

// by cloning our referenced entity first.

//

if (isPrimary) {

Acad::ErrorStatus es;

AcDbEntity* pEnt;

es = acdbOpenAcDbEntity(pEnt, mRefEnt, AcDb::kForRead);



Если Вы создаете заказной объект или с AcDbHardPointerId или жестко закодированной ссылкой AcDbEntity, Вы ответствены за запрос AcDbBlockTableRecord:: appendAcDbEntity () на упомянутом примитиве, когда необходимо в течение wblock (). В этом контексте, жестко закодированная ссылка - любая ситуация, в которой объект заставляет примитив быть включенным в wblockClone () через некоторый заказной код, написанный в приложении.

Необходимо делать добавление в конец вручную, потому что заданное по умолчанию выполнение AcDbDatabase:: wblockClone () будет всегда устанавливать isPrimary в Adesk:: kFalse при запросе wblockClone() на упомянутых объектах. Если объект - AcDbEntity, эта установка сообщает wblockClone() не добавлять примитив. Однако, как обозначено в предыдущей секции, если мы не делаем  WBLOCK* и клонированный примитив должен занять пространство модели или пространство листа, тогда заданное по умолчанию поведение должно быть перегружено, и добавляющийся должен быть вызван.

Если Вы позволяете заданному по умолчанию поведению происходить в запросе к wblockClone () примитив, его клон закончится в базе данных, но это будет ownerless. Это не будет добавлено в конец его новому владельцу, и не имеется никакого текущего способа закончить его, чтобы добавить через API. Для упомянутого примитива, который будет добавлен в конец, значение isPrimary должно быть сброшено к Adesk::kTrue перед  запросом его wblockClone() функция.

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




if (es != Acad::eOk)

return es;

// Use the same owner, and pass in the same isPrimary

// value.

//

AcDbObject* pSubClone = NULL;

es = pEnt->wblockClone(pOwner, pSubClone, idMap, kTrue);

if (pSubClone != NULL)

pSubClone->close();

pEnt->close();

if (es != Acad::eOk)

return es;

}

// Now we can clone ourselves by calling our parent’s method.

//

return AcDbEntity::wblockClone(pOwner, pClone, idMap, isPrimary);

}

Обработка жестких ссылок к AcDbEntities в течение wblockClone(): СЛУЧАЙ 2

Предыдущий пример будет только работать, когда ссылка находится в примитиве, и тот примитив - всегда в той же самой записи таблицы блоков как упомянутый примитив. Поскольку они находятся в той же самой записи таблицы блоков, установка isPrimary для относящегося примитива будет также иметь силу для упомянутого примитива. Однако, если упомянутый примитив может существовать в различной записи таблицы блоков, или если относящийся примитив - AcDbObject, Вы использовали бы другие средства, чтобы определить, было ли добавление в конец сделано.

Сначала, Вы будете должны проверить WBLOCK уведомление, чтобы определить, который тип WBLOCK встречается, вероятно,  устанавливая глобальный флажок, котором можно тогда делать запрос вашим wblockClone () функция:

§         если это - WBLOCK *, не используют AcDbBlockTableRecord:: appendAcDbEntity () в перегрузке заказного класса wblockClone (), в течение повторных вызовов, или в любом другом месте.

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

1) Всегда клонируйте упомянутые примитивы в пространство модели также. В этом случае, Вы всегда установили бы isPrimary в Adesk:: kTrue, или,



2) Проверить{*отметить*} текущее местоположение упомянутого примитива. Если это находится в пространстве модели или пространстве листа, клон это к соответствующему пространству и устанавливает isPrimary в Adesk:: kTrue. Если это находится в отобранном блоке, также клонировать это к пространству модели. Если это находится в некотором другом определяемом пользователем блоке, то вызовите wblockClone () на той блочной записи. Только убедитесь, что Вы не пробуете клонировать отобранный блок. В этом случае, запись таблицы блоков будет заботиться о клонировании ваш упомянутый примитив.

§         если это - WBLOCK набора выборов, только сбрасывают isPrimary к Adesk:: kTrue, если упомянутый примитив входит в пространство модели или пространство листа. Если это находится в определяемом пользователем блоке, назовите wblockClone () на этом AcDbBlockTableRecord, вместо на вашем упомянутом примитиве.

Наконец, должно быть отмечено, что введение жесткой ссылки AcDbEntity в настоящее время не поддержано AcDbProxyObject системой, даже если Вы используете AcDbHardPointerId для ссылки. AcDbProxyObject использует по умолчанию wblockClone () выполнение, и таким образом не будет делать добавляющийся из любых упомянутых примитивов в течение любой формы WBLOCK. Если WBLOCK случается, когда ваши примитивы - proxies, ссылки клонируются, но без добавляющегося они будут ownerless и не постоянны. Результат - то, что, когда рисунок wblocked загружается, ваша ссылка, ID будет NULL, и упомянутый примитив будет отсутствовать. Вы должны закодировать ваш заказной объект, чтобы обработать эту ситуацию изящно.

Вставка

Операция вставки - специальный случай глубокого клонирования. В случае вставки, объекты не скопированы в базу данных адресата; вместо этого, они перемещены в новую базу данных. Когда это происходит, исходная база данных больше не имеет силу, потому что это был cannibalized, когда его объекты были перемещены в новую базу данных. Если Вы перегружаете deepClone () функция, ваши объекты будет просто клонирована, когда операцию вставки запрашивают. Если Вы используете заданную по умолчанию форму deepClone (), дешевое клонирование выполнено внутренне.



Когда объект скопирован таким образом, карта ID все еще содержит два объектных ID для каждого клонированного объекта (исходный ID и адресат ID), но эта точка ID временно к тому же самому объекту. Когда операция вставки заканчивается, исходная база данных удалена.

Редактор Функции Уведомления Реактора

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

beginDeepClone ()

beginDeepCloneXlation ()

abortDeepClone ()

endDeepClone ()

BeginDeepClone () функция вызвана после того, как AcDbIdMapping образец создан и прежде, чем любые объекты клонированы. Карта ID будет пуста, но этом можно делать запрос для destDb () и deepCloneContext () в это время.

BeginDeepCloneXlation () функция вызвана в конце концов объектов в первичном наборе выборов,  были клонированы и прежде, чем ссылки оттранслированы.

Это - первый раз, когда возможно видеть,  полный набор чего был клонирован в карте ID. Это - также время, чтобы клонировать любые дополнительные объекты и добавлять их к карте ID. Помните, что любые клонированные объекты имеют их объектные ID в состоянии непрерывного изменения в этой точке.

AbortDeepClone () функция вызвана в любое время между beginDeepClone () и endDeepClone ().

EndDeepClone () функция вызвана в конце процесса трансляции и клонирования. Объектные ID больше не в состоянии непрерывного изменения. Однако, этот запрос не подразумевает, что примитивы находятся в их конечном состоянии для любой команды,  выполняется. Часто клонированные примитивы преобразованы, или другие операции выполнены после клонируемого процесса. Имеются дополнительные функции повторного вызова, которые могут использоваться, чтобы обратиться к примитивам позже, включая commandEnded ().

В дополнение к предыдущим четырем функциям, следующие функции уведомления обеспечиваются в операции клона wblock:

beginWblock ()



otherWblock ()

abortWblock ()

endWblock ()

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

1 beginDeepClone () Этот запрос послан, как только образец адресата АкДбДатабас был создан, но это находится в “необработанном” состоянии и не готово к добавлению в конец.

2 beginWblock () новая база данных теперь имеет ее основные элементы, типа таблицы метки, класс карта ID, и записи таблицы блоков пространства листа и пространство модели. Это все еще пусто. Клонирование не началось, но новая база данных теперь готова к добавлению в конец.

3 otherWblock () и beginDeepCloneXlation () Эти два вызывает,  сделаны противовключенным и может использоваться для той же самой цели. Первичный набор объектов был клонирован, но трансляция ссылки не началась все же.

4 endDeepClone () процесс трансляции теперь закончил, но примитивы - еще не в их конечном состоянии.

5 endWblock () примитивы теперь были преобразованы, и пространство модели, и начала координат пространства листа были установлены. Новая база данных полна, но еще не была сохранена.

Имеются три типа AcEditorReactor:: beginWblock (). Они перечислены здесь наряду с их соответствующими функциями AcDbDatabase:

1 WBLOCK*

void

AcEditorReactor:: beginWblock (

AcDbDatabase* pTo,

AcDbDatabase* pFrom)

Acad:: ErrorStatus

 AcDbDatabase::wblock(AcDbDatabase*& POutputDatabase)

2 WBLOCK определяемого пользователем блока

void

AcEditorReactor:: beginWblock (

AcDbDatabase* pTo,

AcDbDatabase* pFrom,

AcDbObjectId blockId)

Acad:: ErrorStatus

AcDbDatabase:: wblock (

 AcDbDatabase*& POutputDatabase,

AcDbObjectId nObjId)

3 WBLOCK набора выборов

void

AcEditorReactor:: beginWblock (

AcDbDatabase* pTo,

AcDbDatabase* pFrom,

const AcGePoint3d& InsertionPoint)

Acad:: ErrorStatus

AcDbDatabase:: wblock (

 AcDbDatabase*& POutputDatabase,

const AcDbObjectIdArray& PIdSet,

const AcGePoint3d& PPoint3d)



Все три версии клонируют, и пространство модели и пространство листа AcDbBlockTableRecord перед запросом beginWblock (). Однако, для примитивов в пределах этих записей таблицы блоков, порядок уведомления, будет кажется,  прибывает по-другому в первый тип и последние два типа. В одной версии, примитивы в пространстве модели, которые клонируются,  получит запрос wblockClone() перед AcEditorReactor::beginWblock(). В версиях два и три, примитивы в AcDbBlockTableRecord или наборе выборов получат их wblockClone() запрос после AcEditorReactor::beginWblock() уведомление Запрос.

Объекты, которые были клонированы в течение частичного XBIND,  автоматически переадресованы только после endDeepClone() уведомление. Это означает, что их AcDbObjectIds во внешне упомянутой базе данных отправлены AcDbObjectIds клонируемых объектов в рисунке главного компьютера, и объекты во внешне упомянутой базе данных удалены. Объекты, что ссылка, на которую отправленный AcDbObjectIds заканчивают ссылаться, имитируют в ведущем рисунке. Если Вы должны отключить это автоматическое переназначение для ваших объектов, то удалите idPair() от idMap, для ваших клонированных объектов, в течение endDeepClone() уведомление.

Следующая функция вызывает, происходят в течение команды INSERT ИЛИ INSERT*:

§         beginInsert ()

§         otherInsert ()

§         abortInsert ()

§         endInsert ()

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

1 beginInsert () и beginDeepClone () Они вызывают, возвращаются-to-back и может использоваться для той же самой цели.

2 otherInsert() и beginDeepCloneXlation() Они вызывают, также возвращаются -to-back и может использоваться для той же самой цели.

3 endDeepClone() клонирование и процессы трансляции закончено. Примитивы клонированы, но не были добавлены в конец к блоку, так что они не графические. Вы не можете использовать примитивы в наборе выборов все же.



4 endInsert() примитивы теперь были преобразованы и были добавлены в конец к блоку. Если это - ВСТАВКА*, они - теперь в пространстве модели и имеют их графику. Они могут использоваться в наборах выбора. Однако, если это - ВСТАВКА, они только были добавлены в конец к записи таблицы блоков; та запись еще не была добавлена к таблице блоков. В этом случае, Вы должны ждать до commandEnded() уведомления, чтобы использовать эти примитивы в наборе выборов.

Типовой код в этой секции использует beginDeepCloneXlation() функция уведомления. Эта выборка иллюстрирует, как Вы могли записывать реактор, чтобы добавить поведение к команде WBLOCK, чтобы сообщить этому включать все текстовые стили в новый рисунок, вместо только текстовые стили, которые упомянуты примитивами.

Это таким образом показывает, как использовать wblock с небытием.

AcDbIdMapping имеет функцию, deepCloneContext (), который возвращает контекст, в котором глубокая клонируемая функция была вызвана. Контексты - следующее:



kDcCopy



Копирование в пределах базы данных; использует COPY, ARRAY, MIRROR (если Вы не удаляете оригинал), приобретение LEADER, или копия INSERT



kDcExplode



EXPLODE блок-ссылки



KDcBlock



BLOCK создание



kDcXrefBind



XREF Связывают, и XBIND



kDcSymTable



XREF Слияние Присоединяются, DXFIN, и IGESIN (только записи таблицы идентификаторов клонированы здесь)



kDcSaveAs



SAVEAS, когда VISRETAIN установлен в 1 (только записи, таблицы идентификаторов клонированы здесь)



kDcInsert



ВСТАВКА рисунка



kdcWblock



 WBLOCK



kDcObjects



AcDbDatabase:: deepCloneObjects ()

AcEditorReactor::abortDeepClone() функция вызвана, когда запрос к AcDbDatabase::abortDeepClone() сделан.

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

// С тех пор AcDbDatabase::wblock() только поддерживает AcDbEntities в его массиве ID,

// этот код демонстрирует, как добавить дополнительные объекты в течение beginDeepCloneXlation



().

//  Если это - команда WBLOCK, это спрашивает пользователя, если все текстовые стили были wblocked.

//  Иначе, только те текстовые стили, упомянутые примитивами, являющимися wblocked

будут

//  включены (заданное по умолчанию поведение wblock's).

//  AsdkEdReactor is derived from AcEditorReactor.

//

void

AsdkEdReactor::beginDeepCloneXlation(AcDbIdMapping& idMap, Acad::ErrorStatus* es)

{

if (idMap.deepCloneContext() == AcDb::kDcWblock && getYorN("Wblock all Text Styles"))

{

AcDbDatabase *pOrigDb, *pDestDb;

if (idMap.origDb(pOrigDb) != Acad::eOk)

return;

*es = idMap.destDb(pDestDb);

if (*es != Acad::eOk)

return;

AcDbTextStyleTable *pTsTable;

*es = pOrigDb->getSymbolTable(pTsTable, AcDb::kForRead);

if (*es != Acad::eOk)

return;

AcDbTextStyleTableIterator *pTsIter;

*es = pTsTable->newIterator(pTsIter);

if (*es != Acad::eOk) {

pTsTable->close();

return;

}

AcDbTextStyleTableRecord *pTsRecord;

AcDbObject *pClonedObj;

for (; !pTsIter->done(); pTsIter->step()) {

*es = pTsIter->getRecord(pTsRecord, AcDb::kForRead);

if (*es != Acad::eOk) {

delete pTsIter;

pTsTable->close();

return;

}

// It is not necessary to check for already cloned

// records. If the text style is already

// cloned, wblockClone() will return Acad::eOk

// and pCloneObj will be NULL.

//

pClonedObj = NULL;

*es = pTsRecord->wblockClone(pDestDb, pClonedObj, idMap, Adesk::kFalse);

if (*es != Acad::eOk) {

pTsRecord->close();

delete pTsIter;

pTsTable->close();

return;

}

*es = pTsRecord->close();

if (*es != Acad::eOk) {

delete pTsIter;

pTsTable->close();

return;

}

if (pClonedObj != NULL) {

*es = pClonedObj->close();

if (*es != Acad::eOk) {

delete pTsIter;

pTsTable->close();

return;

}

}

}

delete pTsIter;

*es = pTsTable->close();

}

}


Образцы Данных


Имеется отдельный образец всех элементов данных, связанных с базой данных и текущей командой, обрабатывающей состояние для каждого документа. Это включает командный процессор, входной процессор, Визуально ШЕПЕЛЯВЯТ среда, базы данных, наборы выбора, и (больше всего, но не все) переменные системы. Текущая команда, обрабатывающая состояние поддерживается в динамической памяти. В дополнение к этим встроенным элементам системы, все ObjectARX-приложения должны также обслужить{*поддержать*} документированное - определенное состояние или на стеке или в структурах на динамической памяти, которые соответствуют каждому активному документу.

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



Образцы Подстановочных знаков в Списках Фильтра


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



Образование класса пользователя


ObjectARX обеспечивает набор макрокоманд, объявленных в rxboiler.h файле, который помогает Вам создать новые классы, полученные из AcRxObject. Вы можете получать новые классы из большинства классов в ObjectARX иерархии кроме Выпуска AutoCAD 12 набора объектов (перечисленный в главе 6, “ примитивы, ”) и таблица идентификаторов классифицирует. Если Вы не используете макрокоманды ObjectARX, чтобы определить ваш новый класс, класс наследует тождество во время выполнения его наиболее непосредственного{*немедленного*} ObjectARX-зарегистрированного родительского класса.

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

§         AcRxObject

§         AcRxService

§         AcDbObject

§         AcDbEntity

§         AcDbCurve

§         AcDbObjectReactor

§         AcDbDatabaseReactor

§         AcDbEntityReactor

§         AcTransactionReactor

§         AcEdJig

§         AcEditorReactor

§         Приложения не должны получить классы из следующего:

§         AcDbAttribute

§         AcDbAttributeDefinition

§         AcDbArc

§         AcDbBlockReference

§         AcDbCircle

§         AcDbFace

§         AcDbLine

§         AcDbMInsertBlock


§         AcDbPoint

§         AcDbShape

§         AcDbSolid

§         AcDbText

§         AcDbTrace

§         Все классы AcDbXxxDimension

§         AcDbViewport

§         AcDbGroup

§         Все классы, полученные из AcDbSymbolTable

§         Все классы, полученные из AcDbSymbolTableRecord

§         AcDbBlockBegin

AcDbBlockEnd

AcDbSequenceEnd

AcDb2dPolyline

AcDb2dPolylineVertex

AcDb3dPolyline

AcDb3dPolylineVertex

AcDbPolygonMesh

AcDbPolygonMeshVertex

AcDbPolyFaceMesh

AcDbPolyFaceMeshVertex

AcDbFaceRecord

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


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


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



Общие характеристики функций ObjectARX


Эта секция описывает некоторые общие характеристики глобальных функций в ObjectARX библиотеке. Большинство ObjectARX

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

ОБРАТИТЕ ВНИМАНИЕ функции, описанные в этой главе были известны как функции ADS в предыдущих выпусках AutoCAD.



Общие Шаги для Использования AcEdJig


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

Использовать AcEdJig класс

1 Создают образец вашего полученного класса AcEdJig.

2 Устанавливают ваш текст подсказки с AcEdJig:: setDispPrompt () функция.

3 Звонят,  AcEdJig:: перетаскивают () функцию, которая управляет перетащенным циклом и в свою очередь вызывает{*называет*} дискретизатор (), модифицируйте (), и объект () функции, пока пользователь не заканчивает перетащенную последовательность.

4 Проверка в пределах дискретизатора () функция:

Если Вы используете подсказку с ключевыми словами, вызовите AcEdJig:: setKeywordList () функция.

Если Вы хотите установить специальный тип курсора, назовите AcEdJig:: setSpecialCursorType () функцией (. Этот шаг необязательный и может типично опускаться.)

Если желательно, ограничения места на перетащенную последовательность и возвращаемое значение, использующее AcEdJig:: setUserInputControls () функция.

5 Проверяют{*отмечают*} состояние возвращения от AcEdJig::, перемещается{*перетаскивает*} () функцию и передает{*совершает*} изменения{*замены*} перетащенной последовательности. Если пользователь отменил или прервал процесс, исполнять соответствующую очистку.

 



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


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

Цвет

Linetype

Linetype масштаб

Видимость

Уровень

вес Строки

Графическое название{*имя*} стиля

Когда Вы добавляете примитив к блочному отчету{*записи*} таблицы, AutoCAD автоматически вызывает AcDbEntity:: setDatabaseDefaults () функция, которая устанавливает свойства в их значения по умолчанию, если Вы явно не установили их.

AcDbViewport приобретает параметры настройки текущего графического окна.

Если свойство было явно не определено для примитива, текущее значение базы данных для того свойства используется. См. главу 4, “ Операции Базы данных, ” для описания функций члена, используемых для установки и получения текущих значений свойства, связанных с базой данных.



Общие Типы и Определения


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



Общий Доступ


Большинство генерала функций, которые обращаются К AutoCAD - acedCommand () и acedCmd (). Подобно функции (команды) в AutoLISP, эти функции посылают команды и другой ввод непосредственно к Приглашению ко вводу команды AutoCAD.

Int

AcedCommand (int rtype, ...);

Int

AcedCmd (struct resbuf *rbp);

В отличие от большинства других функций взаимодействия AutoCAD, acedCommand () имеет список параметров переменной длины: параметры к acedCommand () обработаны как пары если бы не RTLE и RTLB, которые необходимы, чтобы передать точку указки. Первый из каждой пары параметра идентифицирует тип результата параметра, который следует, и второй содержит фактические данные. Заключительный параметр в списке - одиночный параметр, чей значение является или 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 - тип массива.


Оценка Внешних Функций


Как только внешняя функция была определена, AutoLISP может вызывать это с запросом kInvkSubrMsg. Когда ObjectARX-приложение получает этот запрос, это отыскивает целочисленный код внешней функции,  вызывая acedGetFunCode (). Тогда инструкция выключателя, условный оператор, или таблица с  функциональным запросом могут выбирать и вызывать обозначенный функциональный обработчик. Это - функция, что ObjectARX-приложение определяет, чтобы осуществить внешнюю функцию. Обратите внимание, что имя обработчика и имени, определенного acedDefun () (и поэтому признанный AutoLISP) - не обязательно то же самое имя.

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

ОБРАТИТЕ ВНИМАНИЕ, что  функциональный обработчик должен проверить номер, и тип параметров прошел к этому, потому что не имеется никакого способа сообщить AutoLISP, каковы требования.

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

Группа функций ObjectARX известный как функции возвращения значения (типа acedRetInt(), acedRetReal(), и acedRetPoint()) позволяет внешней функции возвратить значение выражению AutoLISP, которое вызвало это.

Параметры, которые пропускают между внешними функциями и AutoLISP, должны оценить к одному из следующих типов: целое число, реальный (с плавающей точкой), строковый, точка (представленный в AutoLISP как список двух или трех реальных значений), имени примитива, имени набора выбора, символы AutoLISP t и nil, или список, который содержит предыдущие элементы. Символы AutoLISP к другие чем t и nil не пропускают или от внешних функций, но ObjectARX-приложения, могут отыскивать и устанавливать значение символов AutoLISP,  вызывая acedGetSym () и acedPutSym ().

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

( Doitagain pstr iarg rarg)

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

Команда: (doitagain “ Стартовая ширина - ” 3 7.12)

Этот запрос снабжает значениями для строки функции, целого числа, и вещественного числа

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

AcedGetArgs (). Для примера поиска параметров таким образом, см. первый пример в “ Списки и Другие Динамически Размещенные Данные ” на странице 546.



OnModified ()


Этот метод используется, чтобы сообщить объекту COM, что AcDbObject, который это представляет,  изменился. Объект COM тогда ответствен за стреляющее уведомление всем его клиентам через установленные точки соединения.



Операция Wblock


AcDbDatabase класс содержит перегруженный wblock () функция с тремя формами, которые соответствуют опциям команды WBLOCK AutoCAD.



Описатели Области просмотра


Функция acedVports (), подобно функции AutoLISP (vports), получает список описателей текущих областей просмотра и их местоположений.

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

struct resbuf *rb;

int rc;

rc = acedVports(&rb);

acedRetList(rb);

acutRelRb(rb);

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

Точно так же, если четыре области просмотра равняться-размера расположены в четырех углах экрана, и TILEMODE включен, предшествующий код может возвращать конфигурацию, показанную в следующем рисунке.

Описатель текущей области просмотра - всегда сначала в списке. В списке, показанном в предшествующем числе{*рисунке*}, номер 5 области просмотра - текущая область просмотра.



Определение прокси-объекта


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

Прокси-объекты созданы для объектов и примитивов. AutoCAD использует прокси-объекты, чтобы обеспечить доступ для чтения данных в заказном объекте, полученном из AcDbObject или AcDbEntity. Прокси-объекты также обеспечивают управляемые возможности редактирования этого данными. Родительское приложение определяет степень тех возможностей редактирования с параметром PROXY_FLAGS макрокоманды ACRX_DXF_DEFINE_MEMBERS.

Класс прокси-объекта AcDbProxyObject получен из AcDbObject, и класс прокси-примитива AcDbProxyEntity получен из AcDbEntity. И - абстрактные классы, которые не могут быть действительны и включены в ObjectARX API.

Прокси-объекты преобразовывают назад к первоначальному заказному объекту всякий раз, когда родительское приложение загружено. Например, если прокси-объекты созданы в начале сессии рисунка, и родительское приложение впоследствии загружено, прокси-объекты восстановлены к заказным объектам.

При специальных обстоятельствах, прокси-объекты написаны к файлам, но прокси-объекты обычно существуют только в памяти.

ObjectARX разработчики может затрагивать создание и управлять модификацию прокси-объектов,  используя макрокоманду ACRX_DXF_DEFINE_MEMBERS и требование, загружающее особенности в AutoCAD (см. “ Загрузка по требованию ” на странице 45). Кроме того, они могут использовать функции классов прокси-объекта в их собственных приложениях, чтобы управлять прокси-объектами, которые AutoCAD создает для заказных объектов других приложений.



Определение расширения протокола


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

классом во время выполнения. Ассоциация ObjectARX класса с классами расширения протокола сделана посредством ObjectARX объекта описателя класса (описанной в главе 11, при Наследовании Заказного ObjectARX Класса. ”) объект описателя класса описывает класс и включает массив указателей на любые объекты, которые расширяют функциональные возможности того класса. ObjectARX

класс может иметь любой номер протокола расширения, связанные с этим.



Определение Внешних Функций


Когда ObjectARX-приложение получает запрос kLoadDwgMsg от AutoCAD, это должно определить все его внешние функции,  вызывая acedDefun () однажды для каждой функции. AcedDefun () запрос связывает имя внешней функции (прошел как строковое значение) с целочисленным кодом, который является уникальным в пределах приложения. Целочисленный код не должен быть отрицателен, и это не может быть большее чем 32,767 (другими словами, код - короткое целое число).

Следующий запрос к acedDefun () определяет, что AutoLISP признает, что внешняя функция вызвала doit в AutoLISP, и что, когда AutoLISP вызывает doit, это передает функциональный нуль кода (0) к ObjectARX-приложению:

AcedDefun ("doit", 0);

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

Внешние функции определены отдельно для каждого открытого документа в MDI. Функция определяется, когда документ становится активным. Для подробной информации, см. главу 16, “ Многодокументная среда. ”

ПРЕДУПРЕЖДЕНИЕ! Если два или больше ObjectARX-приложения определяют функции (в том же самом документе) которые имеют то же самое имя, AutoLISP признает только наиболее недавно определенную внешнюю функцию. Предварительно загруженная функция будет потеряна.

Это может также случаться, если пользователь вызывает defun с противоречивым именем.

Как в AutoLISP, новая функция может быть определена как команда AutoCAD приписыванием ее имя с “ C: ” или “ c: ”, как показано в следующем примере:

AcedDefun ("C:DOIT", 0);

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

Функции, определенные как команды AutoCAD могут все еще быть вызваны от выражений AutoLISP, при условии, что “ C: ” префикс включен как часть их названий.

Например, учитывая предыдущий acedDefun () запрос, пользователь AutoCAD мог также вызывать команду DOIT как функция с параметрами:

Команда: (c:doit x y)

ПРЕДУПРЕЖДЕНИЕ! Если приложение определяет команду C:XXX, чей конфликты имен со встроенной командой или именем команды, определенным в acad.pgp файле, AutoCAD не признает внешнюю функцию как команда. Функция может все еще вызываться как AutoLISP внешняя функция. Например, после запроса acedDefun ("c:cp", 0), ввод пользователя cp (псевдоним для COPY, определенного в acad.pgp) вызывает команду COPY AutoCAD, но пользователь мог вызывать внешнюю функцию с c:cp.

ОБРАТИТЕ ВНИМАНИЕ Имена функции, определенные acedDefun () могут быть неопределены,  вызывая acedUndef (). После того, как функция была неопределена, попытка вызывать это вызывает ошибку.



Определения Функции Повторного вызова


Чтобы регистрировать функции повторного вызова с ads_action_tile () и ads_new_dialog (), adsdlg.h определяет тип CLIENTFUNC, который указывает на функцию повторного вызова как показано в следующей примере:

typedef void (*CLIENTFUNC)(ads_callback_packet *cpkt);

 

(Пустой) символ CALLB определен, чтобы делать функции повторного вызова проще, чтобы расположить в исходном тексте, как в следующем примере:

static void CALLB

dbox_handler(ads_callback_packet *cpkt)

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

 #define NULLCB ((CLIENTFUNC) 0)



Определения и Объявления


Чтобы записывать приложения, которые вызывают функции в пакете PDB, включают следующую директиву препроцессора в вашей программе:

 #include "Adsdlg.h"

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



Определенные Примитивы


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

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

AcDb2dPolyline, который имеет объекты AcDb2dPolylineVertex

AcDb3dPolyline, который имеет объекты AcDb3dPolylineVertex

AcDbPolygonMesh, который имеет объекты AcDbPolygonMeshVertex

AcDbPolyFaceMesh, который имеет объекты AcDbPolyFaceMeshVertex и объекты AcDbFaceRecord

AcDbBlockReference, который имеет объекты AcDbAttribute

AcDbMInsertBlock, который имеет объекты AcDbAttribute

Примеры создания и выполнения итераций через сложные примитивы обеспечиваются в “ Сложные Примитивы ” на странице 134.



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.



Основная операция средства просмотра


Следующее - основные шаги, чтобы установить вид (или виды) рисунка, сопровождаемого в соответствии с описанием графического выбора примитива.

Устанавливать вид

1 приложение ObjectDBX загружает DWG

файл в образец AcDbDatabase.

2 приложение создает область просмотра и передает связанный AcGiViewport к AcGix.

3 приложение сообщает AcGix инициализировать перегенеральный из определенной записи таблицы блоков или отдельного примитива в данный набор областей просмотра.

4 AcGix восстанавливает примитив (ы) во все активные области просмотра. По существу, каждый примитив открыт для чтения, его AcDbEntity:: worldDraw () вызван, и если состояние возвращения указывает, его AcDbEntity:: viewportDraw () перегрузка члена вызвана однажды для каждой активной области просмотра.

5 От любого из этих членов, каждый класс свободен получить объекты AcGiWorld/ViewportGeometry и объекты AcGiSubentityTraits, и делать, вызывает, чтобы послать геометрические графические и графические черты (атрибуты подобно цвету, linetype, шрифт) к ним. Эти объекты AcGi

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

6 vectortaker берет входные пакеты сообщения (или функция вызывает) и преобразовывает их в, вызывает к основной системе графики.



Основы глубокого клонирования


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

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

AcDbDatabase:: deepCloneObjects ()

AcDbDatabase:: wblock ()

AcDbDatabase:: insert()

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

При использовании AcDbDatabase:: вставка (), только вставляют к базам данных адресата, которые уже были сформированы. Вы можете получить полностью сформированный (и возможно полностью заполняемый) базу данных адресата,  используя текущий рисунок, чтобы формировать новую базу данных с параметром конструктора Adesk:: kTrue или,  создавая пустую новую базу данных, используя параметр конструктора Adesk:: kFalse и затем вызывая AcDbDatabase:: readDwgFile () на этом, чтобы заполнить это.

Вообще, чтобы использовать AcDbDatabase:: deepCloneObjects (), AcDbDatabase:: wblock (), или AcDbDatabase:: вставка () функции в вашем коде, Вы не должны знать того, как карта объекта ID заполнена или точно, что случается в течение каждой стадии глубокого клонирования. Если Вы создаете новый класс, и Вы хотите перегрузить AcDbObject:: deepClone () или AcDbObject:: wblockClone () функции, вы будете должны быть знакомыми с подробностями тех функций, которые описаны в “ Реализация deepClone () для Классов пользователя ” на странице 476.

AcDbObject:: deepClone () и AcDbObject:: wblockClone () функции не должен быть вызван{*назван*} непосредственно на заказном объекте в прикладном коде. Они только вызваны как часть цепочки от операции клонирования более высокого уровня.



Осуществление Точки входа для 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;

}

return AcRx::kRetOK;

}



От сети нитей к сети объектов


Сеть traversers представляет списки смежных вершин объектов сети, которые связаны в контексте объекта сети более высокий измерение.

Сеть traversers

Class

Objects

AcBrMesh2dElement2dTraverser

AcBrMesh2d (owner)

AcBrElement2d (position)

AcBrElement2dNodeTraverser

AcBrElement2d (owner)

AcBrNode (position)

Каждый специфический тип traverser выставляет, и объект, который это использует для контекста (то есть владелец списка смежных вершин) и объект, на который это в настоящее время указывает (то есть позиция списка смежных вершин) с функциями set* и get*.

MeshElement обход

Этот класс определяет функции, которые являются подходящими для 2-ого элемента. Это используется, чтобы отобрать убывающий иерархический обход 2-ой сети, или пересекать все уникальные 2-ые элементы и узлов в 2-ой сети.

ElementNode обход

Этот класс определяет функции, которые являются подходящими для узла в контексте 2-ого элемента. Это используется, чтобы получить доступ к данным узла и геометрии первоначальной поверхности, типа поверхностных нормалей и пар параметра UV.

Узлы используются больше чем одним элементом сети и могут быть связаны с больше чем одной поверхностью с тех пор имеется совместное использование узла в общих границах первоначальных поверхностей.