参考http://blog.csdn.net/zhujiang1001/article/details/1819938 本文在其基础上稍加改进,以使其适合VS2008+ObjectARX2012的组合。
1. 用ObjectARX向导建立一个arx程序。
2. 在StdAfx.h中添加宏定义:
#define ZXL_CUSTOMENT
#undef ZXL_API
#define ZXL_API __declspec(dllexport)
3. 添加头文件EntTest.h
#pragma once
class ZXL_API CEntTest : public AcDbEntity
{
public:
ACRX_DECLARE_MEMBERS(CEntTest);
protected:
static Adesk::UInt32 kCurrentVersionNumber;
public:
CEntTest();
CEntTest(AcGePoint3d startPoint, AcGePoint3d endPoint);
virtual ~CEntTest();
// 自定义实体必须重载的函数
virtual Adesk::Boolean subWorldDraw(AcGiWorldDraw * pWd);
virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);
virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
virtual Acad::ErrorStatus subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray & osnapModes, AcDbIntArray & geomIds) const;
virtual Acad::ErrorStatus subMoveGripPointsAt(const AcDbIntArray & indices, const AcGeVector3d& offset);
// 将实体加入模型空间块表记录
static AcDbObjectId AddEntityToDbs(AcDbEntity*pEnt);
private:
AcGePoint3d m_StartPoint;
AcGePoint3d m_EndPoint;
};
#ifdef ZXL_CUSTOMENT
ACDB_REGISTER_OBJECT_ENTRY_AUTO(CEntTest)
#endif
4. 添加源文件EntTest.cpp
#include "StdAfx.h"
#include "EntTest.h"
ACRX_DXF_DEFINE_MEMBERS(CEntTest, AcDbEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
0, ZXL_CUSTOM_ENT, "CustomEnt");
MAKE_ACDBOPENOBJECT_FUNCTION(CEntTest);
Adesk::UInt32 CEntTest::kCurrentVersionNumber = 1;
CEntTest::CEntTest()
{
}
CEntTest::CEntTest(AcGePoint3d startPoint, AcGePoint3d endPoint)
: m_StartPoint(startPoint), m_EndPoint(endPoint)
{
}
CEntTest::~CEntTest()
{
}
Acad::ErrorStatus CEntTest::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
AcDbObject::dwgInFields(pFiler);
if (pFiler->filerType() == AcDb::kWblockCloneFiler)
{
AcDbHardPointerId Id;
pFiler->readItem(&Id);
}
pFiler->readPoint3d(&m_StartPoint);
pFiler->readItem(&m_EndPoint);
return pFiler->filerStatus();
}
Acad::ErrorStatus CEntTest::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
AcDbObject::dwgOutFields(pFiler);
if (pFiler->filerType() == AcDb::kWblockCloneFiler)
{
pFiler->writeHardPointerId((AcDbHardPointerId)ownerId());
}
pFiler->writePoint3d(m_StartPoint);
pFiler->writeItem(m_EndPoint);
return pFiler->filerStatus();
}
Adesk::Boolean CEntTest::subWorldDraw(AcGiWorldDraw * pWd)
{
pWd->subEntityTraits().setColor(1);
AcGePoint3d verts[2];
verts[0] = m_StartPoint;
verts[1] = m_EndPoint;
/* AcGiWorldDraw::geometry ---- 返回一个对AcGiWorldGeometry对象的引用,
该对象允许使用者生成几何图形(多段线、圆弧、网格等)。*/
pWd->geometry().polyline(2, verts);
return AcDbEntity::subWorldDraw(pWd);
}
Acad::ErrorStatus CEntTest::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray & osnapModes, AcDbIntArray & geomIds) const
{
assertReadEnabled();
gripPoints.append(m_StartPoint);
gripPoints.append(m_EndPoint);
AcGePoint3d midpoint;
midpoint.x = (m_StartPoint.x + m_EndPoint.x) / 2;
midpoint.y = (m_StartPoint.y + m_EndPoint.y) / 2;
gripPoints.append(midpoint);
return Acad::eOk;
}
Acad::ErrorStatus CEntTest::subMoveGripPointsAt(const AcDbIntArray & indices, const AcGeVector3d& offset)
{
assertReadEnabled();
if (indices.length() == 0)
{
return Acad::eOk;
}
int num = indices.length();
for (int i = 0; i < num; ++i)
{
int k = indices[i];
if (k == 0)
{
m_StartPoint += offset;
}
else if (k == 1)
{
m_EndPoint += offset;
}
else
{
m_StartPoint += offset;
m_EndPoint += offset;
}
}
return Acad::eOk;
}
void CEntTest::Init()
{
// 第一个 ads_point 参数如果给一个已知点坐标,那么会以这个点做基点拉出一个橡皮筋。
// 如果第一个参数 给 NULL,那么不拉橡皮筋。
ads_point startPt;
if (acedGetPoint(NULL, _T("\n请输入起点:\n"), startPt) != RTNORM)
{
acutPrintf(_T("输入起点错误!\n"));
return;
}
m_StartPoint = asPnt3d(startPt);
ads_point endPt;
if (acedGetPoint(startPt, _T("请输入终点:\n"), endPt) != RTNORM)
{
acutPrintf(_T("输入终点错误!\n"));
return;
}
m_EndPoint = asPnt3d(endPt);
}
AcDbObjectId CEntTest::AddEntityToDbs(AcDbEntity* pEnt)//将生成的自定义实体对象加入CAD数据库
{
if (pEnt == NULL)
{
delete pEnt;
acutPrintf(_T("acdbentity == NULL\n"));
return AcDbObjectId::kNull;
}
AcDbBlockTable *pBlockTable;
acdbCurDwg()->getBlockTable(pBlockTable,AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
AcDbObjectId entityId;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);
pBlockTable->close();
pBlockTableRecord->appendAcDbEntity(entityId,pEnt);
pBlockTableRecord->close();
pEnt->close();
return entityId;
}
5. 用工具栏命令添加一个命令,命令函数中添加如下内容:
CEntTest* pEntTest = new CEntTest();
pEntTest->Init();
pEntTest->AddEntityToDbs(pEntTest);
//CEntTest* pEnt = new CEntTest(AcGePoint3d(0.0,0.0,0.0), AcGePoint3d(100.0,100.0,0.0));
//pEnt->AddEntityToDbs(pEnt);