[转载]实体反应器的用法_客博_新浪博客
[转载]实体反应器的用法

#i nclude "dbapserv.h"
#i nclude "dbents.h"
#i nclude "accmd.h"


// 下面这个例子为直线A添加一个反应器,并且关联到标注,当A有变化时,标注也会随之变化
void addToModelSpace(AcDbObjectId &objId, AcDbEntity* pEntity);

// AsdkObjectToNotify - 反应器对象
class AsdkObjectToNotify : public AcDbObject
{
public:
    ACRX_DECLARE_MEMBERS(AsdkObjectToNotify);
    AsdkObjectToNotify() {};
    void eLinkage(AcDbObjectId i) {mId=i;}
    void              modified(const AcDbObject*);
    Acad::ErrorStatus dwgInFields(AcDbDwgFiler*);
    Acad::ErrorStatus dwgOutFields(AcDbDwgFiler*) const;
    Acad::ErrorStatus dxfInFields(AcDbDxfFiler*);
    Acad::ErrorStatus dxfOutFields(AcDbDxfFiler*) const;
private:
    AcDbObjectId mId;
};

ACRX_DXF_DEFINE_MEMBERS(AsdkObjectToNotify, AcDbObject,
    AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
    0, ASDKOBJECTTONOTIFY, persreac);


// 每次直线实体变化时会通知反应器,就会调用反应器的这个函数. 
// 调用时,传入的是修改的那个直线指针,在这个函数里对你的要起反应的直线修改
//
void AsdkObjectToNotify::modified(const AcDbObject* pObj)
{
    AcDbLine *pLine = AcDbLine::cast(pObj);
    if (pLine == NULL)
 {
        const char* cstr = pObj->isA()->name();
        acutPrintf("这是一个 %s实体。\n", cstr);
        acutPrintf("我只能处理直线。\n");
        return;
    }
    acutPrintf("\n直线 %lx的反应器在修改标注 %lx。\n", pLine->objectId(), mId);

    AcDbAlignedDimension *pDim;
    if (acdbOpenObject((AcDbObject*&)pDim, mId, AcDb::kForWrite) == Acad::eOk)
    {
  // 修改标注
  pDim->setXLine1Point(pLine->startPoint());
  pDim->setXLine2Point(pLine->endPoint());
  pDim->close();
    }
}


// 反应器导入函数
Acad::ErrorStatus
AsdkObjectToNotify::dwgInFields(AcDbDwgFiler* filer)
{
    assertWriteEnabled();
    AcDbObject::dwgInFields(filer);
    filer->readItem((AcDbSoftPointerId*) &mId);
    return filer->filerStatus();
}


// 反应器导出
Acad::ErrorStatus
AsdkObjectToNotify::dwgOutFields(AcDbDwgFiler* filer) const
{
    assertReadEnabled();
    AcDbObject::dwgOutFields(filer);
    filer->writeItem((AcDbSoftPointerId&)mId);
    return filer->filerStatus();
}


// dxf函数
Acad::ErrorStatus
AsdkObjectToNotify::dxfInFields(AcDbDxfFiler* filer)
{
    assertWriteEnabled();
    Acad::ErrorStatus es;
    if ((es = AcDbObject::dxfInFields(filer)) != Acad::eOk)
    {
        return es;
    }

    if(!filer->atSubclassData("AsdkObjectToNotify"))
 {
        return Acad::eBadDxfSequence;
    }

    struct resbuf rbIn;
    while (es == Acad::eOk)
 {
        if ((es = filer->readItem(&rbIn)) == Acad::eOk) {
   if (rbIn.restype == AcDb::kDxfSoftPointerId)
            {
                // ObjectIds are filed in as ads_names.
                 acdb GetObjectId_r(mId, rbIn.resval.rlname);
            }
   else
     // invalid group
                return(filer->pushBackItem());
            }
        }
    }
    return filer->filerStatus();
}


// dxf函数
Acad::ErrorStatus
AsdkObjectToNotify::dxfOutFields(AcDbDxfFiler* filer) const
{
    assertReadEnabled();
    AcDbObject::dxfOutFields(filer);
    filer->writeItem(AcDb::kDxfSubclass, "AsdkObjectToNotify");
    filer->writeItem(AcDb::kDxfSoftPointerId, mId);
    return filer->filerStatus();
}


// 创建一条线和一个标注,并让他们互相关联起来(通过反应器)
void
assocLines()
{
    AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
    AcDbObjectId aId, dimId;
    AcDbLine *pLineA = new AcDbLine;
    pLineA->setDatabaseDefaults(pDb);
    pLineA->setStartPoint(AcGePoint3d(1, 1, 0));
    pLineA->setEndPoint(AcGePoint3d(2, 1, 0));
    addToModelSpace(aId, pLineA);
    acutPrintf( "Line A is %lx from 1,1 to 2,1.\n", pLineA->objectId());

 AcDbAlignedDimension *pDim = new AcDbAlignedDimension(
  AcGePoint3d(1, 10, 0),
  AcGePoint3d(2, 10, 0),
  AcGePoint3d(1, 10, 0),
  NULL,
  AcDbObjectId::kNull);
 addToModelSpace(dimId, pDim);
 pDim->close();

    // 打开命名对象词典, 并且检查是否有条目“ASDK_DICT”存在
    // 如果没有,创建一个字典,并且添加到命名对象字典中
    //
    AcDbDictionary *pNamedObj = NULL;
    AcDbDictionary *pNameList = NULL;
    pDb-> getNamedObjectsDictionary_r(pNamedObj, AcDb::kForWrite);

    if (pNamedObj-> getAt_r("ASDK_DICT", (AcDbObject*&)pNameList, AcDb::kForWrite) == Acad::eKeyNotFound)
    {
        pNameList = new AcDbDictionary;
        AcDbObjectId DictId;
        pNamedObj->setAt("ASDK_DICT", pNameList, DictId);
    }
    pNamedObj->close();

    // 为直线A创建反应器
    AsdkObjectToNotify *pObj = new AsdkObjectToNotify();
    pObj->eLinkage(dimId); // 把标注的ID存入反应器,以便在A被修改时,能修改标注

    AcDbObjectId objId;
    if ((pNameList-> getAt_r("object_to_notify_A", objId)) == Acad::eKeyNotFound)
    {
        pNameList->setAt("object_to_notify_A", pObj, objId);
        pObj->close();
    } else {
        delete pObj;
        acutPrintf("object_to_notify_A already exists\n");
    }

    // 为直线A添加{yj}反应器
    pLineA->addPersistentReactor(objId);
    pLineA->close();
    pNameList->close();
}

// 添加一个实体到模型空间
void
addToModelSpace(AcDbObjectId &objId, AcDbEntity* pEntity)
{
    AcDbBlockTable *pBlockTable;
    AcDbBlockTableRecord *pSpaceRecord;
    acdbHostApplicationServices()->workingDatabase()
        -> getSymbolTable_r(pBlockTable, AcDb::kForRead);
    pBlockTable-> getAt_r(ACDB_MODEL_SPACE, pSpaceRecord, AcDb::kForWrite);
    pBlockTable->close();
    pSpaceRecord->appendAcDbEntity(objId, pEntity);
    pSpaceRecord->close();
    return;
}

// 初始化应用程序
void initApp()
{
    acedRegCmds->addCommand("ASDK_ALINES", "ASDK_ALINES",
        "ALINES", ACRX_CMD_MODAL, assocLines);
    AsdkObjectToNotify::rxInit();
    acrxBuildClassHierarchy();
}

void unloadApp()
{
    acedRegCmds->removeGroup("ASDK_ALINES");
    // 删除自定义反应器
    deleteAcRxClass(AsdkObjectToNotify::desc());
}

// 入口函数
//
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;
}

已投稿到:
郑重声明:资讯 【[转载]实体反应器的用法_客博_新浪博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——