ObjectARX_符号表---->块和属性

实体AcDbBlockReference :块参照,块引用

块表AcDbBlockTable 

表记录AcDbBlockTableRecord:块定义,块表记录,

(1)创建块定义:所有的实体都保存在块表记录中,而块表记录则存储在块表中。定义块相当于增加了一个块表记录,块表记录的名称就是块定义的名称。

当前图形的块表中包含了五个记录:*Model_Space(模型空间)、*Paper_Space(图纸空间中的“布局1”)、*Paper_Space0(图纸空间中的“布局2”)、 “圆形”和“矩形” 。

void ZffCHAP3AddBlk()
{
// 获得当前图形数据库的块表
AcDbBlockTable *pBlkTbl = NULL;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite);

// 创建新的块表记录
AcDbBlockTableRecord *pBlkTblRcd = new AcDbBlockTableRecord();

// 根据用户的输入设置块表记录的名称
char blkName[40];
if (acedGetString(Adesk::kFalse, "\n输入图块的名称:", blkName) != RTNORM)
{
pBlkTbl->close();
delete pBlkTblRcd;
return;
}
pBlkTblRcd->setName(blkName);

// 将块表记录添加到块表中
AcDbObjectId blkDefId;
pBlkTbl->add(blkDefId, pBlkTblRcd);
pBlkTbl->close();

// 向块表记录中添加实体
AcGePoint3d ptStart(-10, 0, 0), ptEnd(10, 0, 0);
AcDbLine *pLine1 = new AcDbLine(ptStart, ptEnd); // 创建一条直线
ptStart.set(0, -10, 0);
ptEnd.set(0, 10, 0);
AcDbLine *pLine2 = new AcDbLine(ptStart, ptEnd); // 创建一条直线
AcGeVector3d vecNormal(0, 0, 1);
AcDbCircle *pCircle = new AcDbCircle(AcGePoint3d::kOrigin,vecNormal, 6);
AcDbObjectId entId;
pBlkTblRcd->appendAcDbEntity(entId, pLine1);
pBlkTblRcd->appendAcDbEntity(entId, pLine2);
pBlkTblRcd->appendAcDbEntity(entId, pCircle);

// 关闭实体和块表记录
pLine1->close();
pLine2->close();
pCircle->close();
pBlkTblRcd->close();
}

(2)插入块参照:块定义不是一个实体,而是一种对实体的描述,通过定义块获得;块参照则是一种实体,图形窗口中显示的“块”都是块参照,通过插入块获得。

void ZffCHAP3InsertBlk()
{
acDocManager->lockDocument(curDoc()); 
// 获得用户输入的块定义名称 
char blkName[40];
if (acedGetString(Adesk::kFalse, "\n输入图块的名称:", blkName) !=RTNORM)
   return;

// 获得当前数据库的块表
AcDbBlockTable *pBlkTbl = NULL;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite);

// 查找用户指定的块定义是否存在
CString strBlkDef;
strBlkDef.Format("%s", blkName);
if (!pBlkTbl->has(strBlkDef))
{
acutPrintf("\n当前图形中未包含指定名称的块定义!");
pBlkTbl->close();
return;
}

// 获得用户输入的块参照的插入点
ads_point pt;
if (acedGetPoint(NULL, "\n输入块参照的插入点:", pt) != RTNORM)
{ 
pBlkTbl->close();
return;
}
AcGePoint3d ptInsert = asPnt3d(pt);

// 获得用户指定的块表记录
AcDbObjectId blkDefId;
pBlkTbl->getAt(strBlkDef, blkDefId);

// 创建块参照对象
AcDbBlockReference *pBlkRef = new AcDbBlockReference(ptInsert,blkDefId);

//pBlkRef->setPosition(basePoint); //设置插入点
//pBlkRef->setRotation(0.0); //设置旋转角度
//pBlkRef->setNormal(normal);//设置法向量

// 将块参照添加到模型空间
AcDbBlockTableRecord *pBlkTblRcd = NULL;
pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd,AcDb::kForWrite);
AcDbObjectId entId;
pBlkTblRcd->appendAcDbEntity(entId, pBlkRef);

// 关闭数据库的对象
pBlkRef->close();
pBlkTblRcd->close();
pBlkTbl->close();
acDocManager->lockDocument(curDoc()); 
}

(3)创建带属性的块定义:AcDbAttributeDefinition 类: AcDbText 类的一个派生类,表示属性定义对象,,属性定义是 AutoCAD的一种图形对象(对应于 AutoCAD 中的“属性” ) ,可以直接创建该类的一个对象,然后将其添加到块表记录中。

// 创建一个属性 输入直径
AcDbAttributeDefinition *pAttDef = new AcDbAttributeDefinition(ptEnd, "20", "直径", "输入直径"); 

// 向块表记录中添加实体
pBlkTblRcd->appendAcDbEntity(entId, pAttDef);

(4)插入带属性的块参照:包含块参照和属性两个部分,属性不能直接存在于图形窗口中,而必须依附于块参照存在。

插入一个普通的块参照后,使用遍历器遍历块参照对应的块表记录,如果找到一个属性定义,就创建一个属
性,并且附加到块参照上。

// 判断指定的块表记录是否包含属性定义
AcDbBlockTableRecord *pBlkDefRcd = NULL;
acdbOpenObject(pBlkDefRcd, blkDefId, AcDb::kForRead);
if (pBlkDefRcd->hasAttributeDefinitions())
{
AcDbBlockTableRecordIterator *pItr = NULL;
pBlkDefRcd->newIterator(pItr);
AcDbEntity *pEnt = NULL;
for (pItr->start(); !pItr->done(); pItr->step())
{
pItr->getEntity(pEnt, AcDb::kForRead);

// 检查是否是属性定义
AcDbAttributeDefinition *pAttDef = NULL;
pAttDef = AcDbAttributeDefinition::cast(pEnt);
if (pAttDef != NULL)
{
// 创建一个新的属性对象
AcDbAttribute *pAtt = new AcDbAttribute();

// 从属性定义获得属性对象的图层特性
pAtt->setPropertiesFrom(pAttDef);

// 设置属性对象的其他特性
pAtt->setInvisible(pAttDef->isInvisible());
AcGePoint3d ptBase = pAttDef->position();
ptBase += pBlkRef->position().asVector();
pAtt->setPosition(ptBase);
pAtt->setHeight(pAttDef->height());
pAtt->setRotation(pAttDef->rotation());

// 获得属性对象的Tag、Prompt和TextString
char *pStr = NULL;
pStr = pAttDef->tag();
pAtt->setTag(pStr);
free(pStr);//也可用全局函数 acutDelString 来代替
pStr = pAttDef->prompt();
acutPrintf("%s%s", "\n", pStr);
free(pStr);
pAtt->setFieldLength(30);
pAtt->setTextString("40");

// 向块参照追加属性对象
pBlkRef->appendAttribute(pAtt);
pAtt->close();
}
pEnt->close();
}
delete pItr;
}

(5)查看块定义的图标

获得指定的块表记录的预览图像

HBITMAP CPreviewBlkDlg::BlockIconToBMP(const AcDbObjectId &blkId, HDC hdc)
{
Acad::ErrorStatus es;
AcDbBlockTableRecord *pBlkTblRcd = NULL; // 块表记录的指针
AcArray<Adesk::UInt8> icon;  // 保存预览图标的数组

// 获得保存块表记录的预览图标的数组
try
{ 
es = acdbOpenObject(pBlkTblRcd, blkId, AcDb::kForRead);
if (es != Acad::eOk)
throw 1;

if (!pBlkTblRcd->hasPreviewIcon()) // 如果块定义不包含预览图标
{ 
pBlkTblRcd->close();
return NULL;
}

es = pBlkTblRcd->getPreviewIcon(icon);
if (es != Acad::eOk)
throw 2;
es = pBlkTblRcd->close();
if (es != Acad::eOk)
throw 3;
}
catch (...)
{ 
pBlkTblRcd->close();
return NULL; 
} 

// 由icon数组获得可显示的位图
BITMAPINFOHEADER ih; // 位图信息头
memcpy(&ih, icon.asArrayPtr(), sizeof(ih));
size_t memsize = sizeof(BITMAPINFOHEADER) + ((1<<ih.biBitCount)* sizeof(RGBQUAD)); 
LPBITMAPINFO bi = (LPBITMAPINFO)malloc(memsize);  // 位图信息
memcpy(bi, icon.asArrayPtr(), memsize);
HBITMAP hbm = CreateDIBitmap(hdc, &ih, CBM_INIT,icon.asArrayPtr() + memsize, bi,DIB_RGB_COLORS);
free(bi);
return hbm;
}

获得当前图形中用户定义的所有块表记录

// 获得当前图形的块表
AcDbBlockTable *pBlkTbl = NULL;
AcDbBlockTableRecord *pBlkTblRcd = NULL;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead);

// 遍历块表,获得用户自定义块表记录的名称,将其添加到组合框中
AcDbBlockTableIterator *pItr = NULL;
pBlkTbl->newIterator(pItr);
for (pItr->start(); !pItr->done(); pItr->step())
{ 
pItr->getRecord(pBlkTblRcd, AcDb::kForRead);
char *pName = NULL;
pBlkTblRcd->getName(pName);
CString strName(pName);
acutDelString(pName);
if (strName.Compare(ACDB_MODEL_SPACE) != 0 && strName.Compare(ACDB_PAPER_SPACE) != 0 && strName.Compare("*Paper_Space0"))
{
m_lstBlkDef.AddString(strName);
} 
pBlkTblRcd->close();
}
delete pItr;
pBlkTbl->close();

根据选择的块定义,查找对应的预览图标、对应块参照的数量,以及块定义是否包含属性

// 显示预览图标
CPaintDC dc(this);

AcDbBlockTable *pBlkTbl = NULL;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead);

CString strBlkDefName;//定义块的名称
m_lstBlkDef.GetLBText(m_lstBlkDef.GetCurSel(), strBlkDefName);

AcDbObjectId blkTblRcdId;
Acad::ErrorStatus es = pBlkTbl->getAt(strBlkDefName, blkTblRcdId);

HBITMAP hBitmap = BlockIconToBMP(blkTblRcdId, dc.GetSafeHdc());
m_bitmap.SetBitmap(hBitmap);

// 获得块表记录的指针
AcDbBlockTableRecord *pBlkTblRcd = NULL;
pBlkTbl->getAt(strBlkDefName, pBlkTblRcd, AcDb::kForRead);

// 获得块参照的数量
AcDbBlockReferenceIdIterator *pItr = NULL;
pBlkTblRcd->newBlockReferenceIdIterator(pItr);
int number = 0;
for (pItr->start(); !pItr->done(); pItr->step())
{
number++;
}
m_strBlkRefNum.Format("%d", number);

// 获得块参照是否包含属性
if (pBlkTblRcd->hasAttributeDefinitions())
{
m_strHasAttribute = "是";
}
else
{
m_strHasAttribute = "否";
}
pBlkTblRcd->close();
pBlkTbl->close();
UpdateData(FALSE);

 

转载于:https://my.oschina.net/u/2930533/blog/1596278

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ObjectARX是一种用于AutoCAD软件定制化开发的API。张帆的《ObjectARX开发实例教程》是一本适合初学者入门的书籍,通过实例的方式对ObjectARX进行系统性讲解。 本书共分为18章,从AutoCAD开发环境的搭建开始讲起,引领读者逐步深入了解ObjectARX。每一章都包含了相关实例,全面讲解了AutoCAD编程基础、ObjectARX、COM技术等相关知识点,让读者能够深入了解各种开发技术,如绘图、编辑、图形操作等。 本书中的实例都是实用性强、综合性好的项目,作者在实例中讲述了ObjectARX的各种技术应用,通过详细讲解及代码演示,使读者能够掌握这些方法,进而灵活应用到实际项目中。此外,文中还介绍了D-BASE文件格式、UNIX操作系统等相关知识,以帮助读者更好地理解AutoCAD的架构原理。 总之,张帆的《ObjectARX开发实例教程》是一本详实而全面的AutoCAD相关书籍,适合有编程基础并对AutoCAD感兴趣的读者学习参考。其中的案例演示丰富,对初学者来说十分友好,同时也能帮助已有一定开发经验的开发人员深造提高。 ### 回答2: ObjectARX是AutoCAD的开放式编程接口,使得开发者可以在AutoCAD上创建个性化的工具和应用程序。这使得AutoCAD成为一个灵活性更高的应用程序。 张帆的《ObjectARX开发实例教程》是一本以实践为主的教程,带领读者从零开始学习如何使用ObjectARX进行自定义开发。教程分为四部分,以一个图像处理器为示例介绍了ObjectARX的编写、调试、应用等技术。 第一部分介绍了ObjectARX的介绍、编程工具的准备和环境的搭建。第二部分从绘图交互的角度介绍了如何利用ObjectARX实现AutoCAD图形处理。第三部分以实例介绍了如何利用ObjectARX编写实用功能的插件程序,并介绍了用户界面设计方面的知识。第四部分介绍了如何编写和发布新的应用程序。 在实例教程中,张帆深入深出地剖析了ObjectARX开发的重要概念和技巧,介绍了它们在实际编程过程中的应用。该书比较深入且严谨,可以帮助读者了解ObjectARX中的各种实用细节,同时它也适合有一定编程基础的开发者学习。 总之,《ObjectARX开发实例教程》是入门到高阶的一本好书,对初学者和已有一定开发经验的开发者都非常适用。它既介绍了ObjectARX的基础,又让读者从编写插件和应用程序的角度发掘ObjectARX的灵活性和强大性。这使得读者可以在实践中学习编程技术,提升创造的灵活性和效率。 ### 回答3: “ObjectARX开发实例教程”是一本详细介绍了如何使用Autodesk的ObjectARX编程接口来进行CAD软件二次开发的实战教程。本书作者张帆是一位经验丰富的Autodesk软件开发专家,既有实践经验,也有丰富的教学经验,因此他在本书中将所涉及的内容讲解得非常清晰易懂。 本书从基础概念入手,先介绍了Autodesk的CAD软件和ObjectARX编程接口的基本知识,并且提供了许多实例来帮助读者更好地理解这些知识。在后续章节中,作者则依次介绍了ObjectARX的各个重要模,如数据库、图形界面、用户界面、3D绘图等,针对每个模提供了大量的实例代码,并详细讲解了其实现原理和使用技巧。 作为一本实战教程,本书还提供了很多实际应用场景下的编程技巧,例如如何处理大型CAD工程,如何实现CAD联网等等,这些内容将对实际开发非常有帮助。 总之,“ObjectARX开发实例教程”是一本很实用的CAD软件开发教程,对于想要学习ObjectARX编程接口的开发人员来说,读本书将是一种强有力的支持和帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值