现在的位置: 首页 > 综合 > 正文

CreateDispatch

2013年09月10日 ⁄ 综合 ⁄ 共 8102字 ⁄ 字号 评论关闭
void CExcelaDlg::OnAutocadtest()
{
// TODO: Add your control notification handler code here
IAcadApplication m_autocad;
IAcadDocuments m_acaddocs;
IAcadDocument m_acaddoc;
IAcadModelSpace m_acadmodel;
LPDISPATCH pDisp;
LPUNKNOWN pUnk;
CLSID clsid;
BeginWaitCursor();
::CLSIDFromProgID(L"AutoCAD.Application",&clsid);
if(::GetActiveObject(clsid,NULL,&pUnk)==S_OK)
{
VERIFY(pUnk->QueryInterface(IID_IDispatch,(void**) &pDisp)==S_OK);
m_autocad.AttachDispatch(pDisp);
pUnk->Release();
}
else
{
if(!m_autocad.CreateDispatch("AutoCAD.Application"))
{
AfxMessageBox("Autocad program not found/n");
exit(1);
}
}
m_autocad.SetVisible(true);
m_acaddocs.AttachDispatch(m_autocad.GetDocuments(),true);
m_acaddoc.AttachDispatch(m_acaddocs.Add(vtMissing),true);
m_acadmodel.AttachDispatch(m_acaddoc.GetModelSpace(),true);
m_acadmodel.AddCircle(pVal,100);
m_acadmodel.ReleaseDispatch();
m_acaddoc.ReleaseDispatch();
m_acaddocs.ReleaseDispatch();
m_autocad.ReleaseDispatch();
有几个办法:
1.致信Autodesk,要求autocad自身只能运行一个实例
2.自己写个 Windows 外壳(Shell), 监控,只允许运行一个实例
3.拦截WinExec()
COleExceptione;HRESULThr=NOERROR;LPDISPATCHpDisp=NULL;LPUNKNOWNpUnk=NULL;CLSIDclsid;IAcadApplicationIApp=NULL;hr=::CLSIDFromProgID(L"AutoCAD.Application",&clsid);//获取类IDif(!SUCCEEDED(hr)){returnNULL;}if(::GetActiveObject(clsid,NULL,&pUnk)==S_OK){//ACAD已启动if(pUnk->QueryInte**ce(IID_IDispatch,(void**)&pDisp)==S_OK){IApp.AttachDispatch(pDisp);//建立与AutoCAD的连接pUnk->Release();returnIApp;}}elseif(!IApp.CreateDispatch(clsid,&e))//启动AutoCAD{TCHARpszErr[256];e.GetErrorMessage(pszErr,256);AfxMessageBox(pszErr);returnNULL;}
--  一个使用ActiveX自动化技术读写DWG文件的程序
斑竹,请救!在VC环境下我用OLE自动化技术来读写AutoCAD的DWG文件,我完全按照别人文章的程序建立程序,但是出现AutoCAD无法启动的错误.请问这是什么原因?
其读写DWG文件的函数如下:

void CAcadRWDwgDoc::OnRwDwg()
{
    // TODO: Add your command handler code here
    VARIANT startPoint,endPoint;
    SAFEARRAY* start = NULL;
    SAFEARRAY* end = NULL;
    IAcadApplication acad;

    COleVariant  covTrue((short)TRUE),
                 covFalse((short)FALSE),
                 covOne((long)0),
                 covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
    //启动Autocad应用软件

    if(!acad.CreateDispatch("AutoCAD.Application.15"))
    {
        AfxMessageBox("Autocad 启动失败");        
        return;
    }
    acad.SetVisible(TRUE);
    IAcadDocuments docs = acad.GetDocuments();
    long total = docs.GetCount();
    IAcadDocument doc = docs.Open("C:////Documents and Settings////Administrator////MyDocuments////Drawing1",covFalse);                                

    IAcadModelSpace mSpace = doc.GetModelSpace();
    long entitiesNum = mSpace.GetCount();

    if(entitiesNum >= 1)
    {
        IAcadEntity entity = mSpace.Item(covOne);
        CString name = entity.GetObjectName();

        if(name == "AcDbLine"){
            IAcadLine  line = mSpace.Item(covOne);
            startPoint = line.GetStartPoint();
            endPoint = line.GetEndPoint();
        }
    }
    start = PointToSafeArrayB(1,1,0);
    startPoint.vt = VT_R8|VT_ARRAY;
    startPoint.parray = start;
    end = PointToSafeArrayA(100,200,0);
    endPoint.vt = VT_R8|VT_ARRAY;
    endPoint.parray = end;
    mSpace.AddLine(startPoint,endPoint);
    mSpace.AddCircle(endPoint,60);
    mSpace.AddText("I LOVE YOU AUTOCAD",endPoint,100);
    SafeArrayDestroy(start);
    SafeArrayDestroy(end);

    COleVariant name("C:////Documents and Settings////Administrator////My Documents////Drawing1");
    doc.Close(covTrue,name);
    acad.Quit();
    
}
其中当程序执行到
if(!acad.CreateDispatch("AutoCAD.Application.15"))
    {
        AfxMessageBox("Autocad 启动失败");        
        return;
    }
这里时,编译指出不能找到指定的文件,另外,在注册表HKEY_CLASSES_ROOT中里找不到AutoCAD
组件的DLL文件名称。我想AutoCAD无法启动可能跟这个有关系?
----------------------------

WAHAHA:
作者: NinthOcean    时间: 2010-4-2 02:49 PM     标题: 请教一个奇怪的COM问题!

机器装了AutoCAD 2004以及AutoCAD 2006
对应的ProgID分别为:AutoCAD.Application.16,AutoCAD.Application.16.2
我CreateDispatch指定启动2004,为什么每次都打开2006,
有高手遇到类似的问题吗????

CString szAcadVersion = _T("AutoCAD.Application.16");
CLSID clsid;
::CLSIDFromProgID(szAcadVersion.AllocSysString(), &clsid);
IApp.CreateDispatch(clsid);///////////////////////////////


作者: Danielm103    时间: 2010-4-2 06:27 PM

can you use acedGetIDispatch ();


作者: zngsai    时间: 2010-4-3 03:46 PM

首先更正你的错误,ACAD2004的应用程序标识符,不是AutoCAD.Application.16,而是AutoCAD.Application.16.0。

不过,尽管你改成了正确的应用程序标识符,仍然无法达到预想效果,除非当你再打开一次ACAD2004后,再运行你的程序,则就会开启ACAD2004~

此后就会开启ACAD2004,要想开启ACAD2006,须再打开一次ACAD2006才行。

然,AutoCAD.Application.15.0不会出现这种情况,他会开启ACAD2002(假设你装了02、04、06)。


作者: niyao    时间: 2010-4-3 07:16 PM

//给一个完整的自动化菜单代码,经检测未发现不适用的AutoCAD版本,复制稍改就可以用了。其实ARX包内有示例,我不过小改了下。
void nycadacadamenu()
{
     AutoCAD::IAcadApplication *pAcad;
    AutoCAD::IAcadMenuBar *pMenuBar;
    AutoCAD::IAcadMenuGroups *pMenuGroups;
    AutoCAD::IAcadMenuGroup *pMenuGroup;
    AutoCAD::IAcadPopupMenus *pPopUpMenus;
    AutoCAD::IAcadPopupMenu *pPopUpMenu;
    AutoCAD::IAcadPopupMenuItem *pPopUpMenuItem;
try{
  
  HRESULT hr = NOERROR;
  CLSID clsid;
  LPUNKNOWN pUnk = NULL;
  LPDISPATCH pAcadDisp = NULL;
  
  hr = ::CLSIDFromProgID(L"AutoCAD.Application", &clsid);//不加AutoCAD版本号才是关键!!
  if (SUCCEEDED(hr))
  {
   if(::GetActiveObject(clsid, NULL, &pUnk) == S_OK)//检测AutoCAD是否启动
   {
    if (pUnk->QueryInterface(IID_IDispatch, (LPVOID*) &pAcadDisp) != S_OK)
     return;
    pUnk->Release();
   }
  }
  if (SUCCEEDED(pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication,(void**)&pAcad))  ){  
   pAcad->put_Visible(true);//设置可见
  } else {
   acutPrintf("/nQueryInterface trouble.");
   return;
  }
  
  pAcad->get_MenuBar(&pMenuBar);
  pAcad->get_MenuGroups(&pMenuGroups);
  
  pAcad->Release();
  
  
  long numberOfMenus;
  pMenuBar->get_Count(&numberOfMenus);
  pMenuBar->Release();
  
  VARIANT index;
  VariantInit(&index);
  V_VT(&index) = VT_I4;
  V_I4(&index) = 0;
  
  pMenuGroups->Item(index, &pMenuGroup);
  pMenuGroups->Release();
  
  pMenuGroup->get_Menus(&pPopUpMenus);
  pMenuGroup->Release();
  
  WCHAR wstrMenuName[256];
  MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, "地籍(&C)", -1, wstrMenuName, 256);
  
  
  // Enables the menu to be loaded/unloaded with the same command.
  ::VariantInit(&index);
  V_VT(&index) = VT_BSTR;
  V_BSTR(&index) = SysAllocString(wstrMenuName);
  hr = pPopUpMenus->Item(index,&pPopUpMenu);
  ::SysFreeString(index.bstrVal);
  
  if(hr == S_OK){
   pPopUpMenus->Release();
   VARIANT_BOOL bFlag;
   pPopUpMenu->get_OnMenuBar(&bFlag);
   if(bFlag == VARIANT_FALSE)
   {
    ::VariantInit(&index);
    V_VT(&index) = VT_I4;
    V_I4(&index) = numberOfMenus - 2;//确保自己的下拉菜单位于AutoCAD主菜单右边数第三个
    pPopUpMenu->InsertInMenuBar(index);
   }
   pPopUpMenu->Release();
   return;
  }
  
  pPopUpMenus->Add(wstrMenuName, &pPopUpMenu);
  pPopUpMenus->Release();
  
  if (pPopUpMenu != NULL) {
   pPopUpMenu->put_Name(wstrMenuName);
   
            WCHAR wstrMenuItemName[256];
            WCHAR wstrMenuItemMacro[256];
   
   MultiByteToWideChar(CP_ACP, 0, "绘界址线", -1, wstrMenuItemName, 256);
            MultiByteToWideChar(CP_ACP, 0, "INPUTLINE ", -1, wstrMenuItemMacro, 256);
   VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 0;
            pPopUpMenu->AddMenuItem(index, wstrMenuItemName, wstrMenuItemMacro, &pPopUpMenuItem);
   pPopUpMenuItem->put_HelpString(L"地籍测量:绘制界址线段。");
   
            MultiByteToWideChar(CP_ACP, 0, "界址边长", -1, wstrMenuItemName, 256);
            MultiByteToWideChar(CP_ACP, 0, "INPUTDIST ", -1, wstrMenuItemMacro, 256);
            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 1;
            pPopUpMenu->AddMenuItem(index, wstrMenuItemName, wstrMenuItemMacro, &pPopUpMenuItem);
   pPopUpMenuItem->put_HelpString(L"地籍测量:拾取界址线输入边长。");
   
   //省略其它菜单
   
   VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 19;
            pPopUpMenu->AddSeparator(index,&pPopUpMenuItem);//菜单分割条的代码提供一下
   
      
//省略其它菜单
   
   MultiByteToWideChar(CP_ACP,0,"关于...",-1,wstrMenuItemName,256);
   MultiByteToWideChar(CP_ACP, 0, "ABOUTTHIS ", -1, wstrMenuItemMacro, 256);
   VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 32;
            pPopUpMenu->AddMenuItem(index, wstrMenuItemName, wstrMenuItemMacro, &pPopUpMenuItem);
   pPopUpMenuItem->put_HelpString(L"关于...:软件版本、版权说明。");
       VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = numberOfMenus - 2;
            pPopUpMenu->InsertInMenuBar(index);
   
            pPopUpMenuItem->Release();
   pPopUpMenu->Release();
}//if
else{
  
  
}
}//try
catch(...)
{
  AfxMessageBox("Unexpect  error.");
  if(!pAcad) pAcad->Release();
  if(!pMenuBar) pMenuBar->Release();
  if(!pMenuGroups) pMenuGroups->Release();
  if(!pMenuGroup) pMenuGroup->Release();
  if(!pPopUpMenus) pPopUpMenus->Release();
  if(!pPopUpMenu) pPopUpMenu->Release();
  }
}//结束

抱歉!评论已关闭.