Как использовать длинные транзакции для эмуляции команды -ССЫЛРЕД
Команды -ССЫЛРЕД (-REFEDIT) и ССЫЛРЕД (REFEDIT) обеспечивают возможность контекстного редактирования блока (по месту). Они позволяют переключатся между вложенными ссылками блока. Тогда AutoCAD принимает подсвеченную вставку блока для редактирования по месту. Приложение посылает команду -ССЫЛРЕД для переключения в режим редактирования для удобства пользователя.
На самом деле, мы могли бы имитировать команду –ССЫЛРЕД длинными транзакциями. Классы и методы длинных транзакций обеспечивают схему редактирования примитивов, которая позволяет вытащить примитивы для редактирования и затем вернуть их обратно на прежнее место. Эта операция заменяет исходные примитивы на отредактированные, что очень полезно для редактирования блока, который мы хотим изменить на месте.
Следующий код подразумевает, что в вставке большого блока есть вставка маленького блока. Код предоставляет нам две команды: testcheckout просит нас указать примитивы в вставке маленького блока, затем получает вставку большого блока для редактирования по месту. Это только демо без достаточного числа проверок на ошибки.
Больше информации есть в ObjectARX документации и в примере SDK\samples\database\longtrans_dg.
- // Глобальные переменные для двух команд checkout и checkin
- // ID длинной транзакции
- AcDbObjectId long_trans_id;
- // errorMap длинной транзакции
- AcDbIdMapping error_map;
- /////////////////////////////////////////////////////////
- // команда: testcheckout
- //
- // указываем примитивы вставки малого блока
- // принимаем вставку большого блока для редактирования по месту
- ///////////////////////////////////////////////////////
- static void ADNSample_testcheckout(void)
- {
- // Это исправленное демо, не забудьте указать примитивы
- // вставки малого блока
- ads_name ename;
- ads_point ptResult;
- ads_matrix adsmat;
- struct resbuf *info;
- AcDbObjectId ownerId;
- int rt =
- acedNEntSelP(_T("\nВыберите примитив малого блока:"),
- ename,ptResult, false ,adsmat, &info);
- if( rt!= RTNORM)
- {
- acutPrintf(_T("\nОшибка в acedNEntSelP"));
- return;
- }
- if(info == NULL)
- {
- acutPrintf(_T("\n Нет информации!"));
- return;
- }
- // Выбранные примитивы могут находится в вложенных вставках.
- // в этом примере: большая вставка и малая вставка
- // Массив всех id вставок
- AcDbObjectIdArray owner_Entity_idArray;
- struct resbuf *rbIter = info;
- ads_name tempName;
- AcDbObjectId objId;
- while (rbIter != NULL) {
- tempName[0] = rbIter->resval.rlname[0];
- tempName[1] = rbIter->resval.rlname[1];
- acdbGetObjectId(objId, tempName);
- owner_Entity_idArray.append(objId);
- rbIter = rbIter->rbnext;
- }
- acutRelRb(info);
- // В этом примере второй – это вставка большого блока
- AcDbObjectId big_ref_id = owner_Entity_idArray[1];
- // итерация по примитивам владельца.
- AcDbObjectIdArray parentBlkEntArr;
- AcDbObjectId big_ref_rec_id;
- AcDbObject *pObj = NULL;
- // Открываем вставку большого блока
- Acad::ErrorStatus es =
- acdbOpenObject(pObj,big_ref_id,AcDb::kForRead);
- if(Acad::eOk == es)
- {
- if(pObj->isKindOf(AcDbBlockReference::desc()))
- {
- // получаем id определения вставки большого блока
- big_ref_rec_id =
- ((AcDbBlockReference*)pObj)->blockTableRecord();
- }
- pObj->close();
- }
- // готовим объекты для check out.
- // Обратите внимание: объектами checkout являются
- // примитивы определения блока
- // открываем определение вставки большого блока
- es = acdbOpenObject(pObj,big_ref_rec_id,AcDb::kForWrite);
- if(es != Acad::eOk) return;
- AcDbBlockTableRecord *big_ref_rec =
- (AcDbBlockTableRecord*)pObj;
- // Покажем имя блока, которое будем редактировать по месту
- const ACHAR *ref_rec_name = NULL;
- big_ref_rec->getName(ref_rec_name);
- TCHAR msg[256] = {0};
- _tcscat( msg,L"Блок который будем редактировать по месту: ");
- _tcscat( msg, ref_rec_name );
- MessageBox(NULL,msg,msg,0);
- AcDbObjectIdArray objIdArray;
- AcDbBlockTableRecordIterator *pIter;
- big_ref_rec->newIterator(pIter);
- // получаем примитивы в определении блока
- for (pIter->start(); !pIter->done(); pIter->step())
- {
- AcDbEntity *pEntity;
- pIter->getEntity(pEntity, AcDb::kForRead);
- objIdArray.append(pEntity->objectId());
- pEntity->close();
- }
- delete pIter;
- big_ref_rec->close();
- // получаем id пространства модели
- AcDbBlockTable *pThisBlockTable;
- acdbHostApplicationServices()->workingDatabase()
- ->getSymbolTable(pThisBlockTable, AcDb::kForRead);
- AcDbBlockTableRecord *pThisMsBtr;
- pThisBlockTable->getAt(ACDB_MODEL_SPACE,
- pThisMsBtr, AcDb::kForWrite);
- pThisBlockTable->close();
- AcDbObjectId model_space_id = pThisMsBtr->objectId();
- pThisMsBtr->close();
- // Выполняем check out
- acapLongTransactionManagerPtr()->checkOut(long_trans_id,
- objIdArray, model_space_id, error_map);
- // теперь мы будем видеть вставку большого блока
- // как редактируемую по месту
- // ее можно редактировать вручную средствами AutoCAD
- }
- ///////////////////////////////////////////////
- // Команда: testcheckin
- //
- // check in длинную транзакцию для
- // закрепления результатов редактирования
- //
- ////////////////////////////////////////////
- static void ADNSample_testcheckin(void)
- {
- // check in
- acapLongTransactionManagerPtr()->checkIn(
- long_trans_id, error_map);
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=128.0
Отредактировано 04.08.2013 в 16:31:43