subErase、subOpen、subClose 和 subCancel
、 和 函数 都具有以前缀 sub 开头的对应虚函数。可以重写这些辅助函数,以便为派生类提供额外的功能。辅助函数由非虚拟的“master”函数调用。例如,调用 .签名如下:erase()open()close()cancel()erase()subErase()subErase() virtual Acad::ErrorStatus subErase(Adesk::Boolean pErasing); 重写附属函数
最好不要更改附属函数中的任何状态。如果必须更改状态,请尝试在调用同一函数的父类实现后更改它(以防返回错误代码)。如果必须在调用父类函数之前更改状态,则请准备好在父类返回错误状态时撤消它。 下面的示例演示擦除对象时调用的函数的实现。该函数检查对其他对象的硬指针引用,并擦除它们。subErase()subErase() class AsdkEllipse : public AcDbEllipse // This class extends AcDbEllipse by adding in functionality // to store a dynamic array of hard pointer object IDs. // // The subErase() member function has been overridden and // implemented, so when an object of this class is // erased, the objects pointed to by the hard pointer IDs // stored within the object will also be erased. // { public: ACRX_DECLARE_MEMBERS(AsdkEllipse); AsdkEllipse() {}; AsdkEllipse(const AcDbObjectIdArray& ellipses) : mEllipseIds(ellipses) {}; AsdkEllipse(const AcGePoint3d& center, const AcGeVector3d& unitNormal, const AcGeVector3d& majorAxis, double radiusRatio, double startAngle = 0.0, double endAngle = 6.28318530717958647692); AsdkEllipse(const AcDbObjectIdArray& ellipses, const AcGePoint3d& center, const AcGeVector3d& unitNormal, const AcGeVector3d& majorAxis, double radiusRatio, double startAngle = 0.0, double endAngle = 6.28318530717958647692); AcDbObjectId ellipseId(unsigned short which); Acad::ErrorStatus setEllipseId( const AcDbObjectId& objId, unsigned short which); Acad::ErrorStatus setEllipseIds( const AcDbObjectIdArray& Ids); Acad::ErrorStatus appendId(const AcDbObjectId& objId); Acad::ErrorStatus appendIds( const AcDbObjectIdArray& objIds); inline Adesk::Boolean removeId( const AcDbObjectId& objId); // AcDbObject overrides. // virtual Acad::ErrorStatus subErase( Adesk::Boolean pErasing); virtual Acad::ErrorStatus dwgInFields( AcDbDwgFiler* filer); virtual Acad::ErrorStatus dwgOutFields( AcDbDwgFiler* filer) const; virtual Acad::ErrorStatus dxfInFields( AcDbDxfFiler* filer); virtual Acad::ErrorStatus dxfOutFields( AcDbDxfFiler* filer) const; virtual Acad::ErrorStatus wblockClone( AcRxObject* pOwnerObject, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary = Adesk::kTrue) const; // AcDbEntity overrides. // virtual void list() const; private: AcDbObjectIdArray mEllipseIds; static int mInFlux; // == 1 when first object's // subErase is erasing. }; ACRX_DXF_DEFINE_MEMBERS(AsdkEllipse, AcDbEllipse, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 0,\ ASDKELLIPSE, REFERENC); // Static class data member definition. // int AsdkEllipse::mInFlux = Adesk::kFalse; AsdkEllipse::AsdkEllipse(const AcGePoint3d& center, const AcGeVector3d& unitNormal, const AcGeVector3d& majorAxis, double radiusRatio, double startAngle, double endAngle) : AcDbEllipse(center, unitNormal, majorAxis, radiusRatio, startAngle, endAngle) { } AsdkEllipse::AsdkEllipse(const AcDbObjectIdArray& ellipses, const AcGePoint3d& center, const AcGeVector3d& unitNormal, const AcGeVector3d& majorAxis, double radiusRatio, double startAngle, double endAngle) : AcDbEllipse(center, unitNormal, majorAxis, radiusRatio, startAngle, endAngle), mEllipseIds(ellipses) { } AcDbObjectId AsdkEllipse::ellipseId(unsigned short which) { assertReadEnabled(); if (which > mEllipseIds.length()) return AcDbObjectId::kNull; return mEllipseIds[which]; } Acad::ErrorStatus AsdkEllipse::setEllipseId(const AcDbObjectId& objId, unsigned short which) { assertWriteEnabled(); if (which > mEllipseIds.length()) return Acad::eInvalidIndex; mEllipseIds[which] = objId; return Acad::eOk; } Acad::ErrorStatus AsdkEllipse::setEllipseIds(const AcDbObjectIdArray& objIds) { assertWriteEnabled(); if (objIds.length() == 0) return Acad::eNullObjectId; mEllipseIds = objIds; return Acad::eOk; } Acad::ErrorStatus AsdkEllipse::appendId(const AcDbObjectId& objId) { assertWriteEnabled(); if (objId == AcDbObjectId::kNull) return Acad::eNullObjectId; mEllipseIds.append(objId); return Acad::eOk; } Acad::ErrorStatus AsdkEllipse::appendIds(const AcDbObjectIdArray& objIds) { assertWriteEnabled(); if (objIds.length() == 0) return Acad::eNullObjectId; mEllipseIds.append(objIds); return Acad::eOk; } inline Adesk::Boolean AsdkEllipse::removeId(const AcDbObjectId& objId) { assertWriteEnabled(); return mEllipseIds.remove(objId); } // This implementation of subErase opens and erases all // objects that this entity has hard pointer references // to. The effect is that when one AsdkEllipse is erased, // all the others it has hard pointers to also erase as // a "group". // Acad::ErrorStatus AsdkEllipse::subErase(Adesk::Boolean pErasing) { Acad::ErrorStatus es = AcDbEllipse::subErase(pErasing); if (es != Acad::eOk) return es; if (mInFlux == Adesk::kFalse) { mInFlux = Adesk::kTrue; AsdkEllipse *pEllipse; int es; for (int i = 0; i < mEllipseIds.length(); i++) { es = acdbOpenObject(pEllipse, mEllipseIds[i], AcDb::kForWrite, Adesk::kTrue); if (es != Acad::eOk) continue; pEllipse->erase(pErasing); pEllipse->close(); } mInFlux = Adesk::kFalse; } return Acad::eOk; } Acad::ErrorStatus AsdkEllipse::dwgInFields(AcDbDwgFiler* filer) { assertWriteEnabled(); AcDbEllipse::dwgInFields(filer); mEllipseIds.setLogicalLength(0); int idCount; filer->readInt32((long*)&idCount); AcDbHardPointerId objId; for (int i = 0; i < idCount; i++) { filer->readItem(&objId); mEllipseIds.append(objId); } return filer->filerStatus(); } Acad::ErrorStatus AsdkEllipse::dwgOutFields(AcDbDwgFiler* filer) const { assertReadEnabled(); AcDbEllipse::dwgOutFields(filer); filer->writeInt32(mEllipseIds.length()); for (int i = 0; i < mEllipseIds.length(); i++) { filer->writeHardPointerId(mEllipseIds[i]); } return filer->filerStatus(); } Acad::ErrorStatus AsdkEllipse::dxfInFields(AcDbDxfFiler* filer) { assertWriteEnabled(); Acad::ErrorStatus es = AcDbEllipse::dxfInFields(filer); if (es != Acad::eOk) { return es; } // Check to see if we're at the right subclass data // marker. // if (!filer->atSubclassData("AsdkEllipse")) { return Acad::eBadDxfSequence; } struct resbuf inbuf; AcDbObjectId objId; int idCount; filer->readItem(&inbuf); if (inbuf.restype == AcDb::kDxfInt32) { idCount = inbuf.resval.rint; } else { filer->pushBackItem(); filer->setError(Acad::eInvalidDxfCode, "\nError: expected group code %d", AcDb::kDxfInt32); return filer->filerStatus(); } for (int i = 0; i < idCount; i++) { es = filer->readItem(&inbuf); if (es != Acad::eOk) { filer->setError(Acad::eMissingDxfField, "\nError: expected more group code %d's", AcDb::kDxfHardPointerId); return filer->filerStatus(); } if (inbuf.restype == AcDb::kDxfHardPointerId) { acdbGetObjectId(objId, inbuf.resval.rlname); mEllipseIds.append(objId); } else { filer->pushBackItem(); filer->setError(Acad::eInvalidDxfCode, "\nError: expected group code %d", AcDb::kDxfHardPointerId); return filer->filerStatus(); } } return filer->filerStatus(); } Acad::ErrorStatus AsdkEllipse::dxfOutFields(AcDbDxfFiler* filer) const { assertReadEnabled(); AcDbEllipse::dxfOutFields(filer); filer->writeItem(AcDb::kDxfSubclass, "AsdkEllipse"); filer->writeInt32(AcDb::kDxfInt32, mEllipseIds.length()); for (int i = 0; i < mEllipseIds.length(); i++) { filer->writeObjectId(AcDb::kDxfHardPointerId, mEllipseIds[i]); } return filer->filerStatus(); } void AsdkEllipse::list() const { assertReadEnabled(); AcDbEllipse::list(); acutPrintf("\nClass:\t%s", isA()->name()); for (int i = 0; i < mEllipseIds.length(); i++) { acutPrintf("\nReferenceId[%d]:\t%ld", i, (mEllipseIds[i]).asOldId()); } } Acad::ErrorStatus AsdkEllipse::wblockClone(AcRxObject* pOwnerObject, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { assertReadEnabled(); static AcDbObjectId btr, pspace = AcDbObjectId::kNull; AcTransaction *pTrans = NULL; pClonedObject = NULL; if (pspace == AcDbObjectId::kNull) { AcDbBlockTable *pTable; database()->getSymbolTable(pTable, AcDb::kForRead); pTable->getAt(ACDB_PAPER_SPACE, pspace); pTable->close(); } if ( idMap.deepCloneContext() == AcDb::kDcXrefBind && ownerId() == pspace) return Acad::eOk; // Have we already done this entity ? // AcDbIdPair idPair(objectId(), (AcDbObjectId)NULL, Adesk::kTrue); if (idMap.compute(idPair) == TRUE && idPair.value() != NULL) { pClonedObject = NULL; return Acad::eOk; } AcDbBlockTableRecord *pBTR = AcDbBlockTableRecord::cast(pOwnerObject); if (pBTR != NULL) { if (isPrimary == Adesk::kTrue) btr = pBTR->objectId(); else btr = AcDbObjectId::kNull; } else if (btr != AcDbObjectId::kNull) { pTrans = actrTransactionManager->startTransaction(); pTrans->getObject((AcDbObject*&)pBTR, btr, AcDb::kForWrite); pOwnerObject = pBTR; } Acad::ErrorStatus es = AcDbEllipse::wblockClone(pOwnerObject, pClonedObject, idMap, btr != AcDbObjectId::kNull); if (pTrans) actrTransactionManager->endTransaction(); acutPrintf("\nWblockClone error status: %s", acadErrorStatusText(es) ); return Acad::eOk; } void createEllipses() { const ellipseCount = 10; AsdkEllipse *pEllipse; pEllipse = new AsdkEllipse(AcGePoint3d(4.0, 4.0, 0.0), AcGeVector3d(0.0, 0.0, 1.0), AcGeVector3d(2.0, 0.0, 0.0), 0.5); AcDbVoidPtrArray ellipses; ellipses.append(pEllipse); // Now use the getTransformedCopy() function with a // scaling matrix (in X & Y only) to create new // AsdkEllipses, each 0.5 units larger than the last in // the X & Y direction, but identical in the Z // direction. This would be similar to the // getOffsetCurves() function, but that function // returns AcDbSpline entities instead of AcDbEllipses. // double j = 1.1; AcGeMatrix3d scale; for (int i = 0; i < ellipseCount; i++, j += 0.1) { scale.setToScaling(j, pEllipse->center()); scale.entry[2][2] = 1.0; // Z scaling == 1 // getTransformed copy uses this->clone() to create // a new object, which the ent pointer is assigned // to point to. Therefore, ent should NOT point to an // existing entity or there will be a memory leak! // // Since this->clone() is used, the AsdkEllipse class // must override this member function to // be sure that an AsdkEllipse is created instead // of just an AcDbEllipse. // AsdkEllipse *pNextEllipse; ((AsdkEllipse*)ellipses[0])->getTransformedCopy( scale, (AcDbEntity*&)pNextEllipse); ellipses.append(pNextEllipse); } AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase() ->getSymbolTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite); pBlockTable->close(); AcDbObjectIdArray ellipseIds; AcDbObjectId tempId; for (i = 0; i < ellipses.length(); i++) { pBlockTableRecord->appendAcDbEntity(tempId, (AsdkEllipse*)ellipses[i]); ellipseIds.append(tempId); } pBlockTableRecord->close(); // Set up the hard pointers and close the ellipses. // for (i = 0; i < ellipses.length(); i++) { // Add in all the IDs. // ((AsdkEllipse*)ellipses[i]) ->setEllipseIds(ellipseIds); // Now remove the object ID of the "*this" ellipse // so it doesn't reference itself. // ((AsdkEllipse*)ellipses[i])->removeId( ((AsdkEllipse*)ellipses[i])->objectId()); ((AsdkEllipse*)ellipses[i])->close(); } } void initApp() { acedRegCmds->addCommand("ASDK_ELLIPSES", "ASDK_ELLIPSES", "ELLIPSES", ACRX_CMD_MODAL, createEllipses); AsdkEllipse::rxInit(); acrxBuildClassHierarchy(); } void unloadApp() { acedRegCmds->removeGroup("ASDK_ELLIPSES"); // Remove the AsdkEllipse class from the ACRX runtime // class hierarchy. If this is done while the database is // still active, it should cause all objects of class // AsdkEllipse to be turned into proxies. // deleteAcRxClass(AsdkEllipse::desc()); } extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* appId) { switch (msg) { case AcRx::kInitAppMsg: acrxDynamicLinker->unlockApplication(appId); acrxDynamicLinker->registerAppMDIAware(appId); initApp(); break; case AcRx::kUnloadAppMsg: unloadApp(); } return AcRx::kRetOK; } 父主题: |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2024-12-15 22:19
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.