objectarx修改块内实体无效
做了一个测试程序,试图将选中的块内直线的颜色改为红色,程序运行既不提示错误,运行过后也没有效果。不知道为什么?static void MyGroup_test_kuai (){
//将选到的块内直线变成红色
resbuf* rb = acutBuildList(RTDXF0, ACRX_T("INSERT"),RTNONE);
int ret = RTNORM;
ads_name result;
ret = acedSSGet(NULL, NULL, NULL, rb, result );
if ( ret!= RTNORM )
{
acedPrompt( _T("\n创建选择集失败!") );
return;
}
acutRelRb(rb);
// 对选择集进行处理
long len;//选集元素数量
long i=0;
acedSSLength(result,&len);
for(i=0; i<len; i++)
{
// 获得指定元素的ObjectId;
ads_name ent;
acedSSName(result, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
// 获得指向当前元素的指针;
AcDbEntity *pEnt;
//读模式打开对象
acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead);
if(pEnt->isKindOf(AcDbBlockReference::desc()))//块;
{
//插入的块数据;
AcDbBlockReference *pBlockReference = AcDbBlockReference::cast(pEnt);
ads_name enti;
AcDbObjectId objId;
objId=pBlockReference->objectId();
struct resbuf *rbEnt; // 保存实体数据的结果缓冲区;
struct resbuf *rbrb; // 用于遍历rbEnt的结果缓冲区;
acdbGetAdsName(enti,objId);
rbEnt = acdbEntGet(enti);
rbrb = rbEnt;
CString bk;
while(rbrb->restype!=2) rbrb=rbrb->rbnext;
bk=rbrb->resval.rstring;//插入的块名称;
acutRelRb(rbrb);
//构建块表记录遍历器
AcDbBlockTable *pBlkTbl;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead);
AcDbBlockTableRecord *pBlkTblRcd; // Blk块表记录;
pBlkTbl->getAt(bk, pBlkTblRcd, AcDb::kForRead);
AcDbBlockTableRecordIterator *pItr; // 块表记录遍历器;
pBlkTblRcd->newIterator(pItr);
// 遍历块表记录,将所有的直线改为红色
for (pItr->start(); !pItr->done(); pItr->step())
{
AcDbEntity *pEn;
pItr->getEntity(pEn, AcDb::kForRead);
if(pEn->isKindOf(AcDbLine::desc()))//直线
{
pEn->upgradeOpen();//将对象打开模式由读提升为写
AcDbLine * pLine=AcDbLine::cast(pEn);
pLine->setColorIndex(1);//将直线改为红色
pEn->close();
}//Circle
if (pEn != NULL)
{
pEn->close();
}
}
delete pItr;
pBlkTblRcd->close();
pBlkTbl->close();
pEnt->close();
}//块;
if (pEnt != NULL)
{
pEnt->close();
}
}
//acutRelRb(rb);
acedSSFree(result);//释放选集
} 本帖最后由 ivde 于 2015-10-28 22:13 编辑
1 Blockreference直接获取blockid不用entget
2 改完regen或更新所有blockreference ivde 发表于 2015-10-28 22:10 static/image/common/back.gif
1 Blockreference直接获取blockid不用entget
2 改完regen或更新所有blockreference
Blockreference直接获取blockid不用entget,遍历块可以不用知道块的名称?这个没有看到实例,我也只是照着实例抄着来的。 更新所有blockreference这个还真不懂。希望能给个代码学习下! static void asdkMyGroupMyCommand () {
// Put your command code here
resbuf* rb=NULL;
rb= acutBuildList(RTDXF0, _T("INSERT"),RTNONE);
int ret;
ads_name result;
ret = acedSSGet(NULL, NULL, NULL, rb, result );
if (ret!= RTNORM)
{
acedPrompt( _T("\n创建选择集失败!") );
return;
}
acutRelRb(rb);
long len,i=0;
acedSSLength(result,&len);
AcDbObjectIdArray blkIds;
Acad::ErrorStatus es;
ads_name ent;
AcDbObjectId objId,blkId;
for(i=0; i<len; i++)
{
acedSSName(result, i, ent);
acdbGetObjectId(objId, ent);
AcDbEntity *pEnt=NULL;
es=acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead,false);
if (es!=Acad::eOk)
{
continue;
}
AcDbBlockReference *pBlockRef =NULL;
pBlockRef = AcDbBlockReference::cast(pEnt);
blkId=pBlockRef ->blockTableRecord();
if (!blkIds.contains(blkId,0))
{
blkIds.append(blkId);
}
pBlockRef->close();
pEnt->close();
}
for (int i=0;i<blkIds.logicalLength();i++)
{
AcDbObjectId id=blkIds.at(i);
AcDbBlockTableRecordPointer btr(id,AcDb::kForWrite,false);
if (btr.openStatus()!=Acad::eOk)
{
continue;
}
AcDbBlockTableRecordIterator *pItr=NULL; // 块表记录遍历器;
btr->newIterator(pItr);
AcDbEntity *pEn=NULL;
for (pItr->start(); !pItr->done(); pItr->step())
{
pItr->getEntity(pEn, AcDb::kForRead,false);
if (pEn->isA()==AcDbLine::desc())
{
pEn->upgradeOpen();
pEn->setColorIndex(1,1);
pEn->close();
}
}
delete pItr;
btr.close();
}
acedCommand(RTSTR,_T("regen"),RTNONE);
acedSSFree(result);//释放选集
}
ivde 发表于 2015-10-29 08:04 static/image/common/back.gif
谢谢指导!看到您的代码感觉受益良多!另外如果不用regen如何更新所有blockreference? 本帖最后由 ivde 于 2015-10-30 00:39 编辑
zdqwy19 发表于 2015-10-29 15:21 static/image/common/back.gif
谢谢指导!看到您的代码感觉受益良多!另外如果不用regen如何更新所有blockreference?
据说使用这两句
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
我是没有测试成功过,可以使用一个变通方法
AcDbObjectIdArray ids;
es=btr->getBlockReferenceIds(ids,true,false);
....
if (es==Acad::eOk)
{
for (int n=0;n<ids.logicalLength();n++)
{
AcDbObjectId bid;
bid=ids.at(n);
AcDbEntity* pblk=NULL;
es=acdbOpenAcDbEntity(pblk,bid,AcDb::kForWrite,false);
if (es==Acad::eOk)
{
AcDbBlockReference* pBlkr=NULL;
pBlkr=AcDbBlockReference::cast(pblk);
if (pBlkr!=NULL)
{
AcGePoint3d pint;
pint=pBlkr->position();
pBlkr->setPosition(pint);
pBlkr->close();
}
pblk->close();
}
}
}
相当于强制更新 ivde 发表于 2015-10-30 00:37 static/image/common/back.gif
据说使用这两句
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
这个我找到了解决方法,打开插入块的时候
AcDbEntity* pEntity;
AcDbObjectId blkId;
acdbOpenObject( pEntity, blkId, AcDb::kForWrite );
//更改...
pEntity ->recordGraphicsModified();
pEntity ->close();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
谢谢了!
页:
[1]