用C++开发CAD,一般会选择ObjectARX,很少用OLE方式来开发,正因为很少,所以参考资料也少,帮助也少,
这点我 深有感触。为方便交流,我将近日的一些心得放在这里,还望多多指教!
1. 启动CAD,如果安装了CAD多个版本,当我们双击一个后缀是dwg或dxf的文件
时,默认是用最近一次启动的那个版本来打开文件,用COM启动CAD也一样。为了
避免这种情况,需要在程序ID上修改。
window.google_render_ad();IAcadApplication app;
LPUNKNOWN pUnk;
CLSID clsid;//获取Map3D的类ID//"AutoCAD.Application.17"表示启动AutoCAD Map3D 2008// "AutoCAD.Application.15"表示启动AutoCAD 2002,//而 "AutoCAD.Application.16"则是CAD2005::CLSIDFromProgID(L"AutoCAD.Application.17",&clsid);if(::GetActiveObject(clsid,NULL,&pUnk) == S_OK)//判断ACAD是否已启动
{ //CAD已经启动,则连接CAD即可
if (pUnk->QueryInterface(IID_IDispatch,(void**) &pDisp)== S_OK)
{
app.AttachDispatch(pDisp,FALSE);pUnk->Release(); } } else { //CAD没有启动,启动CAD app.CreateDispatch(clsid);
} app.SetVisible(TRUE); /设置为可见
2 获取文档
一般来说,启动CAD后即有一个默认的空白文档,如果要获取这个空白文档,就要
可以直接这样:
IAcadDocument oDoc=app.GetActiveDocument();
得到,IAcadApplication::GetActiveDocument()获取活动文档。
打开其他的文件, 调用IAcadDocument的Open函数:
oDoc.Open(_T("D:\\test.dwg"),COlevariant(_T("")));
要添加新的空白文档就调用:
IAcadDocuments oDocs=app.GetDocuments();
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
IAcadDocument oDoc=oDocs.Add(covOptional);
要直接打开其他文档则调用:
IAcadDocument oDoc=oDocs.Open(COleVariant(strPath),
COleVaraint((short)0L),COleVariant(_T("")));
好了,到这里也可以做一小结了,我把部分实例放在这里,其他部分如
(文档操作、选择集)以后再讲:
BOOL GetFiles(CStringArray &filesArray) { //... return TRUE; } BOOL OperatorCADFiles(IAcadDocument &oDoc) { if(oDoc.m_lpDispatch==NULL)return FALSE; oDoc.SendCommand(_T("zoom e\n"));
IAcadSelectionSets sets=oDoc.GetSelectionSets(); IAcadSelectionSet set; VARIANT vGrpVals,vtStr,vtStr2; BOOL bFlag=TRUE; try { COleSafeArray value,data,type,type2; SAFEARRAY *GrpVals ; SAFEARRAYBOUND bnd; COleSafeArray pt,pt2; IAcadPolyline polyLine; double d1[]={0,0,0} ; short typei[]={8,100}; long i=0,nFictureNum; BOOL bGenerateAsBlock=FALSE;
set=sets.Add(_T("test")); type.CreateOneDim(VT_I2,2,typei); pt.CreateOneDim(VT_R8,3,d1); bnd.lLbound = 0; vtStr.vt = VT_BSTR; vtStr.bstrVal = SysAllocString(_T("contour,0")); bnd.cElements= 2; GrpVals = SafeArrayCreate(VT_VARIANT,1, &bnd);
vtStr2.vt = VT_BSTR; vtStr2.bstrVal = SysAllocString(_T("AcDbPolyline"));
i=0; SafeArrayPutElement(GrpVals,&i,&vtStr); i=1; SafeArrayPutElement(GrpVals,&i,&vtStr2 );
vGrpVals.vt = VT_VARIANT | VT_ARRAY; vGrpVals.parray = GrpVals;
//select AcDbPolyline on layers "contour" or "0" set.Select(5,pt,pt,type,vGrpVals); VariantClear(&vGrpVals);
nFictureNum=set.GetCount(); for(i=0;i<nFictureNum;i++)
{ polyLine.AttachDispatch(set.Item(COleVariant(i))); polyLine.SetLayer(_T("new_layer")); } } catch (CException* e) { TCHAR szError[256]; bFlag=FALSE; e->GetErrorMessage(szError,255); AfxMessageBox(szError); } set.Delete(); set.ReleaseDispatch(); sets.ReleaseDispatch(); return bFlag; } void ReadCADFiles() { IAcadApplication app; IAcadDocuments oDocs; CLSID clsid; CStringArray strFilesPath;
app.m_lpDispatch=NULL; ::CLSIDFromProgID(_T("AutoCAD.Application.17"),&clsid); app.CreateDispatch(clsid); app.SetVisible(1); oDocs = app.GetDocuments(); if(!GetFiles(strFilesPath)) { AfxMessageBox(_T("Can not find files!")); goto ExitFun; }
for(int i=0;i<strFilesPath.GetSize();i++) { IAcadDocument oDoc=oDocs.Open(strFilesPath.GetAt(i),COleVariant((short)1),COleVariant(_T(""))); OperatorCADFiles(oDoc); oDoc.Close(COleVariant((short)0),COleVariant(_T(""))); } ExitFun: oDocs.Close(); app.Quit(); }