Тема: Помогите перевести этот код на С++

Помогите перевести этот код на С++
Dim acadApp As Object
On Error Resume Next
Set acadApp = GetObject(, "AutoCAD.Application")
If Err Then
Err.Clear
Set acadApp = CreateObject("AutoCAD.Application")
If Err Then
MsgBox Err.Description
Exit Sub
End If
End If
acadApp.Visible = True
acadApp.Documents.Open ("C:\downtown.dwg")

Re: Помогите перевести этот код на С++

int OpenDwgFile()
{
    ::CoInitialize(NULL);
    try
    {
        CLSID clsid ;
        _com_util::CheckError(CLSIDFromProgID (L"AutoCAD.Application", &clsid));
        AutoCAD::IAcadApplicationPtr pApp;
        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));
        AutoCAD::IAcadDocumentPtr pDoc;
        _com_util::CheckError(pDocs->Open(_bstr_t("c:\\downtown.dwg"),_variant_t(false),&pDoc));
    }
    catch(const _com_error e)
    {
        if (e.ErrorMessage()!=NULL)
            acutPrintf("Error: %s",e.ErrorMessage());
    }
    ::CoUninitialize();
  return 0;
}

Re: Помогите перевести этот код на С++

Добавь в начало строку для AutoCAD 2004-2006:

#import "acax16enu.tlb"

или для AutoCAD 2000-2002:

#import "acad.tlb"

Re: Помогите перевести этот код на С++

Спасибо за хорошие советы, но тут еще один вопрос. Как получить доступ к уже существующей надписи и изменить ее содержание?
И еще почему не работает такой код:

::CoInitialize(NULL);
    try
    {
        CLSID clsid ;
        _com_util::CheckError(CLSIDFromProgID(L"AutoCAD.Application", &clsid));
        AutoCAD::IAcadApplicationPtr pApp;
        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));
        AutoCAD::IAcadDocumentPtr pDoc;
        _com_util::CheckError(pDocs->Open(_bstr_t("c:\\g1.dwg"),_variant_t(false),&pDoc));
        //_com_util::CheckError(pApp->Update());
        AutoCAD::IAcadModelSpacePtr pModelSpace;
        _com_util::CheckError(pDoc->get_ModelSpace(&pModelSpace));
        //AutoCAD::IAcadMTextPtr pTxt;
        double p[2];
        p[0]=20;
        p[1]=30;
        p[2]=50;
        _com_util::CheckError(pModelSpace->AddMText(p,2,_bstr_t("Hello world")));
    }
    catch(const _com_error e)
    {
        if (e.ErrorMessage()!=NULL)
                //            cout<<e.ErrorMessage();
            return -1;
    }
::CoUninitialize();

Re: Помогите перевести этот код на С++

Я не понял главного. Ты создаешь arx-файл или exe-файл? Если arx-файл, то зачем изврашаться и обращаться к чертежу через "одно место" (именуемое ActiveX), если для этого в ObjectARX есть специальные методы?
А по поводу твоего кода - проверять не стал, но первое, что бросилось в глаза - ты объявил double p[2], а записываешь в p[2], т.е. явно за границу. К тому же AddMtext требует не double [3], а Variant, который получается при помощи следующей функции:

HRESULT getVariantFromPoint(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;
}

И твой код превращается приблизительно в это:

...
double p[3];
p[0]=20; p[1]=30; p[2]=50;
VARIANT vp;  VariantInit(&vp);
_com_util::CheckError(getVariantFromPoint(p,&vp));
_com_util::CheckError(pModelSpace->AddMText(vp,2,_bstr_t("Hello world")));

Re: Помогите перевести этот код на С++

Я пишу отдельно работающее приложение,которое использует AutoCAD для отображения результатов работы (даные все время меняются). Мне нужно как-то получить доступ к надписе на листе и поменять ее содержание. Проблема в том что я вообще никогда не пользовался AutoCAD и COM так как программировал восновном под Unix! Может заодно и литературу какую-нить посоветуете, а то у меня есть книжечка Дональда Бокса по СОМ и в ней такого способа работы с интерфейсами вообще не описано!

Re: Помогите перевести этот код на С++

> IUnknown
Ух! Могу посочувствовать...
Из собственного опыта программирования под AutoCAD (15 лет профессиональной работы):
1) Пользоваться ActiveX только если все другие способы невозможны.
2) Не писать внешние exe, запускающие AutoCAD, если можно написать arx, который будет делать все необходимое и отображать результаты непосредственно в AutoCAD.
3) Если же пункт 2) по каким-то причинам невозможен, то запускать acad.exe и передать ему в качестве параметра arx-файл, который и будет выполнять внутри AutoCAD все, что необходимо. Если нужно синхронизовать exe-файл и arx-файл, то делать это используя Windows API.
4) Изучить документацию по ObjectARX и примеры, которые есть в нем.
По поводу литературы по COM/ActiveX - ничего не посоветую. sad