添加下面代码向acad中添加一个层过滤器
int CreateLayerFilter(LPTSTR filterName,LPTSTR layerNames)
{
AcDbSymbolTablePointer<AcDbLayerTable> bp(acdbCurDwg(),AcDb::kForWrite);
bp->createExtensionDictionary();
AcDbObjectId ExDic_ID=bp->extensionDictionary(); //为层表创建扩展字典
AcDbObject * p_Obj=NULL;
if (Acad::eOk == acdbOpenAcDbObject(p_Obj,ExDic_ID,AcDb::kForWrite))
{
AcDbDictionary * p_Dic=NULL;
p_Dic=AcDbDictionary::cast(p_Obj);
AcDbDictionary * p_LfDic=NULL;
AcDbObjectId lfDic_ID;
if (p_Dic->has(_T("ACAD_LAYERFILTERS"))){ //如果已有层过滤器定义就获取
p_Dic->getAt(_T("ACAD_LAYERFILTERS"),lfDic_ID);
}
else{
p_LfDic=new AcDbDictionary; //如果没有就添加一个
p_Dic->setAt(_T("ACAD_LAYERFILTERS"),p_LfDic,lfDic_ID);
p_LfDic->close();
}
p_Dic->close();
acdbOpenAcDbObject(p_Obj,lfDic_ID,AcDb::kForWrite);
p_LfDic=AcDbDictionary::cast(p_Obj);
AcDbXrecord *p_NewXrec=NULL;
AcDbObjectId xrecID;
if (p_LfDic->has(filterName)) //如果已有同名过滤器就获取
{
p_LfDic->getAt(filterName,xrecID);
acdbOpenAcDbObject(p_Obj,xrecID,AcDb::kForWrite);
p_NewXrec=AcDbXrecord::cast(p_Obj);
}else{ //如果没有就添加一个
p_NewXrec=new AcDbXrecord;
p_LfDic->setAt(filterName,p_NewXrec,xrecID);
}
p_LfDic->close();
resbuf *pRb;
pRb = acutBuildList(
AcDb::kDxfText,filterName, //过滤器设定名
AcDb::kDxfText,layerNames, //过滤图层名,用逗号分隔
AcDb::kDxfText,_T("*"),
AcDb::kDxfText,_T("*"),
AcDb::kDxfInt16 ,0,
AcDb::kDxfText,_T("*"),
AcDb::kDxfText,_T("*"),
RTNONE);
p_NewXrec->setFromRbChain(*pRb); //按构建的dxf编码组设置AcdbXrecrod的内容
acutRelRb(pRb);
p_NewXrec->close();
}
return RTNORM;
}
执行代码如: CreateLayerFilter(_T("test"),_T("图层1,图层2"));
结果如下:
AcDbDictionary中存的内容很杂,可以先用AcDbDictionaryIterator将其遍历一遍,搞清楚里面存的东西的类型和name,
这个很重要,最好是先有一个已经建好的结构,比如上面的层过滤器,先用acad建一个,然后分析就方便了
AcDbDictionaryIterator * it;
it=p_LfDic->newIterator();
AcDbXrecord *p_Xrec;
while (!it->done())
{
CString itemName=it->name(); //存储内容的关键字AcDbDictionary的setAt就靠它了,当然也可用acdbobjectid
resbuf *pRb;
it->getObject(p_Obj,AcDb::kForWrite); //获取存储的内容,一般都是AcDbXrecord
p_Xrec=AcDbXrecord::cast(p_Obj);
p_Xrec->rbChain(&pRb);
CString str_value= pRb->resval.rstring; //随便找个值读一下,根据dxf的类型自己分,在层过滤器中其acdbxrecord的dxf编码第一个是string类型,就是过滤器的名字
acutPrintf(_T("%s"),str_value);
p_Xrec->close();
acutRelRb(pRb);
it->next();
}
delete it;
说name重要是因为AcDbDictionary在setAt的时候,要和acutBuildList中用同样的filterName命名
p_LfDic->setAt(filterName,p_NewXrec,xrecID); //一定要用filterName,否则就悲剧,一点图层过滤器按钮就崩溃,折腾了好久才发现。
避免这个问题的最好办法就是前面说的,先用acad建一个图层过滤器,用迭代器看清楚了再动手添加。