明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1376|回复: 6

objectarx修改块内实体无效

[复制链接]
发表于 2015-10-28 18:44:20 | 显示全部楼层 |阅读模式
     做了一个测试程序,试图将选中的块内直线的颜色改为红色,程序运行既不提示错误,运行过后也没有效果。不知道为什么?
  1. static void MyGroup_test_kuai ()
  2.   {
  3.     //将选到的块内直线变成红色
  4.     resbuf* rb = acutBuildList(RTDXF0, ACRX_T("INSERT"),RTNONE);
  5.     int ret = RTNORM;
  6.     ads_name result;
  7.     ret = acedSSGet(NULL, NULL, NULL, rb, result );
  8.     if ( ret!= RTNORM )
  9.     {
  10.       acedPrompt( _T("\n创建选择集失败!") );
  11.       return;
  12.     }
  13.     acutRelRb(rb);
  14.     // 对选择集进行处理
  15.     long len;//选集元素数量
  16.     long i=0;
  17.     acedSSLength(result,&len);
  18.     for(i=0; i<len; i++)
  19.     {
  20.       // 获得指定元素的ObjectId;
  21.       ads_name ent;
  22.       acedSSName(result, i, ent);
  23.       AcDbObjectId objId;
  24.       acdbGetObjectId(objId, ent);
  25.       // 获得指向当前元素的指针;
  26.       AcDbEntity *pEnt;
  27.       //读模式打开对象
  28.       acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead);
  29.       if(pEnt->isKindOf(AcDbBlockReference::desc()))//块;
  30.       {
  31.         //插入的块数据;
  32.         AcDbBlockReference *pBlockReference = AcDbBlockReference::cast(pEnt);
  33.         ads_name enti;
  34.         AcDbObjectId objId;
  35.         objId=pBlockReference->objectId();
  36.         struct resbuf *rbEnt; // 保存实体数据的结果缓冲区;
  37.         struct resbuf *rbrb; // 用于遍历rbEnt的结果缓冲区;
  38.         acdbGetAdsName(enti,objId);
  39.         rbEnt = acdbEntGet(enti);
  40.         rbrb = rbEnt;
  41.         CString bk;
  42.         while(rbrb->restype!=2) rbrb=rbrb->rbnext;
  43.         bk=rbrb->resval.rstring;//插入的块名称;
  44.         acutRelRb(rbrb);
  45.         //构建块表记录遍历器
  46.         AcDbBlockTable *pBlkTbl;
  47.         acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead);
  48.         AcDbBlockTableRecord *pBlkTblRcd; // Blk块表记录;
  49.         pBlkTbl->getAt(bk, pBlkTblRcd, AcDb::kForRead);

  50.         AcDbBlockTableRecordIterator *pItr; // 块表记录遍历器;
  51.         pBlkTblRcd->newIterator(pItr);

  52.         // 遍历块表记录,将所有的直线改为红色
  53.         for (pItr->start(); !pItr->done(); pItr->step())
  54.         {
  55.           AcDbEntity *pEn;
  56.           pItr->getEntity(pEn, AcDb::kForRead);
  57.           if(pEn->isKindOf(AcDbLine::desc()))//直线
  58.           {
  59.             pEn->upgradeOpen();//将对象打开模式由读提升为写
  60.             AcDbLine * pLine=AcDbLine::cast(pEn);
  61.             pLine->setColorIndex(1);//将直线改为红色

  62.             pEn->close();
  63.           }//Circle
  64.             
  65.           if (pEn != NULL)
  66.           {
  67.             pEn->close();
  68.           }
  69.         }
  70.         delete pItr;
  71.         pBlkTblRcd->close();
  72.         pBlkTbl->close();  
  73.         pEnt->close();
  74.       }//块;
  75.       if (pEnt != NULL)
  76.       {
  77.         pEnt->close();
  78.       }
  79.     }

  80.     //acutRelRb(rb);
  81.     acedSSFree(result);//释放选集
  82.   }
复制代码
发表于 2015-10-28 22:10:08 | 显示全部楼层
本帖最后由 ivde 于 2015-10-28 22:13 编辑

1 Blockreference直接获取blockid不用entget
2 改完regen或更新所有blockreference
 楼主| 发表于 2015-10-28 22:57:11 | 显示全部楼层
ivde 发表于 2015-10-28 22:10
1 Blockreference直接获取blockid不用entget
2 改完regen或更新所有blockreference

Blockreference直接获取blockid不用entget,遍历块可以不用知道块的名称?这个没有看到实例,我也只是照着实例抄着来的。 更新所有blockreference这个还真不懂。希望能给个代码学习下!
发表于 2015-10-29 08:04:47 | 显示全部楼层
  1.         static void asdkMyGroupMyCommand () {
  2.                 // Put your command code here
  3.                 resbuf* rb=NULL;
  4.                 rb= acutBuildList(RTDXF0, _T("INSERT"),RTNONE);
  5.                 int ret;
  6.                 ads_name result;
  7.                 ret = acedSSGet(NULL, NULL, NULL, rb, result );
  8.                 if (ret!= RTNORM)
  9.                 {
  10.                         acedPrompt( _T("\n创建选择集失败!") );
  11.                         return;
  12.                 }
  13.                 acutRelRb(rb);
  14.                 long len,i=0;
  15.                 acedSSLength(result,&len);
  16.                 AcDbObjectIdArray blkIds;
  17.                 Acad::ErrorStatus es;
  18.                 ads_name ent;
  19.                 AcDbObjectId objId,blkId;
  20.                 for(i=0; i<len; i++)
  21.                 {
  22.                         acedSSName(result, i, ent);
  23.                         acdbGetObjectId(objId, ent);
  24.                         AcDbEntity *pEnt=NULL;
  25.                         es=acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead,false);  
  26.                         if (es!=Acad::eOk)
  27.                         {
  28.                                 continue;
  29.                         }
  30.                         AcDbBlockReference *pBlockRef =NULL;
  31.                         pBlockRef = AcDbBlockReference::cast(pEnt);
  32.                         blkId=pBlockRef ->blockTableRecord();
  33.                         if (!blkIds.contains(blkId,0))
  34.                         {
  35.                                 blkIds.append(blkId);
  36.                         }
  37.                         pBlockRef->close();
  38.                         pEnt->close();
  39.                 }
  40.                 for (int i=0;i<blkIds.logicalLength();i++)
  41.                 {
  42.                         AcDbObjectId id=blkIds.at(i);
  43.                         AcDbBlockTableRecordPointer btr(id,AcDb::kForWrite,false);
  44.                         if (btr.openStatus()!=Acad::eOk)
  45.                         {
  46.                                 continue;
  47.                         }
  48.                         AcDbBlockTableRecordIterator *pItr=NULL; // 块表记录遍历器;
  49.                         btr->newIterator(pItr);
  50.                         AcDbEntity *pEn=NULL;
  51.                         for (pItr->start(); !pItr->done(); pItr->step())
  52.                         {
  53.                                 pItr->getEntity(pEn, AcDb::kForRead,false);
  54.                                 if (pEn->isA()==AcDbLine::desc())
  55.                                 {  
  56.                                         pEn->upgradeOpen();  
  57.                                         pEn->setColorIndex(1,1);                                       
  58.                                         pEn->close();
  59.                                 }
  60.                         }                         
  61.                         delete pItr;
  62.                         btr.close();
  63.                 }
  64.                 acedCommand(RTSTR,_T("regen"),RTNONE);
  65.                 acedSSFree(result);//释放选集
  66.         }
复制代码
 楼主| 发表于 2015-10-29 15:21:40 | 显示全部楼层
ivde 发表于 2015-10-29 08:04

谢谢指导!看到您的代码感觉受益良多!另外如果不用regen如何更新所有blockreference?
发表于 2015-10-30 00:37:42 | 显示全部楼层
本帖最后由 ivde 于 2015-10-30 00:39 编辑
zdqwy19 发表于 2015-10-29 15:21
谢谢指导!看到您的代码感觉受益良多!另外如果不用regen如何更新所有blockreference?


据说使用这两句
                actrTransactionManager->flushGraphics();  
                acedUpdateDisplay();
我是没有测试成功过,可以使用一个变通方法

  1. AcDbObjectIdArray ids;
  2. es=btr->getBlockReferenceIds(ids,true,false);
  3. ....
  4. if (es==Acad::eOk)
  5.                         {
  6.                                 for (int n=0;n<ids.logicalLength();n++)
  7.                                 {
  8.                                         AcDbObjectId bid;
  9.                                         bid=ids.at(n);
  10.                                         AcDbEntity* pblk=NULL;
  11.                                         es=acdbOpenAcDbEntity(pblk,bid,AcDb::kForWrite,false);
  12.                                         if (es==Acad::eOk)
  13.                                         {
  14.                                                 AcDbBlockReference* pBlkr=NULL;
  15.                                                 pBlkr=AcDbBlockReference::cast(pblk);
  16.                                                 if (pBlkr!=NULL)
  17.                                                 {
  18.                                                         AcGePoint3d pint;
  19.                                                         pint=pBlkr->position();
  20.                                                         pBlkr->setPosition(pint);
  21.                                                         pBlkr->close();
  22.                                                 }
  23.                                                 pblk->close();
  24.                                         }
  25.                                 }
  26.                         }
复制代码
相当于强制更新
 楼主| 发表于 2015-10-30 14:50:22 | 显示全部楼层
ivde 发表于 2015-10-30 00:37
据说使用这两句
                actrTransactionManager->flushGraphics();  
                acedUpdateDisplay();

这个我找到了解决方法,打开插入块的时候
AcDbEntity* pEntity;
AcDbObjectId blkId;
acdbOpenObject( pEntity, blkId, AcDb::kForWrite );
//更改...
pEntity ->recordGraphicsModified();
pEntity ->close();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
谢谢了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-28 22:05 , Processed in 0.195071 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表