Exposing ObjectARX Functions Through ActiveX Automation

In the simplest case, your COM wrapper class will expose one or more functions that you would like to make available to developers using programming environments such as VBA. Again, you have the option of including your ObjectARX code in the COM DLL, or creating separate DLLs for the COM and ObjectARX components. The following sections provide procedures that explain the required process.

To create an Automation wrapper project for an ObjectARX application

  1. Set up your project according to the steps in Setting Up an ATL Project File.
  2. In the generated COM class header file, add the following code:
#include "dbmain.h"
#include "acad24.h"
#include "axtempl.h" // main ActiveX Automation template                      // header file

Change the derivation of your COM class by adding the following declaration to the end of its derivation list:

public IRetrieveApplicationImpl

Add the following entry to the COM_MAP:

COM_INTERFACE_ENTRY(IRetrieveApplication)

In the IDL file, add the following code after importlib("stdole32.tlb") and importlib("stdole2.tlb"):

importlib("acax24enu.tlb"); // revise the path to match your
                            // own AutoCAD installation

Make sure you substitute the path that matches your AutoCAD installation.

Once the wrapper is set up, you need to provide interfaces to expose your functionality through ActiveX.

To expose functionality through ActiveX

Add the desired ActiveX methods and properties to your wrapper class by choosing Add Method or Add Property from the ClassView Interface shortcut menu. In your COM class CPPfile, ATL generates stubs similar to the following:

STDMETHODIMP CAsdkSquareWrapper::get_Number(short *pVal)
{
}
STDMETHODIMP CAsdkSquareWrapper::put_Number(short newVal)
{
}

Typically, these members will be used to wrap calls to your ObjectARX application.

Add implementation code to the new COM class methods and properties. The following example shows a sample property implementation:

STDMETHODIMP CAsdkSquareWrapper::get_Number(short *pVal)
{
    // TODO: Add your implementation code here
    AcDbObjectPointer<AsdkSquare> pSq(m_objId, AcDb::kForRead);
    if (pSq.openStatus() != Acad::eOk)
            return E_ACCESSDENIED;          
    int id;
    pSq->squareId(id);
    *pVal = id;
    return S_OK;
}
STDMETHODIMP CAsdkSquareWrapper::put_Number(short newVal)
{
    AcAxDocLock docLock(m_objId, AcAxDocLock::kNormal);
    if(docLock.lockStatus() != Acad::eOk)
        return E_ACCESSDENIED;
    AcDbObjectPointer<AsdkSquare> pSq(m_objId, AcDb::kForWrite);
    if (pSq.openStatus() != Acad::eOk)
        return E_ACCESSDENIED;          
    pSq->setSquareId(newVal);
    return S_OK;
}

Build and register the application according to the steps in Building and Registering a COM DLL.