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() |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-1-8 19:48
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.