dipenghao 发表于 2005-3-29 12:22:00

扩展记录查找问题

查询某一个实体对象添加扩展记录的时候,使用extensionDictionary()获得字典ID,然后打开字典,字典里面已经添加上了AcdbXrecord类


        在使用getAt(        const char* entryName,       AcDbObjectId& entryObj)根据关键字搜索对应的扩展记录的时候,明明存在,使用getAt去查询不到 ?各位 遇到没有遇到这种问题,


还有一个就是使用字典迭代指针的时候,getObject()遍历 也是搜寻不到,

pandoram 发表于 2005-3-29 14:21:00

如果不是拼写问题, 那就可能是AcDbObjectID&指针没有cast好. 如果你要打开的是一个AcDbXrecord, 需要建立一个Xrecord指针, 但从字典打开的时候要cast成AcDbObject指针.


这种情况最好把具体的代码拿出来看看.

dipenghao 发表于 2005-3-29 15:16:00

代码如下


        //删掉扩展字典里面的扩展记录<BR>       ads_name ent;<BR>        ads_point pt;<BR>        AcDbObject *pObj;<BR>        AcDbObjectId Id,dictObjId;


                if(acedEntSel("\n选择一个实体:",ent,pt)!=RTNORM) return;


        acdbGetObjectId(Id,ent);<BR>        acdbOpenAcDbObject(pObj,Id,AcDb::kForRead);<BR>       <BR>                       dictObjId=pObj-&gt;extensionDictionary();        <BR>        if(AcDbObjectId::kNull==dictObjId)<BR>        {<BR>        acedGetAcadDwgView()-&gt;MessageBox("该实体没有扩展字典","错误提示",MB_ICONERROR);<BR>                               pObj-&gt;close();<BR>        return;<BR>        }


        AcDbDictionary *pDict;<BR>               acdbOpenAcDbObject((AcDbObject*&amp;)pDict,dictObjId,AcDb::kForRead);<BR><BR>                AcDbDictionaryIterator *Iter=pDict-&gt;newIterator();<BR>        int n=0;<BR>                       for(;!Iter-&gt;done();Iter-&gt;next())<BR>        {                       CString sName=Iter-&gt;name();<BR>                               acutPrintf("%s       ",sName);<BR>                if(n%4==0)<BR>                        acutPrintf("\n");<BR>                        n++;<BR>        }<BR>        delete Iter;<BR>        pDict-&gt;close(); //关闭一次再打开<BR>        //输入关键字索引 然后删掉对应的扩展记<BR>        char *result=new char[];<BR>        stat=acedGetString(0,"\n选择要删除关键字:(ESC-退出)",result);<BR>        if(stat==RTCAN||stat!=RTNORM)<BR>        {<BR>                pObj-&gt;close();<BR>                break;<BR>        }<BR>        //acutPrintf("输入的值为:%s\n",result);<BR>        pObj-&gt;upgradeOpen();<BR>        AcDbXrecord *pXrec;


pDIct-&gt;upgradeOpen();<BR>        if(Acad::eOk!=pDict-&gt;getAt(result,(AcDbObject * &amp;)pXrec,AcDb::kForWrite))<BR>        {<BR>                acutPrintf("没有找到\n");<BR>                pObj-&gt;close();<BR>                return;<BR>        }<BR>        else<BR>               {


                       pXrec-&gt;erase();<BR>                               pXrec-&gt;close();<BR>                pObj-&gt;close();


}


其中,形成扩展记录的时候以下格式生成


        struct resbuf *head;<BR>       ads_point testpt;<BR>       testpt=point_cur.x;<BR>       testpt=point_cur.y;<BR>       testpt=point_cur.z;<BR>       head = acutBuildList(AcDb::kDxfText,<BR>                                                                                                                                                       data,//输入的字符串值<BR>                                                                                                                       AcDb::kDxfXCoord,<BR>                                                                                                                       testpt,//点的坐标<BR>                                                                                                               0);<BR>               pXrec-&gt;setFromRbChain(*head));       


//有的时候能够找到,但是执行erase命令时候提示不能为写

pandoram 发表于 2005-3-29 16:59:00

代码可能有问题之处比较乱, 可能要细心一点慢慢查找.


pDict-&gt;close(); //关闭一次再打开<BR>和<BR>pDIct-&gt;upgradeOpen();<BR><BR>第一, 拼写似乎有不同. 第二, upgradeOpen是从open(read)提到write, 不是从close提到open, 因为open这个操作的默认开放度是kForRead. 所以实际上很可能你在执行getAt的时候dictionary并没有打开.


另外, 最后结束时没有关闭pDict.


如果要从externsion dictionary删除记录, 最好直接用dicitonary的remove功能, 打开要被删除的记录让它直接自己删除自己是容易让数据库暴走的行为, 除非你想要将来能够执行undo. 因为erase()本身并不直接物理删除记录, 只是把自己标注成erased而已.

dipenghao 发表于 2005-3-30 00:11:00

多谢,我以前写的代码,关闭再打开只是为了验证以下扩展记录里面的内容,用的是erase()命令比较多,后来我用remove简单多了,


不过很多时候,由于VC中用CString类比较多,而Arx中的函数大多是char*        的,象getAt函数,有的时候必须转换。       还有就是,有时候我用字典迭代器循环可以得到每个扩展记录的关键字,却在使用getObject()函数的时候,无法返回正确的指针。

pandoram 发表于 2005-3-30 10:49:00

CString类 = const char*, 自己设一个char*, strcpy过来就可以了. 主要是VC++的对话框控件都是生成CString. char*是C type string所以C++不喜欢用, 但ARX是从C(ADS)提上来的, 所以很多函数还有C的成分.


getObject的指针也是要cast的, 这个问题也很难说就是指针回返出错, 因为就像你楼上给的那部分代码一样, 有时侯是前面后面的细节没有处理好造成中间的一个函数暴走. 最好还是仔细从头到尾检查一下, 不过这种情况偶强烈推荐用VC debugger, 观察在进入getObject之前之后所有的指针是否都正确.

dipenghao 发表于 2005-3-30 18:43:00

多谢
页: [1]
查看完整版本: 扩展记录查找问题