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

实体AcDbBlockReference :块参照,块引用数据库

块表AcDbBlockTable 数组

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

(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)插入块参照:块定义不是一个实体,而是一种对实体的描述,经过定义块得到;块参照则是一种实体,图形窗口中显示的“块”都是块参照,经过插入块得到。this

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 中的“属性” ) ,能够直接建立该类的一个对象,而后将其添加到块表记录中。3d

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

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

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

插入一个普通的块参照后,使用遍历器遍历块参照对应的块表记录,若是找到一个属性定义,就建立一个属
性,而且附加到块参照上。code

// 判断指定的块表记录是否包含属性定义
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)查看块定义的图标orm

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

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);
相关文章
相关标签/搜索