LOGO
帮助文档
旧版文档
简介运行控件添加自定义实体类添加动态拖动类初始化自定义注册到系统增加测试按钮补充说明函数说明
简介

在完成使用“自定义实体”绘制五角星教程后,我们在此实例中将学习如何使用动态选择的方式选择五角星的中心点及长度。

在本教程的准备文件中已备好所需的动态拖动类,如下所示:


    教程  DynamicEntity\MyDynamic.h

    教程  DynamicEntity\MyDynamic.cpp及 自定义实体 中的MyCustomEntity类


在本教程中,我们使用CAD控件\MxDraw52\Src\MxDraw5.2\samples\Edit项目进行添加自定义实体演示;使用了继承AcEdJig和集成McEdGetPointWorldDraw两种方式实现动态绘制;在多数和场景下皆可互相替换,值得注意的是McEdGetPointWorldDraw在封装上更为简洁。

本教程中,对所需的虚函数进行了重写及说明,读者可根据需要跳入被继承的父类了解各个函数的作用。

运行控件

运行VS,打开“Edit”项目。

添加自定义实体类

添加自定义实体 MyCustomentity 类(在 自定义实体 教程中的文件)。

添加动态拖动类

添加动态拖动类 MyDynamic类(本教程使用已准备好的文件),为自定义实体添加命令,并注册进CAD控件命令系统。


使用 WorldDraw 方式

.h

static void DynamicByWd();

.cpp

CDynByWorldDraw cWdDynDraw;
cWdDynDraw.DoIt();

使用 Jig 方式

.h

static void DynamicByJig();

.cpp

CDynByJig cJigDynDraw;
cJigDynDraw.DoIt();
MrxDbgUtils::addToCurrentSpaceAndClose(cJigDynDraw.GetEntity());

初始化自定义

在MFC控件的InitInstance函数中添加如下代码:


MyCustomEntity::rxInit();
注册到系统

1. 使用 WorldDraw 方式


acedRegCmds->addCommand(_T("SysCmd"), _T("DoMyDynamicByWd"), _T("DoMyDynamicByWd"), 1, DynamicByWd);


2. 使用 Jig 方式


acedRegCmds->addCommand(_T("SysCmd"), _T("DoMyDynamicByJig"), _T("DoMyDynamicByJig"), 1, DynamicByJig);
增加测试按钮

1. 使用 WorldDraw 方式


acDocManager->sendStringToExecute(MxDraw::GetDatabase(m_hDrawOcx)->GetDocument(), _T("DoMyDynamicByWd"));


2. 使用 Jig 方式


acDocManager->sendStringToExecute(MxDraw::GetDatabase(m_hDrawOcx)->GetDocument(), _T("DoMyDynamicByJig"));


补充说明

1. 在通过继承AcEdJig和McEdGetPointWorldDraw两种的方式中,我们使用了添加 DoIt 函数进行具体的动态选取操作。

通过继承AcEdJig类的CDynByJig类,在DoIt结束后,通过GetEntity返回实体而添加进当前模型空间():


MrxDbgUtils::addToCurrentSpaceAndClose(cJigDynDraw.GetEntity());


通过McEdGetPointWorldDraw类的CDynByWorldDraw类,则在DoIt函数中直接加入了当前模型空间。这二者并无区别。


2. 在CDynByJig的DoIt中,我们通过设置关键字( setKeywordList(_T("A B C D")) )来让用户选择,在sampler中让用户继续自己选择的操作,而在选择的过程中,用户则可以输入关键字取消当前的交互选择,通过返回的值,得到用户选择的结果、关键值、或其他状态。


3. 动态交互的核心即为每次发生一些事件(鼠标移动、键盘输入...),调用回调函数(如继承AcEdJig的CDynByJig的sampler函数,继承McEdGetPointWorldDraw类的CDynByWorldDraw类的worldDraw函数),在回调函数中,绘制自定义实体或基本实体(线、圆、弧线、PolyLine...),而不添加至当前模型空间,而在确认后,将要添加的实体用在交互时所得到的信息进行实例化后再添加进当前模型空间。

下面将阐述动态绘制的基本思想:


    动态绘制多数情况下为绘制一个自定义实体,如本次绘制的五角星,则需要先将五角星的自定义实体实现,我们使用的是在 自定义实体 教程中已完成的MyCustomEntity类,而五角星实体需要 “中心点” 和 “长度”,我们在动态绘制时,需要与用户交互来得到这两个信息。


在此实例中,我们首先通过使用实体类默认的值:


MyCustomEntity::MyCustomEntity()//自定义实体的默认值{m_vCenterPt = McGePoint3d(200, 200, -100);m_iLength = 50;}


且首先选择“中心点”来直接绘制自定义实体,在代码中的体现为:


CDynByJig::CDynByJig() :m_bIsDraw(TRUE), m_eNextInput(CENTER){}


在DoIt函数中,调用 drag 后,鼠标的每一次移动都会调用sampler,之后则会在选择“中心点”下的case项中,acquirePoint获得当前的位置并设置到五角星实体的属性中去,在得到实体所需的信息后,可以实例化一个实体添加进当前模型空间,也可以像实例一样,通过返回类中的实体变量添加进当前的模型空间,如:

MrxDbgUtils::addToCurrentSpaceAndClose(cJigDynDraw.GetEntity());
函数说明

McEdJig类


Sampler function


作用:继承类重载该函数,通知数据采样操作。


接口virtual DragStatus sampler()= NULL;


参考例程


AcEdJig::DragStatus CDynByJig::sampler()
{
AcEdJig::DragStatus ret(kNoChange);
 
switch (m_eNextInput)
{
case CDynByJig::CHOOSELENGTH:
{
AcGePoint3d vPt;
ret = acquirePoint(vPt);
if (AcEdJig::kNormal == ret)
m_ent.SetLenth(vPt.distanceTo(m_ent.GetCenter()));
}
break;
case CDynByJig::INPUTLENGTH:
{
int dLength(0);
ret = acquireInt(dLength);
if (AcEdJig::kNormal == ret)
m_ent.SetLenth(dLength);
}
break;
case CDynByJig::CENTER:
{
AcGePoint3d vPt;
ret = acquirePoint(vPt);
if (AcEdJig::kNormal == ret)
m_ent.SetCenter(vPt);
}
}
 
return ret;
}


Update function


作用:继承类重载该函数,通知更新显示操作。


接口virtual Mdesk::Boolean update()= NULL;


参考例程


Adesk::Boolean CDrawSplineJig::update()
{
return Adesk::kTrue;
}


entity function


作用:继承类重载该函数,返回拖放时用于显示的实体。


接口virtual McDbEntity * entity() const = NULL;


参考例程


AcDbEntity * CDynByJig::entity() const
{
const AcDbEntity* pRet = &m_ent;
return const_cast<AcDbEntity*>(pRet);
}


setKeywordList function


作用:设置关键字字符串。


接口void setKeywordList(const TCHAR * pszKeyword);


参考例程:


bool    
CRectSelJig::DoIt(AcGePoint3d& pt1,AcGePoint3d& pt2)
{
acutPrintf(_T("\n 请选择矩形第一点:"));
m_ent.SetStatus(true);
setKeywordList(_T("A B C Test"));
 
DragStatus ret =  drag();
 
acutPrintf(_T("KKK:%d"),(int)ret);
 
return false;
 
acutPrintf(_T("\n 请选择矩形第一点:"));
m_ent.SetStatus(true);
if(drag() != AcEdJig::kNormal)
{
return false;
}
 
acutPrintf(_T("\n 请选择矩形第二点:"));
m_ent.SetStatus(false);
if(drag() != AcEdJig::kNormal)
{
return false;
}
 
pt1 = m_ent.m_basePoint;
pt2 = m_ent.m_movePoint;
 
return true;
}


McEdGetPointWorldDraw类


worldDraw function


作用:纯虚函数,从该类继承,实现该接口,完成自定义拖放绘制。


接口virtual Mdesk::Boolean worldDraw(McGiWorldDraw * wdMcGePoint3d currentPoint) = NULL;


参数


名称说明
wd

绘图时使用的环境参数

CurrentPoint

当前点坐标


参考例程


Mdesk::Boolean CDynByWorldDraw::worldDraw(McGiWorldDraw * wd, McGePoint3d currentPoint)
{
 
if (m_bIsDraw)
{
m_ent.SetCenter(currentPoint);
}
else
{
double dLength = currentPoint.distanceTo(m_ent.GetCenter());
m_ent.SetLenth(dLength);
}
 
m_ent.worldDraw(wd);
 
return Mdesk::kTrue;
}