VC++和OLE开发CAD

用C++开发CAD,一般会选择ObjectARX,很少用OLE方式来开发,正因为很少,所以参考资料也少,帮助也少,

这点我 深有感触。为方便交流,我将近日的一些心得放在这里,还望多多指教!

  1.    启动CAD,如果安装了CAD多个版本,当我们双击一个后缀是dwg或dxf的文件

    时,默认是用最近一次启动的那个版本来打开文件,用COM启动CAD也一样。为了

     避免这种情况,需要在程序ID上修改。

  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();
}
window.google_render_ad();

你可能感兴趣的:(VC++和OLE开发CAD)