找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1047|回复: 6

[ARX程序]:紧急求救(关于克隆实体)!!!

[复制链接]
发表于 2002-6-26 15:51:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
//////////////////////////////////////////////////////////////////////////
//    问题描述,我有一个模板文件路径 c:\MapMaper\TCAD01.dwt ,其中有9种块,
//块名分别为 1,2,3,4,5,6,7,8,9 我想做的是,在当前文档中插入c:\MapMaper\TCAD01.dwt
//中定义过的块,以下代码命令为 InsertBlock_1(其功能为在当前文档中插入块名为1的块)
//开发思路为:首先将块1克隆到当前文档中来,然后再以正常的方式插入一个块引用。
//
//    遇到的问题:我想让CAD以后台的方式打开TCAD01.dwt,当我想取得块1的ObjectID时
//系统说没找到(可以用for语句测试,代码地81行)可是当我以前台方式打开时(将第79,80
//行注销将82行打开)就可以访问到块1,地95行后的代码还没有测试不知道写的对不对,请求
//各位帮助解决。
//
//注:附件中已经带上了TCAD01.dwt
//                                                                                                万分感谢!!!
//                                                                                                                                沈阳 杜冰
//
////////////////////////////////////////////////////////////////////////

// ObjectARX defined commands, created by  [六月/25/2002] ,

#include "StdAfx.h"
#include "StdArx.h"
#include "stdafx.h"
#include "resource.h"
#include "acutads.h"
#include "dbents.h"
#include "dbpl.h"
#include "MALLOC.h"
#include "STDLIB.h"
#include "acedads.h"
#include "acutads.h"
#include "dbmtext.h "
#include "stdio.h"
#include "dbapserv.h"
#include "dbidmap.h"
#include "dbsymutl.h"
#include "dbsymtb.h"
#include "actrans.h"

//-----------------------------------------------------------------------------
// This is command 'INSERTBLOCK_1, by  [六月/25/2002], ,
void SKDInsertBlock_1()
{
#ifdef OARXWIZDEBUG
        acutPrintf ("\nOARXWIZDEBUG - SKDInsertBlock_1() called.");
#endif // OARXWIZDEBUG



        //Program Start
       
        //获得块的插入点
        ads_point Pnt1;
        AcGePoint3d insertPt;
        if (acedGetPoint(NULL,"\nPlease give me Insert point:",Pnt1)!=RTNORM)
        {
                acutPrintf("\n...User Cancel\n");
                return;
        }
        insertPt[X]=Pnt1[X];
        insertPt[Y]=Pnt1[Y];
        insertPt[Z]=0;
        //对数据库操作开始
        AcDbDatabase *pCurrentDb = NULL; //用于指向当前数据库
        AcDbDatabase *pSourceDb = new AcDbDatabase;//用于指向后台数据库
        AcDbObjectId InsertblockId; //块的ObjctId
        AcDbObjectId referenceId;//快引用的ObjectId
        AcDbIdMapping pIdMap;
        AcDbObjectIdArray list;
        AcDbObjectId MyBlockId;
        AcDbBlockTable *pBlockTable = NULL;
        AcDbBlockTableRecord *pBlockTableRecord;
        char *pBlockName;
        AcDbBlockTableIterator *pLtIterator;

        //*********************************************************************************
        //以后台方式打开TCAD01.dwt数据库
        pSourceDb->readDwgFile("c:\\MapMaper\\TCAD01.dwt");   //Line  79
        pSourceDb->getSymbolTable(pBlockTable,AcDb::kForRead); //Line  80
        //以前台方式打开TCAD01.dwt数据库
        //acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable,AcDb::kForRead); //Line  82
    //***********************************************************************************


        //以下for语句用于测试块表中的块的名称  
        //!!! 问题在于如果以后台方式打开就无法访问块表,如果以前台打开(当前文档就是TCAD01.dwt)就可以 Why???
        pBlockTable->newIterator(pLtIterator);       
        for(;!pLtIterator->done();pLtIterator->step ())
        {
                pLtIterator->getRecord(pBlockTableRecord,AcDb::kForRead);
                pBlockTableRecord->getName(pBlockName);
                pBlockTableRecord->close();
                acutPrintf("\n Block Name is: %s",pBlockName);
        }
        /////////////////////////////////////
       
        delete pLtIterator;
        if(pBlockTable->has("1"))
        {
                pBlockTable->getAt("1",MyBlockId);
                list.append( MyBlockId );
                AcDbDatabase *curDb=acdbHostApplicationServices()->workingDatabase();
                AcDbObjectId ablockId = NULL;
                AcDbSymbolUtilities::getBlockId(ablockId,ACDB_MODEL_SPACE,curDb);               
                pSourceDb->deepCloneObjects (list,ablockId,pIdMap);//复制块到当前打开的文档
               
                AcDbBlockReference *pBlockReference = new AcDbBlockReference;               
                pBlockReference->setBlockTableRecord(MyBlockId);
                pBlockReference->setPosition(insertPt); //设置插入点
                pBlockReference->setRotation(0);//设置旋转角度
                pBlockReference->setLayer("0");//为插入的图块设置图层
                pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);
                pBlockTableRecord->appendAcDbEntity(referenceId,pBlockReference);
                pBlockTable->close();
                pBlockTableRecord->close();
                pBlockReference->close();

        }
        else
        {
                pBlockTable->close();
                pSourceDb->closeInput();
                delete pSourceDb;
                return;  //没有图块返回
        }
        pBlockTable->close();       
        pSourceDb->closeInput();
        delete pSourceDb;
        //Program End

}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
 楼主| 发表于 2002-6-26 15:53:19 | 显示全部楼层
上一贴的附件
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2002-7-2 09:15:56 | 显示全部楼层
//-----------------------------------------------------------------------------
// This is command 'XX, by  [七月/02/2002], ,
void xxxx()
{
#ifdef OARXWIZDEBUG
        acutPrintf ("\nOARXWIZDEBUG - xxxx() called.");
#endif // OARXWIZDEBUG

        // TODO: Implement the command
    AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);

    pDb->readDwgFile("e:\\test1.dwg");

    AcDbBlockTable *pBlkTbl;
    pDb->getSymbolTable(pBlkTbl, AcDb::kForRead);

    AcDbBlockTableIterator *pLtIterator;
        pBlkTbl->newIterator(pLtIterator);
    pBlkTbl->close();

        AcDbBlockTableRecord *pBlockTableRecord;
        char *pBlockName;
        for(pLtIterator->start();!pLtIterator->done();pLtIterator->step ())
        {
        pLtIterator->getRecord(pBlockTableRecord,AcDb::kForRead);
        pBlockTableRecord->getName(pBlockName);
        pBlockTableRecord->close();
        acutPrintf("\n Block Name is: %s",pBlockName);
        }

    delete pLtIterator;
    delete pDb;

}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2002-7-2 15:11:55 | 显示全部楼层
不知道为什么,我发现问题首先出现在文件的路径,您提供的源代码非常好,但是如果您试一试就会发现如果将文件的路径改为("c:\\MapMaper\\test1.dwg"),即包含上一级目录,就得到只能访问块名为: *Model_Space ,*Paper_Space,*Paper_Space0 的奇怪结果,再次麻烦您看一看这是怎么回事?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2002-7-3 10:46:43 | 显示全部楼层
我看了一看并没有错!
是不是你的vc没有sp,或arx没升级
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2002-7-5 10:24:58 | 显示全部楼层
这位同仁,程序做好了吗?如果好了,把这个例子贴出来,让大家共同研究学习
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2002-7-5 12:03:07 | 显示全部楼层
下面的程序实现了我预想的功能,如果当前文档已经有块,直接插入,如果没有则从指定的数据库中Clone一个实体过来然后在指定的点插入。

新的问题:在原数据库中定义的块是红色的(在第二帖的dwg文档中是红色的),Clone到当前文档后变为了白色,不知道这是为什么?

帮助分析分析,谢谢!

新的代码:
///////////////////////////////////////////////////////////////////////////////////////////
//
// ObjectARX defined commands, created by  [七月/02/2002], ,

#include "StdAfx.h"
#include "StdArx.h"
#include "stdafx.h"
#include "resource.h"
#include "acutads.h"
#include "dbents.h"
#include "dbpl.h"
#include "MALLOC.h"
#include "STDLIB.h"
#include "acedads.h"
#include "acutads.h"
#include "dbmtext.h "
#include "stdio.h"
#include "dbapserv.h"
#include "dbidmap.h"
#include "dbsymutl.h"
#include "dbsymtb.h"
#include "actrans.h"
#include "dbhatch.h"
#include "gepnt2d.h"
#include "util.h"


bool InsertBlock(AcGePoint3d insertPt,char BlockName[100], CString BlockLayer,double BlockRotation)
{
        AcDbBlockTable *pBlockTable = NULL;
        acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pBlockTable,AcDb::kForWrite);
        AcDbBlockTableRecord *pBlockTableRecord;
        AcDbObjectId blockId;
        if(pBlockTable->getAt(BlockName,blockId)==Acad::eOk)
        {
                AcDbBlockReference *pBlockReference = new AcDbBlockReference;
                AcDbObjectId referenceId;
                pBlockReference->setBlockTableRecord(blockId);
                pBlockReference->setPosition(insertPt); //设置插入点
                pBlockReference->setRotation(BlockRotation);//设置旋转角度
                pBlockReference->setLayer(BlockLayer);//为插入的图块设置图层
                pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);
                pBlockTableRecord->appendAcDbEntity(referenceId,pBlockReference);
                pBlockTable->close();
                pBlockTableRecord->close();
                pBlockReference->close();
                                           //此处原想将插入的块引用改变颜色,但是实际证明,如果块已经定义了,就不能更改块引用的颜色了
                AcDbEntity *pEnt=NULL;
                acdbOpenAcDbEntity(pEnt,referenceId,AcDb::kForWrite);
                pEnt->setColorIndex(1);       
                pEnt->close();
                return TRUE;
        }
        else
        {
                //没有图块什么也不做
                pBlockTable->close();
                return FALSE;  
        }
}

//-----------------------------------------------------------------------------
// This is command 'TEST, by  [七月/02/2002], ,
void SKDtest()
{
#ifdef OARXWIZDEBUG
        acutPrintf ("\nOARXWIZDEBUG - SKDtest() called.");
#endif // OARXWIZDEBUG

        //Program Start
       
        //获得块的插入点
        ads_point Pnt1;
        AcGePoint3d insertPt;
        if (acedGetPoint(NULL,"\nPlease give me Insert point:",Pnt1)!=RTNORM)
        {
                acutPrintf("\n...User Cancel\n");
                return;
        }
        insertPt[X]=Pnt1[X];
        insertPt[Y]=Pnt1[Y];
        insertPt[Z]=0;


        if (InsertBlock(insertPt,"1","0",0) == FALSE)
        {

                //对数据库操作开始
                AcDbDatabase *pCurrentDb = NULL; //用于指向当前数据库
                AcDbDatabase *pSourceDb = new AcDbDatabase;//用于指向后台数据库
                AcDbObjectId InsertblockId; //块的ObjctId
                AcDbObjectId referenceId;//快参考的ObjectId
                AcDbIdMapping pIdMap;
                AcDbObjectIdArray list;
                AcDbObjectId MyBlockId;
                AcDbBlockTable *pBlockTable = NULL;
                AcDbBlockTableRecord *pBlockTableRecord;
                char *pBlockName;
                AcDbBlockTableIterator *pLtIterator;

                //*********************************************************************************
                //以后台方式打开TCAD01.dwt数据库
                //pSourceDb->readDwgFile("c:\\MapMaper\\TCAD01.dwg");   //Line  79

                pSourceDb->readDwgFile("c:\\TCAD01.dwg");
                pSourceDb->getSymbolTable(pBlockTable,AcDb::kForRead); //Line  80
                //以前台方式打开TCAD01.dwt数据库
                //acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable,AcDb::kForRead); //Line  82
                //***********************************************************************************


                //以下for语句用于测试块表中的块的名称  
                //!!! 问题在于如果以后台方式打开就无法访问块表,如果以前台打开(当前文档就是TCAD01.dwt)就可以 Why???
                pBlockTable->newIterator(pLtIterator);
                pBlockTable->close(); //少了这一句
                for(;!pLtIterator->done();pLtIterator->step ())
                {
                        pLtIterator->getRecord(pBlockTableRecord,AcDb::kForRead);
                        pBlockTableRecord->getName(pBlockName);
                        AcDbObjectId aaaa;
                        AcDbHandle acHandle;
                        char handleStr[20];
                        aaaa = pBlockTableRecord->objectId();
                        pBlockTableRecord->getAcDbHandle(acHandle);
                        acHandle.getIntoAsciiBuffer(handleStr);
                        pBlockTableRecord->close();
                        acutPrintf("\n Block Name is: %s , Handle: %s",pBlockName,handleStr);               
                       
                }
                /////////////////////////////////////

                delete pLtIterator;
                if(pBlockTable->has("1"))
                {

                        AcDbDatabase* toDb = acDocManager->curDocument()->database();//设置目标数据库
                        AcDbIdMapping idMap;
                        idMap.setDestDb(toDb);
                        AcDbObjectId destBlkId;
                        destBlkId = toDb->currentSpaceId();//得到当前数据库
                        pBlockTable->getAt("1",MyBlockId);
                        list.append( MyBlockId );               
                        pSourceDb->wblockCloneObjects(list,destBlkId,idMap,AcDb::kDrcIgnore);//复制块到当前打开的文档                                                       
                        InsertBlock(insertPt,"1","0",0);
                }
                else
                {
                        pBlockTable->close();
                        pSourceDb->closeInput();
                        delete pSourceDb;
                        return;  //没有图块返回
                }
                pBlockTable->close();       
                pSourceDb->closeInput();
                delete pSourceDb;
                //Program End
        }

}

//结束
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-12-25 13:54 , Processed in 0.425733 second(s), 44 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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