ADN Club > ObjectARX
Рисовать в Autocad с помощью c++
Александр Ривилис:
Я подготовил небольшой пример, который показывает как запустить AutoCAD (через COM/ActiveX), создать новый документ, нарисовать в нем отрезок и несколько окружностей, сохранить его и выйти из AutoCAD. Имей в виду что в коде минимальное количество проверок на ошибки:
--- Код - C++ [Выбрать] ---#import "acax19enu.tlb" raw_interfaces_only no_namespace HRESULT PointToVariant(const double pt[3], VARIANT* pVal); void CMFCAcadAppDlg::OnBnClickedStartacad(){ // TODO: Add your control notification handler code here ::CoInitialize(NULL); COleMessageFilter* pFilter = AfxOleGetMessageFilter(); if (pFilter != NULL) { DWORD dTimedelay = 1000; pFilter->SetMessagePendingDelay(dTimedelay); // Врем ожидания - 1 сек dTimedelay = -1; pFilter->SetRetryReply(dTimedelay); pFilter->EnableBusyDialog(FALSE); // Запрещаем диалог "сервер занят" pFilter->EnableNotRespondingDialog(FALSE); // Запрещаем диалог "сервер не отвечает" } try { CLSID clsid ; // Для AutoCAD 2014 - L"AutoCAD.Application.19.1" // Если версия AutoCAD не важна, то можно L"AutoCAD.Application" _com_util::CheckError(CLSIDFromProgID (L"AutoCAD.Application.19.1", &clsid)); IAcadApplicationPtr pApp; // Если AutoCAD не запущен - попробуем запустить if (FAILED(pApp.GetActiveObject(clsid))) { _com_util::CheckError(pApp.CreateInstance(clsid)); } pApp->put_Visible(VARIANT_TRUE); // Получаем список открытых документов AutoCAD IAcadDocumentsPtr pDocs; _com_util::CheckError(pApp->get_Documents(&pDocs)); IAcadDocumentPtr pDoc; // Создаем новый документ-чертеж (для простоты с шаблоном acadiso.dwt) _com_util::CheckError(pDocs->Add(_variant_t(_T("acadiso.dwt")), &pDoc)); // Будем работать с пространством модели IAcadModelSpacePtr pSpace; _com_util::CheckError(pDoc->get_ModelSpace(&pSpace)); // Добавим отрезок с началом в {0 0 0} и концом в {10 10 0} IAcadLinePtr pLine; _variant_t vStart, vEnd; // Начало и конец отрезка const int iMax = 10; double p1[3] = {0, 0, 0}, p2[3] = { iMax, iMax, 0}; _com_util::CheckError(PointToVariant(p1, &vStart)); _com_util::CheckError(PointToVariant(p2, &vEnd)); _com_util::CheckError(pSpace->AddLine(/*начало*/ vStart, /*конец*/ vEnd, &pLine)); _com_util::CheckError(pLine->put_color(acYellow)); // Меняем цвет на желтый // Добавим окружности вдоль отрезка с радиусом 1 IAcadCirclePtr pCircle; for (int i = 0; i <= iMax; i++) { p1[0] = i; p1[1] = i; _com_util::CheckError(PointToVariant(p1, &vStart)); _com_util::CheckError(pSpace->AddCircle( /*центр*/ vStart, /*радиус*/ 1.0, &pCircle)); _com_util::CheckError(pCircle->put_color(acGreen)); // Меняем цвет на зеленый } pDoc->SaveAs(_bstr_t(_T("C:\\test.dwg"))); pApp->Quit(); } catch(const _com_error e) { if (e.ErrorMessage()!=NULL) { CString msg; msg.Format(_T("Error: %s"),e.ErrorMessage()); AfxMessageBox(msg,MB_ICONERROR); } } ::CoUninitialize();} //////////////////////////////////////////////////////////////////////////// Функция для преобразования точки double pt[3] в VARIANT//////////////////////////////////////////////////////////////////////////HRESULT PointToVariant(const double pt[3], VARIANT* pVal){ pVal->vt = VT_ARRAY | VT_R8; SAFEARRAYBOUND rgsaBound; rgsaBound.lLbound = 0L; rgsaBound.cElements = 3; pVal->parray = SafeArrayCreate(VT_R8, 1, &rgsaBound); if (!pVal->parray) return E_OUTOFMEMORY; HRESULT hr; for (long i = 0; i < 3; i++) { if ((hr = SafeArrayPutElement(pVal->parray,&i,(void*)&pt[i])) != S_OK) return hr; } return S_OK;}Полный проект для VS 2012 приложил.
Nevermind.qqq:
Большое спасибо, буду разбираться
Александр Ривилис:
--- Цитата: Nevermind.qqq от 17-09-2014, 22:54:24 ---Большое спасибо, буду разбираться
--- Конец цитаты ---
Пожалуйста. Будут вопросы - задавай.
Nevermind.qqq:
Нигде не удалось найти VS12 ultimate или professional , поставил VS13 ultimate,собрал программу(Release, т.к. Debug ошибку выбивает). Диалоговое окно открывается, жму "Запустить AutoCAD", он запускается, появляется Чертеж1(видимо который стандартно при запуске создается), и Чертеж2(видимо созданный программой) - оба пустые, при открытии диалогового окна видно что оно выбило ошибку "Error:вызов был отклонен" .Так же один раз приложение все-таки создало test.dwg - но увы пустой, и только 1 раз.
Компилятор пишет следующее:
First-chance exception at 0x7612C41F (KernelBase.dll) in MFCAcadApp.exe: 0x80010001: Вызов был отклонен.
First-chance exception at 0x7612C41F in MFCAcadApp.exe: Microsoft C++ exception: _com_error at memory location 0x0017F45C.
Александр Ривилис:
Ну а теперь тоже самое, только в режиме отладки, пошагово и/или с контрольными точками и посмотри где затык.
Навигация
Перейти к полной версии