简介运行控件添加自定义实体类初始化自定义补充说明函数说明
简介

在本教程中,我们将使用自定义实体绘制一个五角星。

所需头文件及源文件已备好,如下所示:


    教程  MyCustomEntity.h

    教程  MyCustomEntity.cpp


该本教程中,使用控件\MxDraw52\Src\MxDraw5.2\samples\Edit项目进行添加自定义实体进行演示。这里我们使用自定义实体绘制一个五角星,所需虚函数已被重写,在头文件中有对各个虚函数的参数说明,在此将不再赘述,接下来将着重介绍如何加载自定义实体以及需要注意的地方。

本教程旨在介绍控件提供的API及推荐操作方式演示,读者应根据自己需要参考实例使用程序设计语言撰写解决方案。

运行控件

http://www.mxdraw.com/下载控件安装包,该包是自解压包,默认路径是当前文件夹,不会更改你任何的电脑设置。



123.png



运行CopyReleaseFile.bat、CopyReleaseFileX64.bat文件后会出现ReleaseFile、ReleaseFileX64文件夹,里面包含了所需要的动态库和资源文件。


打开VS2010选择新建一个MFC应用程序,在应用程序类型中选择基于对话框,其他的默认。



step1.png



配置开发环境输出目录到MxDraw52\Bin\vc100d。



step2.png



包含目录修改成MxDraw52\Src\MxDraw5.2\MxInc,库目录修改成MxDraw52\Src\MxDraw5.2\libvc100。



step3.png



首先在资源界面上加入一个Buttun(ID命名为IDC_DRAWFPS_BUTTON)按钮和一个Group Box(ID命名为IDC_RANGE_STATIC)按钮。



step4.png



给Group Box按钮右键添加一个变量:



step5.png



接下来为该项目创建一个C++类,这里创建的类名是CMcdbFivePointStar类:



step6.png

添加自定义实体类

在stdafx.h文件中添加代码:#include "mxdraw.h" 并在FivePointStar.cpp文件中进行控件的注册和释放:


CWinApp::InitInstance();
///////////////////////////
MxDraw::InitMxDraw();//注册控件


MxDraw::UnInitMxDraw();//释放控件
///////////////////////////
return FALSE;


在FivePointStarDlg.cpp的OnInitDialog()函数中添加控件额外的初始化代码如下:


CMcdbFivePointStar::rxInit();//注册自定义实体类信息到系统中
CRect rcPos;
GetDlgItem(IDC_RANGE_STATIC)->GetWindowRect(rcPos);
m_hDrawOcx = MxDraw::CreateMxDraw(this, rcPos, MxDraw::kShowCmdLineWindow);
ASSERT(m_hDrawOcx != NULL);

   

初始化自定义

写自定义实体类CMcdbFivePointStar继承自McDbEntity类


#define FPS_VERSION 1  //版本号
 
class CMcdbFivePointStar : public McDbEntity
{
public:
ACRX_DECLARE_MEMBERS(CMcdbFivePointStar);
CMcdbFivePointStar(int iLenth = 50, McGePoint3d vPos = McGePoint3d (0, 0, 0));
~CMcdbFivePointStar(void);
 
//重载该虚函数,绘制自定义实体的显示效果a
Adesk::Boolean worldDraw(
AcGiWorldDraw * wd//显示绘制的上下文对象
);
 
//重载该虚函数,返回自定义的编辑夹点
virtual Acad::ErrorStatus   getGripPoints(
AcGePoint3dArray&  gripPoints,//返回夹点
AcGeIntArray&  osnapModes,// 暂没有使用
AcGeIntArray&  geomIds//暂没有使用
) const;
 
//重载该虚函数,处理夹点编辑结果。
virtual Acad::ErrorStatus moveGripPointsAt(
const AcGeIntArray& indices,//indices [0]参数是传入被编辑的夹点索引, 其  它数组元素暂没有使用。
const AcGeVector3d& offset//夹点编辑的偏移量
);
 
//重载该虚函数,返回自定义实体的外包矩形框
virtual Acad::ErrorStatus   getGeomExtents(
AcDbExtents& extents//返回自定义实体外包矩形框。
) const;
 
//重载该虚函数,返回自定义实体的捕捉点
virtual Acad::ErrorStatus   getOsnapPoints(
AcDb::OsnapMode     osnapMode,//捕捉点类型,通过该变量可以确  定需要返回什  么类型的捕捉点
int                 gsSelectionMark,//暂没有使用
const AcGePoint3d&  pickPoint,//当前输入点
const AcGePoint3d&  lastPoint,//上一次的输入点
const AcGeMatrix3d& viewXform,// 暂没有使用
AcGePoint3dArray&   snapPoints,//返回捕捉点
AcDbIntArray&       geomIds//暂没有使用
) const;
 
//重载该虚函数,返回自定义实体打碎后的实体,在控件中,
//自定义实体保存在到dwg图中时,使用是块引用来保存,
//控件使用该函数得到自定义实体在块引用中的实体数据。
virtual Acad::ErrorStatus   explode(
AcDbVoidPtrArray& entitySet//返回打碎后的基本实体。实体指针 内存控件释放。
) const;
 
//重载该虚函数,响应控件系统,读取自定义实体数据,
//在从文件读取实体,复制实体等地方都会调用该函数。
virtual Acad::ErrorStatus dwgInFields(
AcDbDwgFiler* pFiler//数据归档对象,在这个函数,使用该对象读   取数据。
);
 
//重载该虚函数,响应控件系统,写入自定义实体数据,
//在把实体写入文件时,复制实体等地方都会调用该函数。
virtual Acad::ErrorStatus dwgOutFields(
AcDbDwgFiler* pFiler//数据归档对象,在这个函数,使用该对象写   入数据。
) const;
 
void SetCenter(McGePoint3d vCenter);
const McGePoint3d & GetCenter();
void SetLenth(int dLength);
const int & GetLenth();
private:
std::vector<McGePoint3d> GetFPS() const;
int m_iLength;//五角星半径
McGePoint3d m_vPos; //五角星中心
/* int m_Rdius;*/
};


双击“画五角星产生事件”,添加代码如下:


CMcdbFivePointStar * pFPS = new CMcdbFivePointStar(100, McGePoint3d(100, 100, 0));
MrxDbgUtils::addToCurrentSpaceAndClose(pFPS);

   

补充说明

1. 在自定义实体类函数中添加了读函数(assertReadEnabled)和写函数(assertWriteEnabled),函数说明:

   断言对象当前状态一定被读方式打开,该函数多用于自定义实体的属性操作函数中。


void assertReadEnabled() const;


断言对象当前状态一定被写方式打开,该函数多用于自定义实体的属性操作函数中。


void assertWriteEnabled(Mdesk::Boolean autoUndo = true,
		Mdesk::Boolean recordModified = true,
		Mdesk::Boolean setSaveModifyed = true
		);


    上述的函数主要为“退回”操作及“保存”的操作;如不加则会在上述操作中出现异常。


2. 在打碎虚函数(explode)中,我们进行了具体的添加实体的操作,在此处我们可以根据需要设置一些属性。


3. 在绘制函数中,我们调用打碎虚函数(explode),并对 绘图时使用的环境参数AcGiWorldDraw进行了如下设置: wd-    >subEntityTraits().setLineWeight(pEnt->lineWeight())... 即为我们在explode中对实体设置的属性,在控件中显示出来。


4. 在自定义实体类的头文件中,我们在类名下定义了如下声明:


//使用MCRX_DECLARE_MEMBERS宏定义类的类型信息函数,宏的第一个参数是类的类名
	ACRX_DECLARE_MEMBERS(MyCustomEntity);
	在源文件中进一步说明:
	ACRX_DXF_DEFINE_MEMBERS(
	MyCustomEntity, //自定义实体的类名
	McDbEntity,//自定义实体的基类
	AcDb::kDHL_CURRENT,//当前文件版本
	AcDb::kMReleaseCurrent,//当前控件版本
	AcDbProxyEntity::kAllAllowedBits,//代理实体处理标志
	MyCustomEntity,//Dfx0组码对应值
	MxDrawObj Test Custom Entity//类说明
	);


此信息在实体信息中能够看到。


5. 在dwgInFields和dwgOutFields,我们进行了写档与归档的操作,使用了我们定义的宏:


#define MYCUSTOMENTITY_VERSION 1		//版本号


在自定义实体增加新的内容,如:新增一条线,我们则需要判断版本,根据获取到的版本号对是否使用线进行判断。


    在读与写的操作中,我们使用了参数AcDbDwgFiler 进行具体的读写,此类可读写绝大多数用到的数据,但是读写必须保持同步,及此实例中在dwgOutFields先pFiler->writeInt(MYCUSTOMENTITY_VERSION),dwgOutFields需要先pFiler->readInt(&lVar),才能获取正确的数据。


6. 使用控件的移动函数move,或者点击自定义实体的夹点进行拖动,需要实现dwgInFields、dwgOutFields和moveGripPointsAt。


控件其他例程说明:

在控件安装目录下的samples\CustomEntity\ CustomEntity.sln例程,演示了自定义实体现。在例程实现连接块CLinkBlock自定义实体,CLinkLine自定义实体。


    CLinkBlock类显示通过块引用显示,绘图捕捉点通过块记录中的块属性定义文本来确定,当该实体被编辑后,会自动移动与该实体连接的连接线,实现连动效果。

    CLinkLine 类实现一个线段实体功能,并带有长度标注功能。

函数说明

ACRX_DECLARE_MEMBERS 宏


作用:使用MCRX_DECLARE_MEMBERS宏定义类的类型信息函数,宏的第一个参数是类的类名。


参数


名称说明
第一个参数

宏的第一个参数是类的类名


参考例程


ACRX_DECLARE_MEMBERS(MyCustomEntity);


ACRX_DXF_DEFINE_MEMBERS宏


作用:定义类的类型信息。


定义


#define ACRX_DXF_DEFINE_MEMBERS        MCRX_DXF_DEFINE_MEMBERS_EX

#define MCRX_DXF_DEFINE_MEMBERS_EX(CLASS_NAME,PARENT_CLASS,DWG_VERSION, \

MAINTENANCE_VERSION,PROXY_FLAGS,DXF_NAME,APP) \

MCRX_DEFINE_MEMBERS(CLASS_NAME); \


参数


名称说明

CLASS_NAME

自定义实体的类名

PARENT_CLASS

自定义实体的基类
DWG_VERSION

当前文件版本

MAINTENANCE_VERSION
当前控件版本
PROXY_FLAGS
代理实体处理标志
DXF_NAME
Dfx0组码对应值
APP
类说明


参考例程:


ACRX_DXF_DEFINE_MEMBERS(
MyCustomEntity, //自定义实体的类名
McDbEntity,//自定义实体的基类
AcDb::kDHL_CURRENT,//当前文件版本
AcDb::kMReleaseCurrent,//当前控件版本
AcDbProxyEntity::kAllAllowedBits,//代理实体处理标志
MyCustomEntity,//Dfx0组码对应值
MxDrawObj Test Custom Entity//类说明
);



worldDraw function


作用绘制自定义实体的显示效果


接口Adesk::Boolean worldDraw(AcGiWorldDraw * wd);


参数


名称说明
wd

显示绘制的上下文对象


参考例程


Adesk::Boolean MyCustomEntity::worldDraw(AcGiWorldDraw * wd)
{
assertReadEnabled();
AcDbVoidPtrArray entitySet;
explode(entitySet);
for (int i = 0; i < entitySet.length(); i++)
{
McDbEntity* pEnt = (McDbEntity*)entitySet[i];
wd->subEntityTraits().setLineWeight(pEnt->lineWeight());
wd->subEntityTraits().setColor(pEnt->colorIndex());
wd->subEntityTraits().setAlwaysShowLineWidth(TRUE);
pEnt->worldDraw(wd);
delete pEnt;
}
 
return Mdesk::kTrue;
}



getGripPoints function


作用:返回自定义的编辑夹点。


接口virtual Acad::ErrorStatus getGripPoints(

          AcGePoint3dArray & gripPoints, AcGeIntArray & osnapModes, AcGeIntArray geomIds

      ) const;


参数


名称说明
gripPoints

返回夹点

osnapModes

暂没有使用

geomIds

暂没有使用


参考例程


Acad::ErrorStatus MyCustomEntity::getGripPoints(AcGePoint3dArray & gripPoints, 
AcGeIntArray & osnapModes, AcGeIntArray & geomIds) const
{
assertReadEnabled();
gripPoints.append(m_vCenterPt);
return Acad::eOk;
}


moveGripPointsAt function


作用:处理夹点编辑结果。


接口virtual Acad::ErrorStatus moveGripPointsAt(

          const AcGeIntArray & indices, const AcGeVector3d & offset

      );


参数


名称说明
indices

indices [0]参数是传入被编辑的夹点索引, 其它数组元素暂没有使用

Offset

夹点编辑的偏移量


参考例程


Acad::ErrorStatus MyCustomEntity::moveGripPointsAt(const AcGeIntArray & indices, const 
AcGeVector3d & offset)
{
assertWriteEnabled();
int iIndex = indices[0];
switch (iIndex)
{
case 0:
m_vCenterPt += offset;
break;
}
return Mcad::eOk;
}


getGeomExtents function


作用:返回自定义实体的外包矩形框。


接口virtual Acad::ErrorStatus getGeomExtents(

          AcDbExtents & extents

      ) const;

参数


名称说明
extents

返回自定义实体外包矩形框


参考例程


Acad::ErrorStatus MyCustomEntity::getGeomExtents(AcDbExtents & extents) const
{
assertReadEnabled();
 
auto vPos = GetFPS();
McGePoint3d vLeftBottom;
McGePoint3d vRightTob;
vLeftBottom = vPos[0];
vRightTob = vPos[0];
 
for (size_t i(1); i < vPos.size(); i++)
{
if (vLeftBottom.x > vPos[i].x)
vLeftBottom.x = vPos[i].x;
if (vLeftBottom.y > vPos[i].y)
vLeftBottom.y = vPos[i].y;
if (vRightTob.x < vPos[i].x)
vRightTob.x = vPos[i].x;
if (vRightTob.y < vPos[i].y)
vRightTob.y = vPos[i].y;
}
 
extents.set(vLeftBottom, vRightTob);
 
return Acad::eOk;
}


getOsnapPoints function


作用:返回自定义实体的捕捉点。


接口virtual Acad::ErrorStatus getOsnapPoints(

          AcDb::OsnapMode osnapMode,

          int gsSelectionMark,

          const AcGePoint3d & pickPoint, 

          const AcGePoint3d & lastPoint, 

          const AcGeMatrix3d & viewXform, 

          AcGePoint3dArray & snapPoints, 

          AcDbIntArray & geomIds 

      ) const;


参数


名称说明
osnapMode

捕捉点类型,通过该变量可以确定需要返回什么类型的捕捉点

GsSelectionMark

暂没有使用

pickPoint

当前输入点

LastPoint

上一次的输入点

ViewXform

暂没有使用

SnapPoints

返回捕捉点

GeomIds

暂没有使用


参考例程


Acad::ErrorStatus MyCustomEntity::getOsnapPoints(AcDb::OsnapMode osnapMode, int
 gsSelectionMark, const AcGePoint3d & pickPoint, const AcGePoint3d & lastPoint, const
  AcGeMatrix3d & viewXform, AcGePoint3dArray & snapPoints, AcDbIntArray & geomIds) const
{
assertReadEnabled();
if (osnapMode == McDb::kOsModeEnd)
{
// 返回端点。
auto vPos = GetFPS();
for each (auto it in vPos)
snapPoints.append(it);
}
else if (osnapMode == McDb::kOsModeMid)
{
// 返回的是中点。
snapPoints.append(m_vCenterPt);
}
return Mcad::eOk;
}


Explode function


作用:重载该虚函数,返回自定义实体打碎后的实体,在控件中,自定义实体保存在到dwg图中时,使用是块引用来保存,控件使用该函数得到自定义实体在块引用中的实体数据。


接口virtual Acad::ErrorStatus explode(

          AcDbVoidPtrArray & entitySet

      ) const;


参数


名称说明
entitySet

返回打碎后的基本实体。实体指针内存控件释放


参考例程


Acad::ErrorStatus MyCustomEntity::explode(AcDbVoidPtrArray & entitySet) const
{
assertReadEnabled();
 
auto vPos = GetFPS();
for (size_t i(0); i < vPos.size(); i++)
{
McDbLine* pLine = new McDbLine(vPos[i], vPos[(i + 2) % 5]);
pLine->setLineWeight(McDb::kLnWt025); //设置一些属性
McCmColor mColor;
mColor.setColor(RGB(0, 255, 0));
pLine->setColor(mColor);
pLine->setAlwaysShowLineWeight(TRUE);
entitySet.append(pLine);
}
 
return Acad::eOk;
}


dwgInFields function


作用:重载该虚函数,响应控件系统,读取自定义实体数据,在从文件读取实体,复制实体等地方都会调用该函数。


接口virtual Acad::ErrorStatus dwgInFields(

          AcDbDwgFiler * pFiler

      );

参数


名称说明
pFiler  

数据归档对象,在这个函数,使用该对象写入数据


参考例程


Acad::ErrorStatus MyCustomEntity::dwgInFields(AcDbDwgFiler * pFiler)
{
assertWriteEnabled();
 
int lVar = 1;
 
pFiler->readInt(&lVar);
pFiler->readDouble(&m_iLength);
pFiler->readPoint3d(&m_vCenterPt);
 
return Mcad::eOk;
}


dwgOutFields function


作用:重载该虚函数,响应控件系统,读取自定义实体数据,在从文件读取实体,复制实体等地方都会调用该函数。


接口virtual Acad::ErrorStatus dwgOutFields(

          AcDbDwgFiler * pFiler

      ) const;


参数


名称说明
pFiler

数据归档对象,在这个函数,使用该对象读取数据


参考例程


Acad::ErrorStatus MyCustomEntity::dwgOutFields(AcDbDwgFiler * pFiler) const
{
assertReadEnabled();
 
pFiler->writeInt(MYCUSTOMENTITY_VERSION);
pFiler->writeDouble(m_iLength);
pFiler->writePoint3d(m_vCenterPt);
 
return Mcad::eOk;
}


梦想CAD是专业的CAD插件(控件),可轻松在网页、手机及BS/CS程序中浏览编辑DWG文件,不需安装AutoCAD即可运行。经十余年累积已非常稳定可靠,有关键的空间搜索算法,并使用汇编优化,可同时处理50万级实体,有非常高的图形显示和处理效率。
技术服务
TEL:400-888-5703
185-8173-1060
客服I QQ: 3570505660
技术I QQ: 827867134
技术II QQ:6884123
产品购买
TEL:156-8136-8971
QQ:710714273
用户交流
控件QQ交流群1:73281982
控件QQ交流群2:112199959
MxCAD软件群 1:515771658
技术I:QQ
827867134
客服I:QQ
3570505660
销售QQ
710714273
联系电话400-888-5703