CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

派生自 IAcadBaseObject2Impl

2022-12-31 10:37| 发布者: admin| 查看: 295| 评论: 0|来自: AutoCAD

AsdkSquareWrapper_DGSDK 示例不会创建或操作非数据库驻留对象。如果您检查其源代码,您可能会注意到 thewrapper 类似乎不是从 bothor 派生的。不过,它设置为支持非数据库驻留的对象。这是可能的,因为包装类派生自,而包装类又派生自。该类继承了实现。如果对象派生自 anyor,则不需要显式派生自。CAsdkSquareWrapperIAcadBaseObjectImplIAcadBaseObject2ImplIAcadEntityDispatchImplIAcadObjectDispatchImplIAcadObjectDispatchImplIAcadBaseObject2ImplIAcadEntityDispatchImplIAcadObjectDispatchImplIAcadBaseObject2Impl

IAcadBaseObject并且主要区别在于它们如何识别对象。驻留在数据库的对象可以通过其对象 ID 唯一标识。此 ID 是用于引用它包装的对象的关键。不驻留在数据库中的对象不会分配对象 ID,因此会替换指向实例的指针。IAcadBaseObject2IAcadBaseObjectIAcadBaseObject2AcDbObject

为了支持此抽象,“特性”选项板 API 提供了类和模板类。Anobject 封装对 aninstance 的引用。此类支持常驻和非常驻 objects.is“智能指针”类,使应用程序可以轻松处理这两种类型的对象。模板类的代码用法可以替换为需要支持非数据库驻留对象的应用程序中的引用。AcAxObjectRefAcAxObjectRefPtrAcAxObjectRefAcDbObjectAcAxObjectRefPtrAcDbObjectPointerAcAxObjectRefPtr

实现非数据库驻留支持的AsdkSquareWrapper_DGSDK 示例提供了以下过程的代码示例。

实现对非数据库驻留对象的支持

在 COM 包装器的头文件中,将 COM 接口条目添加到接口的 COM 映射中:IAcadBaseObject2

BEGIN_COM_MAP(CAsdkSquareWrapper)
...
COM_INTERFACE_ENTRY(IAcadBaseObject)
COM_INTERFACE_ENTRY(IAcadBaseObject2)
...
END_COM_MAP()

请注意,COM 映射公开了两者。IAcadBaseObjectIAcadBaseObject2

在 COM 包装器的头文件中,声明实现方法所需的替代:IAcadBaseObject2

STDMETHOD(ForceDbResident)(VARIANT_BOOL *forceDbResident);
STDMETHOD(AddToDb)(AcDbObjectId& objId, 
    AcDbObjectId ownerId = AcDbObjectId::kNull, 
    TCHAR* keyName = NULL);
STDMETHOD(CreateObject)(AcDbObjectId ownerId = AcDbObjectId::kNull,
    TCHAR *keyName = NULL);

将任何实例替换为。例如:AcDbObjectPointerAcAxObjectRefPtr

AcDbObjectPointer<AsdkSquare> pSq(m_objId, AcDb::kForRead);

替换为

AcAxObjectRefPtr<AsdkSquare> pSq(&m_objRef, AcDb::kForRead);

在 COM 包装器的 CPP 文件中,实现所需的方法。如果支持非数据库驻留的对象,则必须实现 、 和函数。AsdkSquareWrapper_DGSDK 示例定义这些方法,如下所示:IAcadBaseObject2Impl ForceDbResident()AddToDb()CreateObject()

HRESULT CAsdkSquareWrapper::ForceDbResident(VARIANT_BOOL *forceDbResident) 
{
    if (NULL == forceDbResident)
        return E_POINTER;
    *forceDbResident = ACAX_VARIANT_FALSE;
    return S_OK;
}
HRESULT CAsdkSquareWrapper::AddToDb(AcDbObjectId& objId,
    AcDbObjectId ownerId, TCHAR* keyName)
{
    try 
    {
        AcAxDocLock docLock(ownerId);
        Acad::ErrorStatus es;
        AcAxObjectRefPtr<AsdkSquare> pSq(&m_objRef,
            AcDb::kForRead);
        AcDbBlockTableRecordPointer pBlockTableRecord(ownerId,
            AcDb::kForWrite);
        if((es = pBlockTableRecord.openStatus()) != Acad::eOk)
            throw es;
        if((es = pBlockTableRecord->appendAcDbEntity(objId,
            pSq.object())) != Acad::eOk)
            throw es;
    }
    catch(const Acad::ErrorStatus)
    {
        return Error(L"Failed to add square to database",
            IID_IAsdkSquareWrapper ,E_FAIL);
    }
    return SetObjectId(objId);
}
HRESULT CAsdkSquareWrapper::CreateObject(AcDbObjectId ownerId,
    TCHAR *keyName) 
{
    try 
    {
        Acad::ErrorStatus es;
        AcDbObjectPointer<AsdkSquare> pSq;
        if((es = pSq.create()) != Acad::eOk)
            throw es;
        pSq->setDatabaseDefaults(ownerId.database());
        AsdkSquare *pTmp = NULL;
        pSq.release(pTmp);
        SetObject((AcDbObject*&)pTmp);
    }
    catch(const Acad::ErrorStatus)
    {
        return Error(L"Failed to create square",
            IID_IAsdkSquareWrapper, E_FAIL);
    }
    return S_OK;
}

修改包装的对象时调用该函数。例如,每个属性访问或方法都应显式调用此函数,如下所示:IAcadBaseObject2Impl::Fire_Notification()put_*

STDMETHODIMP CAsdkSquareWrapper::put_Number(short newVal)
{
    AcAxDocLock docLock(m_objRef.objectId(),
        AcAxDocLock::kNormal);
    if(docLock.lockStatus() != Acad::eOk &&
        docLock.lockStatus() != Acad::eNoDatabase)
        return E_ACCESSDENIED;
    AcAxObjectRefPtr<AsdkSquare> pSq(&m_objRef,
        AcDb::kForWrite);
    if (pSq.openStatus() != Acad::eOk)
        return E_ACCESSDENIED;
    pSq->setSquareId(newVal);
Fire_Notification(DISPID_NUMBER);
return S_OK; }

该函数将更改通知连接的侦听器。侦听器是实现和接口的对象。此机制对于将“特性”选项板编辑与命令行输入同步非常重要,如特性选项板与命令的交互中所述。Fire_Notification()IAcadObjectEventsIPropertyNotifySink

驻留在数据库的对象不需要调用函数。他们的通知由AutoCAD反应器处理。Fire_Notification()


路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 12:02

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部