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);
相關文章
相關標籤/搜索