29/05/2013
Перебор всех IAcadBlock в IAcadBlocks используя ActiveX в C++
Вопрос:
В C++ я не вижу возможности перебрать IAcadBlocks, чтобы получить доступ к каждому IAcadBlock. Есть пример кода, который это делает?
Ответ:
Следующие два подхода перебирают IAcadBlocks для доступа к каждому IAcadBlock. Первый предполагает, что вы настроили ваш проект с использованием ARX/MFC и импортирована TLB-библиотеки AutoCAD COM.
Код - C++: [Выделить]
- void test()
- {
- try
- {
- // Получаем приложение
- IAcadApplicationPtr pIAcad =
- acedGetAcadWinApp()->GetIDispatch(TRUE);
- // Получаем коллекцию блоков
- IAcadBlocksPtr pIBlks =
- pIAcad->GetActiveDocument()->GetBlocks();
- // Подсчитываем блоки
- long nCnt =pIBlks->GetCount();
- for(long i=0; i<nCnt; i++)
- {
- _variant_t var(i);
- // каждый блок
- IAcadBlockPtr pIBlk = pIBlks->Item(var);
- BSTR str;
- // Получаем имя блока
- pIBlk->get_Name(&str);
- _bstr_t bstr(str);
- // Выводим окно с именем блока
- AfxMessageBox(bstr);
- ::SysFreeString(str);
- }
- }
- catch(_com_error& err)
- {
- AfxMessageBox(err.ErrorMessage());
- }
- }
Если вы используете директиву #import для файлов, включенных в ObjectARX, это можно сделать следующим образом.
Код - C++: [Выделить]
- static void test()
- {
- try
- {
- // Получаем приложение
- IDispatch* pDisp =
- acedGetAcadWinApp()->GetIDispatch(TRUE);
- if(!pDisp) _com_issue_error(E_POINTER);
- CComPtr<IAcadApplication> pIAcad;
- pDisp->QueryInterface(IID_IAcadApplication, (void**)&pIAcad);
- // Получаем текущий документ
- CComPtr<IAcadDocument> pIDoc;
- pIAcad->get_ActiveDocument(&pIDoc);
- // Получаем коллекцию блоков
- CComPtr<IAcadBlocks> pIBlks;
- pIDoc->get_Blocks(&pIBlks);
- long blksCnt;
- pIBlks->get_Count(&blksCnt);
- CComPtr<IAcadBlock> pIBlk;
- // Перебираем все блоки
- for(long i=0; i<blksCnt; i++)
- {
- _variant_t x(i);
- pIBlks->Item(x, &pIBlk);
- BSTR str;
- pIBlk->get_Name(&str);
- char buf[256];
- buf [0] =0 ;
- if(WideCharToMultiByte (CP_ACP,
- 0,
- str,
- -1,
- buf,
- 256,
- NULL,
- NULL))
- acutPrintf(_T("\nИмя %d-го блока: %s"), i, buf);
- ::SysFreeString(str);
- }
- }
- catch(_com_error& err)
- {
- AfxMessageBox(err.ErrorMessage());
- }
- }
Примечание переводчика: В коде присутствует вызов WideCharToMultiByte, который был нужен только в AutoCAD до 2006 включительно. Для AutoCAD 2007+ функция acutPrintf для формата %s требует wchar_t *, а не char *.
Обсуждение: http://adn-cis.org/forum/index.php?topic=55.0
Опубликовано 29.05.2013
Отредактировано 06.06.2013 в 12:53:13
Отредактировано 06.06.2013 в 12:53:13