ADN Open CIS
Сообщество программистов Autodesk в СНГ

29/05/2013

Получение имени блока в ARX

Вопрос:
Могу ли я используя ObjectARX получить имя блока из вставки блока внутри ObjectARX приложения? Я знаю, что это можно сделать используя ads_entget (acdbEntGet), а затем найти соответствующий код группы.

Ответ:
Нет метода у класса вставки блока, который бы возвращал имя определения блока. Вставка блока (класс AcDbBlockReference) хранит ID объекта определения блока (класс AcDbBlockTableRecord). Имя блока хранится в определении блока. Чтобы получить имя блока нужно получить ID определения блока и открыть его. Тогда можно будет получить имя блока из определения блока. Следующий код позволяет выбрать вставку блока и получить его имя:

Код - C++: [Выделить]
  1. void AsdkGetBlockName()
  2. {
  3.      // Позволим пользователю выбрать вставку блока.
  4.      ads_name ename;
  5.      ads_point pt;
  6.  
  7.      if (RTNORM != acedEntSel(L"\nВыберите вставку блока: ",
  8.                              ename,
  9.                             pt))
  10.        return;
  11.  
  12.      AcDbObjectId objId;
  13.      AcDbEntity *pEnt;
  14.      AcDbBlockReference *pInsert;
  15.      Acad::ErrorStatus es;
  16.  
  17.      // Проверяем тип примитива.
  18.      acdbGetObjectId(objId, ename);
  19.      if (Acad::eOk != (es = acdbOpenAcDbEntity(pEnt,
  20.                             objId,
  21.                             AcDb::kForRead)))
  22.      {
  23.        acutPrintf(L"\nНельзя получить доступ к примитиву.\n");
  24.        return;
  25.      }
  26.  
  27.      pInsert = AcDbBlockReference::cast(pEnt);
  28.      if (!pInsert)
  29.      {
  30.        acutPrintf(L"\nВыбрали не вставку блока.\n");
  31.        pEnt->close();
  32.        return;
  33.      }
  34.  
  35.      // Получаем objectID определения блока.
  36.      AcDbObjectId blockDefId = pInsert->blockTableRecord();
  37.  
  38.      // Закрываем вставку блока.
  39.      pInsert->close();
  40.  
  41.      // Открываем определение блока.
  42.      AcDbBlockTableRecord *pBlkRecord;
  43.      if (Acad::eOk != (es = acdbOpenObject(pBlkRecord,
  44.                                     blockDefId,
  45.     AcDb::kForRead)))
  46.      {
  47.        acutPrintf(L"\nНельзя получить доступ к определению блока.\n");
  48.        return;
  49.      }
  50.  
  51.      // Получаем имя определения блока.
  52.      const TCHAR* pBlkName;
  53.      es = pBlkRecord->getName(pBlkName);
  54.      pBlkRecord->close();
  55.      if ((Acad::eOk != es) || !pBlkName)
  56.      {
  57.        acutPrintf(L"\nНе можем получить имя блока.\n");
  58.        return;
  59.      }
  60.  
  61.      acutPrintf(L"\nИмя блока: '%s'\n", pBlkName);
  62. }

 

Примечание переводчика: Этот код справедлив только для нединамических блоков. Для динамического блока мы получим имя в формате “*Unnn”. Для универсального получения имени блока можно использовать такой код:

 

Код - C++: [Выделить]
  1. //----------------------------------------------------------------
  2. // Печать имени выбранного блока (динамического или статического)
  3. //----------------------------------------------------------------
  4. static void PrintBlockName(void)
  5. {
  6.     ads_name en; ads_point p;
  7.     if (acedEntSel(_T("\nВыберите вставку блока: "),en,p) == RTNORM) {
  8.         AcDbObjectId eId; acdbGetObjectId(eId,en);
  9.         AcDbObjectPointer pBlkRef(eId,AcDb::kForRead);
  10.         if (pBlkRef.openStatus() == Acad::eOk) {
  11.             AcDbObjectId idBlkTblRec = pBlkRef->blockTableRecord();
  12.             AcDbDynBlockReference dynBlk(eId);
  13.             if (dynBlk.isDynamicBlock()) {
  14.                 AcDbBlockTableRecordPointer pBTR(dynBlk.dynamicBlockTableRecord(),AcDb::kForRead);
  15.                 if (pBTR.openStatus() == Acad::eOk){
  16.                     const ACHAR *blkName = NULL; pBTR->getName(blkName);
  17.                     acutPrintf(_T("\nИмя динамического блока: \"%s\""), blkName);
  18.                 }
  19.             } else {
  20.                 AcDbBlockTableRecordPointer pBTR(pBlkRef->blockTableRecord(),AcDb::kForRead);
  21.                 const ACHAR *blkName = NULL; pBTR->getName(blkName);
  22.                 acutPrintf(_T("\nИмя статического блока: \"%s\""), blkName);
  23.             }
  24.         }
  25.     }
  26. }

 

Источник: http://adndevblog.typepad.com/autocad/2012/05/get-the-name-of-a-block.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=67.0

 

Опубликовано 29.05.2013
Отредактировано 08.06.2013 в 00:50:19