ObjectARX, AutoCAD. Среда программирования библиотеки C++

Формирование Иерархии Монопольных использований


Следующий пример иллюстрирует, как формировать иерархию монопольных использований, используя функции ObjectARX. Пример показывает заголовку и исходным файлам для нового класса, OwnerDemo, который иллюстрирует, как создать дерево монопольных использований. Этот класс имеет два компонента данных, простое целое число, чтобы представить нормальные данные, и жесткое монопольное использование компонент данных ИДЕНТИФИКАТОРА, чтобы провести{*держать*} объект ID находящегося в собственности объекта. Функции

Обеспечиваются для получения и установки значений обоих компонентов данных.

Пример также отменяет четыре требуемых виртуальных функции:

dwgInFields(), dwgOutFields(), dxfInFields(), и  dxfOutFields().

Иерархия монопольных использований установлена в createObjs () подпрограмма к концу примера. Объект имеет объект B. Объект B имеет объект C. Объект добавлен к словарю (ASDK_DICT) в названном объектном словаре. printOut() и listTree () подпрограммы печатает информацию относительно объектов в ASDK_DICT словаре.

ObjectARX Example

// Class declarations

//

class AsdkOwnerDemo : public AcDbObject

// This is a custom object class to demonstrate what is

// necessary to create ownership trees.

//

// To keep it simple, this class has two data members: a



// simple integer to represent normal data, and a hard

// ownership ID data member to hold the object ID of an owned

// object.

//

// Get and set functions are provided for both data members.

//

{

public:

ACRX_DECLARE_MEMBERS(AsdkOwnerDemo);

AsdkOwnerDemo(): mIntval(0) {};

AsdkOwnerDemo(const Adesk::Int16& val): mIntval(val) {};

Adesk::Int16 intData();

Acad::ErrorStatus setIntData(const Adesk::Int16&);

AcDbHardOwnershipId idData();

Acad::ErrorStatus setIdData(const AcDbHardOwnershipId&);

Acad::ErrorStatus dwgInFields (AcDbDwgFiler*);

Acad::ErrorStatus dwgOutFields(AcDbDwgFiler*) const;

Acad::ErrorStatus dxfInFields (AcDbDxfFiler*);

Acad::ErrorStatus dxfOutFields(AcDbDxfFiler*) const;


private:

Adesk::Int16 mIntval;

AcDbHardOwnershipId mObjId;

};

ACRX_DXF_DEFINE_MEMBERS(AsdkOwnerDemo, AcDbObject,

AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 0,

ASDKOWNERDEMO, OWNERSHIP);

// Gets the value of the integer data member.

//

Adesk::Int16

AsdkOwnerDemo::intData()

{

assertReadEnabled();

return mIntval;

}

// Sets the value of the integer data member.

//

Acad::ErrorStatus

AsdkOwnerDemo::setIntData(const Adesk::Int16& val)

{

assertWriteEnabled();

mIntval = val;

return Acad::eOk;

}

// Returns a copy of the ownership ID data member.

//

AcDbHardOwnershipId

AsdkOwnerDemo::idData()

{

assertReadEnabled();

return mObjId;

}

// Sets the value of the ownership ID data member.

//

Acad::ErrorStatus

AsdkOwnerDemo::setIdData(const AcDbHardOwnershipId& ownedId)

{

if (ownedId.asOldId() == 0L) {

return Acad::eInvalidInput;

}

assertWriteEnabled();

mObjId = ownedId;

// Now set the backpointer. A transaction is used for

// opening the object, so if the object is already

// open it won’t prevent this setting from taking place.

//

AcDbObject *pObj;

AcTransaction *pTrans

= actrTransactionManager->startTransaction();

pTrans->getObject(pObj, ownedId, AcDb::kForWrite);

pObj->setOwnerId(objectId());

actrTransactionManager->endTransaction();

return Acad::eOk;

}

// Files data in from a DWG file.

//

Acad::ErrorStatus

AsdkOwnerDemo::dwgInFields(AcDbDwgFiler* filer)

{

assertWriteEnabled();

AcDbObject::dwgInFields(filer);

// For wblock filing we wrote out our owner as a hard

// pointer Id so now we need to read it in to keep things

// in sync.

//

if (filer->filerType() == AcDb::kWblockCloneFiler) {

AcDbHardPointerId id;

filer->readItem(&id);

}

filer->readItem(&mIntval);

filer->readItem(&mObjId);

return filer->filerStatus();

}

// Files data out to a DWG file.

//

Acad::ErrorStatus

AsdkOwnerDemo::dwgOutFields(AcDbDwgFiler* filer) const

{

assertReadEnabled();

AcDbObject::dwgOutFields(filer);



// Since objects of this class will be in the Named

// Objects Dictionary tree and may be hard referenced

// by some other object, to support wblock we need to

// file out our owner as a hard pointer Id so that it

// will be added to the list of objects to be wblocked

//

if (filer->filerType() == AcDb::kWblockCloneFiler)

filer->writeHardPointerId((AcDbHardPointerId)ownerId());

filer->writeItem(mIntval);

filer->writeItem(mObjId);

return filer->filerStatus();

}

// Files data in from a DXF file.

//

Acad::ErrorStatus

AsdkOwnerDemo::dxfInFields(AcDbDxfFiler* filer)

{

assertWriteEnabled();

Acad::ErrorStatus es;

if ((es = AcDbObject::dxfInFields(filer)) != Acad::eOk)

{

return es;

}

// Check if we’re at the right subclass data marker.

//

if (!filer->atSubclassData("AsdkOwnerDemo")) {

return Acad::eBadDxfSequence;

}

struct resbuf inbuf;

while (es == Acad::eOk) {

if ((es = filer->readItem(&inbuf)) == Acad::eOk) {

if (inbuf.restype == AcDb::kDxfInt16) {

mIntval = inbuf.resval.rint;

} else if (inbuf.restype == AcDb::kDxfHardOwnershipId)

{

acdbGetObjectId(mObjId,

inbuf.resval.rlname);

}

}

}

return filer->filerStatus();

}

// Files data out to a DXF file.

//

Acad::ErrorStatus

AsdkOwnerDemo::dxfOutFields(AcDbDxfFiler* filer) const

{

assertReadEnabled();

AcDbObject::dxfOutFields(filer);

filer->writeItem(AcDb::kDxfSubclass, "AsdkOwnerDemo");

filer->writeItem(AcDb::kDxfInt16, mIntval);

// Null object IDs are invalid: don’t write them out.

//

if (mObjId.asOldId() != 0L) {

filer->writeItem(AcDb::kDxfHardOwnershipId, mObjId);

}

return filer->filerStatus();

}

// Creates an AsdkOwnerDemo object (pObjC) and adds data to

// it. Then, AsdkOwnerDemo pObjC is created and set to be

// the owner of pObjC. Next, AsdkOwnerDemo pObjA is created

// and set to own pObjB. Finally, pObjA is added to a

// dictionary in the named object dictionary. Technically,

// we could just add pObjA to the named object dictionary



// itself, but that’ s not appropriate because it would clutter

// up the named object dictionary.

//

void

createObjs()

{

AcDbObjectId objIdA, objIdB, objIdC;

AcDbDictionary *pNamedobj;

AcDbDictionary *pDict = NULL;

AcDbDatabase *pCurDwg = acdbHostApplicationServices()->workingDatabase();

// Create object C with a dummy integer data value of 3.

//

AsdkOwnerDemo *pObjC = new AsdkOwnerDemo(3);

// Append object C to database without setting an owner.

//

pCurDwg->addAcDbObject(objIdC, pObjC);

pObjC->close();

// Create object B with a dummy integer data value of 2.

//

AsdkOwnerDemo *pObjB = new AsdkOwnerDemo(2);

// Append object B to the database without setting an owner.

//

pCurDwg->addAcDbObject(objIdB, pObjB);

// Now set up ownership for object C. The

// AsdkOwnerDemo::setIdData() function takes the

// objectId parameter and copies it into the

// AcDbHardOwnershipId data member. This places the

// object ID in a position to be filed out/in via the

// dwgInFields/dwgOutFields/dxfInFields/dxfOutFields

// member functions. This constitutes primary

// "ownership." The AsdkOwnerDemo::setIdData() function

// also calls each owned object’s setOwnerId() member

// function to set the backpointer and establish the

// full two-way ownership link.

//

pObjB->setIdData(objIdC);

pObjB->close();

// Create object A with a dummy integer data value of 1.

//

AsdkOwnerDemo *pObjA = new AsdkOwnerDemo(1);

// Next, add objA to a dictionary in the named object

// dictionary. This will establish ownership for objA,

// set the ownership backlink, and add it to the

// database.

//

pCurDwg->getNamedObjectsDictionary(pNamedobj, AcDb::kForWrite);

// Get a pointer to the ASDK_DICT dictionary. If it

// doesn’t exist, then create it and add it to the

// named object dictionary.

//

if (pNamedobj->getAt("ASDK_DICT", (AcDbObject*&) pDict,

AcDb::kForWrite) == Acad::eKeyNotFound)

{

pDict = new AcDbDictionary;



AcDbObjectId DictId;

pNamedobj->setAt("ASDK_DICT", pDict, DictId);

}

pNamedobj->close();

// Add object A to the ASDK_DICT dictionary.

//

pDict->setAt("OBJA", pObjA, objIdA);

pDict->close();

// Now set up ownership for object B.

//

pObjA->setIdData(objIdB);

pObjA->close();

}

// The list tree function runs through all objects in the

// ASDK_DICT dictionary, follows their ownership trees, and

// lists out information on all objects in the tree.

//

void

listTree()

{

AcDbDictionary *pNamedobj;

AcDbDictionary *pDict;

acdbHostApplicationServices()->workingDatabase()

->getNamedObjectsDictionary(pNamedobj, AcDb::kForWrite);

// Get a pointer to the ASDK_DICT dictionary.

//

pNamedobj->getAt("ASDK_DICT",(AcDbObject*&)pDict,

AcDb::kForRead);

pNamedobj->close();

// Run through the entries and list their backpointers.

//

AcDbDictionaryIterator *pDictItr = pDict->newIterator();

for (; !pDictItr->done(); pDictItr->next()) {

printOut(pDictItr->objectId());

}

pDict->close();

}

// Recursively walks down an ownership tree of AsdkOwnerDemo

// class objects, printing out information on each one.

//

void

printOut(AcDbObjectId id)

{

AsdkOwnerDemo *pDemo;

acdbOpenObject((AcDbObject*&)pDemo, id, AcDb::kForRead);

acutPrintf("\nIntdata: %d ObjId: %ld Backpointer:"

" %ld OwnedObj: %ld", pDemo->intData(),

(pDemo->objectId()).asOldId(),

(pDemo->ownerId()).asOldId(),

(pDemo->idData()).asOldId());

// Recursive tree walk

//

if ((pDemo->idData()).asOldId() != 0L) {

printOut(pDemo->idData());

}

pDemo->close();

}

// The initialization function is called from acrxEntryPoint()

// during kInitAppMsg case. This function is used to add commands

// to the command stack and to add classes to the ACRX class

// hierarchy.

//

void

initApp()

{

acedRegCmds->addCommand("ASDK_OWNERSHIP_COMMANDS",

"ASDK_CREATE", "CREATE",ACRX_CMD_MODAL, createObjs);



acedRegCmds->addCommand("ASDK_OWNERSHIP_COMMANDS",

"ASDK_LISTREE", "LISTREE",ACRX_CMD_MODAL, listTree);

AsdkOwnerDemo::rxInit();

acrxBuildClassHierarchy();

}

// The clean up function is called from acrxEntryPoint() during the

// kUnloadAppMsg case. This function removes this application’s

// command set from the command stack and the

// AsdkOwnerDemo class from the ARX runtime class tree.

//

void

unloadApp()

{

acedRegCmds->removeGroup("ASDK_OWNERSHIP_COMMANDS");

// Remove the AsdkOwnerDemo class from the ACRX runtime

// class hierarchy. If this is done while the database is

// still active, it should cause all objects of class

// AsdkOwnerDemo to be turned into proxies.

//

deleteAcRxClass(AsdkOwnerDemo::desc());

}

// ObjectARX entry point

//

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;

}


Содержание раздела