【CAD二次开发】-ObjectARX-组字典(Group)

(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
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片