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

Пример расширения протокола


Этот пример расширения протокола разделен на три части:

§

Объявление и определение четырех классов расширения протокола: AsdkEntTemperature, AsdkDefaultTemperature, AsdkRegionTemperature и AsdkCircleTemperature.

§         выполнение energy() для команды ENERGY, которая позволяет пользователю выбирать примитив и затем, вычисляет температуру для того примитива.

§         ObjectARX модуль связывают с помощью интерфейса функции: initApp (), unloadApp () и acrxEntryPoint ().

// This is the AsdkEntTemperature protocol extension abstract base

// class. Notice that this is the lowest level that uses

// the ACRX macros.

//

class AsdkEntTemperature : public AcRxObject

{

public:

ACRX_DECLARE_MEMBERS(AsdkEntTemperature);



virtual double reflectedEnergy(AcDbEntity*) const = 0;

};

ACRX_NO_CONS_DEFINE_MEMBERS(AsdkEntTemperature, AcRxObject);

// This is the default implementation to be attached to AcDbEntity

// as a catch-all. This guarantees that this protocol extension will

// be found for any entity, so the search up the AcRxClass tree will

// not fail and abort AutoCAD.

//

class AsdkDefaultTemperature : public AsdkEntTemperature

{

public:

virtual double reflectedEnergy(AcDbEntity* pEnt) const;

};

double

AsdkDefaultTemperature::reflectedEnergy( AcDbEntity* pEnt) const

{

acutPrintf( "\nThis entity has no area, and no reflection.\n");

return -1.0;

}

// AsdkEntTemperature implementation for Regions

//

class AsdkRegionTemperature : public AsdkEntTemperature

{

public:

virtual double reflectedEnergy(AcDbEntity* pEnt) const;

};

double

AsdkRegionTemperature::reflectedEnergy( AcDbEntity* pEnt) const

{

AcDbRegion *pRegion = AcDbRegion::cast(pEnt);

if (pRegion == NULL)

acutPrintf("\nThe impossible has happened!");

// Compute the reflected energy as the region area multiplied

// by a dummy constant.

//

double retVal;


if (pRegion->getArea(retVal) != Acad::eOk)
return -1.0;
return retVal * 42.0;
}
// AsdkEntTemperature implementation for circles
//
class AsdkCircleTemperature : public AsdkEntTemperature
{
public:
virtual double reflectedEnergy(AcDbEntity* pEnt) const;
};
double
AsdkCircleTemperature::reflectedEnergy( AcDbEntity* pEnt) const
{
AcDbCircle *pCircle = AcDbCircle::cast(pEnt);
// Compute the reflected energy in a manner distinctly
// different than for AcDbRegion.
//
return pCircle->radius() * 6.21 * 42.0;
}
// This function has the user select an entity and then
// calls the reflectedEnergy() function in the protocol
// extension class attached to that entity’s class.
//
void
energy()
{
AcDbEntity *pEnt;
AcDbObjectId pEntId;
ads_name en;
ads_point pt;
if (acedEntSel("\nSelect an Entity: ", en, pt) != RTNORM)
{
acutPrintf("Nothing Selected\n");
return;
}
acdbGetObjectId(pEntId, en);
acdbOpenObject(pEnt, pEntId, AcDb::kForRead);
// call the protocol extension class’s method
//
double eTemp = ACRX_X_CALL(pEnt, AsdkEntTemperature)->reflectedEnergy(pEnt);
acutPrintf("\nEnergy == %f\n", eTemp);
pEnt->close();
}
// Pointers for protocol extension objects. These pointers
// are global so that they can be accessed during
// initialization and cleanup.
//
AsdkDefaultTemperature *pDefaultTemp;
AsdkRegionTemperature *pRegionTemp;
AsdkCircleTemperature *pCircleTemp;
// Initialization function called from acrxEntryPoint() during
// kInitAppMsg case. This function is used to add commands
// to the command stack and to add protocol extension
// objects to classes.
//
void
initApp()
{
acrxRegisterService("AsdkTemperature");
AsdkEntTemperature::rxInit();
acrxBuildClassHierarchy();
pDefaultTemp = new AsdkDefaultTemperature();
pRegionTemp = new AsdkRegionTemperature();
pCircleTemp = new AsdkCircleTemperature();
// Add the protocol extension objects to the appropriate


// AcRxClass objects.
//
AcDbEntity::desc()->addX(AsdkEntTemperature::desc(), pDefaultTemp);
AcDbRegion::desc()->addX(AsdkEntTemperature::desc(), pRegionTemp);
AcDbCircle::desc()->addX(AsdkEntTemperature::desc(), pCircleTemp);
acedRegCmds->addCommand("ASDK_TEMPERATURE_APP",
"ASDK_ENERGY", "ENERGY", ACRX_CMD_TRANSPARENT,
energy);
}
void
unloadApp()
{
delete acrxServiceDictionary->remove("AsdkTemperature");
acedRegCmds->removeGroup("ASDK_TEMPERATURE_APP");
// Remove protocol extension objects from the AcRxClass
// object tree. This must be done before removing the
// AsdkEntTemperature class from the ACRX runtime class
// hierarchy, so the AsdkEntTemperature::desc()
// still exists.
//
AcDbEntity::desc()->delX(AsdkEntTemperature::desc());
delete pDefaultTemp;
AcDbRegion::desc()->delX(AsdkEntTemperature::desc());
delete pRegionTemp;
AcDbCircle::desc()->delX(AsdkEntTemperature::desc());
delete pCircleTemp;
// Remove the AsdkEntTemperature class from the ARX
// runtime class hierarchy.
//
deleteAcRxClass(AsdkEntTemperature::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;
}

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