(1)使用ObjectARX创建一个新工程Group.
注册命令AddGroup,提示用户选择实体,将其创建成一个编组,
实现函数为:
static void AAAMyGroupAddGroup() {
//提示用户选择多个实体
AcDbObjectIdArray entIds;
if (CSelectUtil::PromptSelectEnts(TEXT("\\n选择要成组的实体:"),
AcDbEntity::desc(), entIds))
{
//创建组
AcDbGroup *pGroup = new AcDbGroup();
for (int i = 0; i < entIds.length(); i++)
{
pGroup->append(entIds[i]);
}
//将组添加到有名对象字典的组字典中
AcDbDictionary *pGroupDict = NULL;
acdbHostApplicationServices()->workingDatabase()
->getGroupDictionary(pGroupDict, AcDb::kForWrite);
//如果组名为*,则会创建匿名组
CString groupName = TEXT("*");
AcDbObjectId groupId;
pGroupDict->setAt(groupName, pGroup, groupId);
pGroupDict->close();
pGroup->close();
}
}
其中,函数PromptSelectEnts 的实现:
首先在项目中添加一个普通类 CSelectUtil,
函数 PromptSelectEnts 的声明:
// 提示用户选择多个实体
static bool PromptSelectEnts(const TCHAR* prompt, AcRxClass* classDesc, AcDbObjectIdArray &entIds);
static bool PromptSelectEnts(const TCHAR* prompt, const std::vector<AcRxClass*> &classDescs, AcDbObjectIdArray &entIds);
函数 PromptSelectEnts 的实现:
bool CSelectUtil::PromptSelectEnts(const TCHAR* prompt, AcRxClass* classDesc, AcDbObjectIdArray &entIds)
{
std::vector<AcRxClass*> vecClassDesc;
vecClassDesc.push_back(classDesc);
return PromptSelectEnts(prompt, vecClassDesc, entIds);
}
bool CSelectUtil::PromptSelectEnts(const TCHAR* prompt, const std::vector<AcRxClass*> &classDescs, AcDbObjectIdArray &entIds)
{
// 初始化
entIds.setLogicalLength(0);
// 提示用户选择实体
ads_name sset;
int result = 0;
acutPrintf(prompt);
result = acedSSGet(NULL, NULL, NULL, NULL, sset);
if (result != RTNORM)
{
return false;
}
// 取得选择集的长度
long length = 0;
acedSSLength(sset, reinterpret_cast<Adesk::Int32*>(&length));
// 遍历选择集
Acad::ErrorStatus es;
AcDbEntity* pEnt = NULL;
for (long i = 0; i < length; i++)
{
ads_name ename;
acedSSName(sset, i, ename);
AcDbObjectId curEntId;
es = acdbGetObjectId(curEntId, ename);
if (es != Acad::eOk)
{
continue;
}
// 打开实体
es = acdbOpenObject(pEnt, curEntId, AcDb::kForRead);
if (es != Acad::eOk)
{
continue;
}
// 判断当前实体是否是指定的实体类型
for (int j = 0; j < (int)classDescs.size(); j++)
{
if (pEnt->isKindOf(classDescs[j]))
{
entIds.append(pEnt->objectId());
break;
}
}
pEnt->close(); // 关闭实体
}
acedSSFree(sset); // 释放选择集
return (entIds.length() > 0);
}
(2)注册一个命令DeleteGroup,
提示用户选择图形中位于编组内的实体,然后删除这个编组。
实现函数为:
static void AAAMyGroupDeleteGroup() {
AcDbObjectIdArray entIds;
if (CSelectUtil::PromptSelectEnts(TEXT("\\n选择要分解的组中的实体:"), AcDbEntity::desc(), entIds))
{
//遍历组字典,判断是否包含了给定的实体
AcDbDictionary *pGroupDict = NULL;
acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pGroupDict, AcDb::kForWrite);
AcDbDictionaryIterator *it = pGroupDict->newIterator();
for (; !it->done(); it->next())
{
AcDbGroup *pGroup = NULL;
if (it->getObject((AcDbObject*&)pGroup, AcDb::kForWrite) == Acad::eOk)
{
AcDbObjectIdArray groupEntIds;
pGroup->allEntityIds(groupEntIds);
bool bFound = false;
for (int i = 0; i < entIds.length(); i++)
{
if (groupEntIds.contains(entIds[i]))
{
bFound = true;
break;
}
}
//删除包含选择集中实体的组
if (bFound)
{
pGroup->erase();
}
pGroup->close();
}
}
pGroupDict->close();
}
}
效果:
①运行AutoCAD,加载生成的ARX文件,执行AddGroup命令,
选择若干实体,然后按enter键;
②使用ArxDbg工具来观察:
如果你没有ArxDbg工具,可从这里下载:
https://blog.csdn.net/qq_40416052/article/details/82832475
③执行DelGroup命令,删除编组。
项目的完整源代码:
https://pan.baidu.com/s/1bHE3_IQQb8L7gNhPmla2uQ
参考资料:
张帆 《AutoCAD ObjectARX(VC)开发基础与实例教程》
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END