CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

子擦除、子打开、子关闭和子取消

2022-12-31 21:43| 发布者: admin| 查看: 930| 评论: 0|来自: AutoCAD

,,, 和函数都有以前缀sub 开头的相应虚函数。可以重写这些附属函数,以便为派生类提供额外的功能。附属函数由非虚拟“主”函数调用。例如,呼叫。签名如下:erase()open()close()cancel()erase()subErase()subErase()

virtual Acad::ErrorStatus
subErase(Adesk::Boolean pErasing);

覆盖附属函数

  1. 验证您的周围环境。例如,如果对象具有指向另一个对象的硬指针引用,并且您的对象正在取消擦除,则可以检查所引用的对象是否仍然存在。如果出现问题,请立即返回适当的错误状态,并且不要传递消息,因为错误状态将有效地终止操作。
  2. 如果一切正常,则调用该函数。检查其结果。如果它不返回,则返回。Your Parent::subErase()eOK
  3. 如果一切正常,请执行您的操作。

最好不要更改附属函数中的任何状态。如果必须更改状态,则在调用同一函数的父类实现后尝试更改它(以防返回错误代码)。如果在调用父类函数之前必须更改状态,则准备好在父类返回错误状态时将其反转。

下面的示例演示擦除对象时调用的函数的实现。该函数检查对其他对象的硬指针引用并擦除它们。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;
}

路过

雷人

握手

鲜花

鸡蛋

最新评论

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

GMT+8, 2024-5-19 14:30

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部