本例是《AutoCAD ObjectARX2000开发技术指南》中的例子,稍作修改。
向导建立工程。
AsdkEntTemperature.h头文件:
#pragma once
#include "rxobject.h"
/*
这个扩展协议例子包含两个部分:
1. 声明和定义四个扩展协议类:AsdkEntTemperature、AsdkDefaultTemperature、
AsdkRegionTemperature、AsdkCircleTemperature。
2. 为energy命令实现energy()函数,它让用户选择一个实体,然后计算该实体的温度。
*/
// 这是AsdkEntTemperature协议扩展基类
class AsdkEntTemperature :
public AcRxObject
{
public:
ACRX_DECLARE_MEMBERS(AsdkEntTemperature);
AsdkEntTemperature(void);
~AsdkEntTemperature(void);
virtual double reflectedEnergy(AcDbEntity* ) const = 0;
};
ACDB_REGISTER_OBJECT_ENTRY_AUTO(AsdkEntTemperature);
/*
这是将一个容器附加到AcDbEntity类的缺省实现过程,它保证了这个协议扩展能被所有实体找到。
只有这样,向上搜索AcRxClass层次结构树就不会失败并异常退出AutoCAD
*/
class AsdkDefaultTemperature :
public AsdkEntTemperature
{
public:
AsdkDefaultTemperature(void);
~AsdkDefaultTemperature(void);
virtual double reflectedEnergy(AcDbEntity* pEnt) const;
};
// 为Regions实现AsdkEntTemperature
class AsdkRegionTemperature :
public AsdkEntTemperature
{
public:
AsdkRegionTemperature(void);
~AsdkRegionTemperature(void);
virtual double reflectedEnergy(AcDbEntity* pEnt) const;
};
// 为circle实现AsdkEntTemperature
class AsdkCircleTemperature :
public AsdkEntTemperature
{
public:
AsdkCircleTemperature(void);
~AsdkCircleTemperature(void);
virtual double reflectedEnergy(AcDbEntity* pEnt) const;
};
//------------
void energy();
AsdkEntTemperature.cpp文件:
#include "StdAfx.h"
#include "AsdkEntTemperature.h"
//----------------------------------------------------------------
ACRX_NO_CONS_DEFINE_MEMBERS(AsdkEntTemperature, AcRxObject);
AsdkEntTemperature::AsdkEntTemperature(void)
{
}
AsdkEntTemperature::~AsdkEntTemperature(void)
{
}
//------------------------------------------------------------
AsdkDefaultTemperature::AsdkDefaultTemperature(void)
{
}
AsdkDefaultTemperature::~AsdkDefaultTemperature(void)
{
}
double AsdkDefaultTemperature::reflectedEnergy(AcDbEntity* pEnt) const
{
acutPrintf(L"\n该实体没有面积,所以没有能量反射。\n");
return -1.0;
}
//------------------------------------------------------------
AsdkRegionTemperature::AsdkRegionTemperature(void)
{
}
AsdkRegionTemperature::~AsdkRegionTemperature(void)
{
}
double AsdkRegionTemperature::reflectedEnergy(AcDbEntity* pEnt) const
{
AcDbRegion* pRegion = AcDbRegion::cast(pEnt);
if (pRegion == NULL)
{
acutPrintf(L"\n不可能发生这种情况。\n");
}
// 用区域面积乘以一个常量计算反射面积
double retVal;
if (pRegion->getArea(retVal) != Acad::eOk)
{
return -1.0;
}
return retVal * 42.0;
}
//------------------------------------------------------------
AsdkCircleTemperature::AsdkCircleTemperature(void)
{
}
AsdkCircleTemperature::~AsdkCircleTemperature(void)
{
}
double AsdkCircleTemperature::reflectedEnergy(AcDbEntity* pEnt) const
{
AcDbCircle* pCircle = AcDbCircle::cast(pEnt);
if (pCircle == NULL)
{
acutPrintf(L"\n不可能发生这种情况。\n");
}
// 用不同于AcDbRegion的方法计算发射能量
return pCircle->radius() * 6.21 * 42.0;
}
//-------------
void energy()
{
AcDbEntity* pEnt;
AcDbObjectId pEntId;
ads_name en;
ads_point pt;
if (acedEntSel(L"\n请选择一个实体:", en, pt) != RTNORM)
{
acutPrintf(L"没有选择!\n");
return;
}
acdbGetObjectId(pEntId, en);
acdbOpenObject(pEnt, pEntId, AcDb::kForRead);
// 调用协议扩展类的函数
double eTemp = ACRX_PE_PTR(pEnt, AsdkEntTemperature)->reflectedEnergy(pEnt);
acutPrintf(L"\nEnergy=%f\n", eTemp);
return;
}
acrxEntryPoint.cpp文件中:
添加全局指针:
// 指向扩展协议对象的指针。将这些指针设为全局变量,
// 就可以在初始化和清除它们时访问它们。
AsdkDefaultTemperature* pDefaultTemp;
AsdkRegionTemperature* pRegionTemp;
AsdkCircleTemperature* pCircleTemp;
在应用程序类的On_kInitAppMsg函数中添加:
acrxRegisterService(L"AsdkTemperatrue");
pDefaultTemp = new AsdkDefaultTemperature;
pRegionTemp = new AsdkRegionTemperature;
pCircleTemp = new AsdkCircleTemperature;
// 将协议扩展添加到合适的AcRxClass对象中
AcDbEntity::desc()->addX(AsdkEntTemperature::desc(), pDefaultTemp);
AcDbRegion::desc()->addX(AsdkEntTemperature::desc(), pRegionTemp);
AcDbCircle::desc()->addX(AsdkEntTemperature::desc(), pCircleTemp);
在应用程序类的On_kUnloadAppMsg函数中添加:
delete acrxServiceDictionary->remove(L"AsdkTemperatrue");
// 从AcRxClass对象树中删除协议扩展对象。
AcDbEntity::desc()->delX(AsdkEntTemperature::desc());
delete pDefaultTemp;
AcDbRegion::desc()->delX(AsdkEntTemperature::desc());
delete pRegionTemp;
AcDbCircle::desc()->delX(AsdkEntTemperature::desc());
delete pCircleTemp;
用ARX工具栏新建命令,并在命令函数中添加代码:
energy();
完成。