⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asdktable.cpp

📁 这个是用vc+objectarx开发AcDbTable 实体和AcDbTableStyle对象
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//----- Populate the new table
void populateTable(AcDbTable *&pTbl, const RowData *pRwData)
{
	// Sanity check
	if ((NULL == pTbl) || (!pTbl->isWriteEnabled()) || 
		(NULL == pRwData) || (0 == pRwData->length())) PRTMSGRET(_T("eNotOpenForWrite"))

	if ((pRwData->at(2)->length() != pTbl->numColumns()) || 
		(pRwData->length() != pTbl->numRows()))PRTMSGRET(_T("Table and data does not match"))
	
	// Populate the table / Rows
	for(int nCtr1 = 0;nCtr1 < pRwData->length();nCtr1++)
	{
		FieldData *pColData = pRwData->at(nCtr1);
		for(int nCtr2 = 0;nCtr2 < pColData->length();nCtr2++)
		{
			pTbl->setTextString(nCtr1,nCtr2,pColData->at(nCtr2));
		}
	}
}

//-----------------------------------------------------------------------------
//----- Generate data for the selected Block
Acad::ErrorStatus generateTableFromBlock(const TCHAR *pBlkName, RowData *&pRwData, bool bLink)
{
	// Sanity check
	if((NULL == pRwData) || (NULL == pBlkName))PRTMSGRETES(Acad::eNotApplicable)
	
	AcDbBlockTable *pBT = NULL;
	AcDbBlockTableRecord *pBTR = NULL;
	Acad::ErrorStatus es;

	// Get the block table	
	PRTMSGRETES(acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT,AcDb::kForRead));
	
	// Get the blocktablerecord
	es = pBT->getAt(pBlkName,pBTR,AcDb::kForRead);
	pBT->close();
	
	PRTMSGRETES(es)
	
	// Check for all attributes
	if (!pBTR->hasAttributeDefinitions())
	{
		pBTR->close();
		PRTMSGRETES(Acad::eNotApplicable)
	}
	
	// Iterate for all attribute definitions
	// Build the header, this means find out how many attribute definitions are available
	AcDbBlockTableRecordIterator *pBTRItr = NULL;
	pBTR->newIterator(pBTRItr);
	
	// Add Data

	// Add Title in first row
	FieldData *pTitleData = new FieldData();
	
	TCHAR *pTitle = new TCHAR[256];
	memset(pTitle,0,256 * sizeof(TCHAR));
    _stprintf(pTitle,_T("Block Name: %s"),pBlkName);
	pTitleData->append(pTitle);
	
	pRwData->append(pTitleData);

	// Add header data in second row
	FieldData *pHdrData = new FieldData();

	// First column is Sl number
	pHdrData->append(_tcsdup(_T("Sl.No.")));

	// Second column is Block Reference Handle number
	pHdrData->append(_tcsdup(_T("Block Handle")));
	
	// Get the remaining Column names from the block definition's AcDbAttributeDefinition
	while (!pBTRItr->done())
	{
		AcDbEntity *pEnt = NULL;
		pBTRItr->getEntity(pEnt,AcDb::kForRead);
		
		AcDbAttributeDefinition *pAttDef = NULL;
		pAttDef = AcDbAttributeDefinition::cast(pEnt);
		
		if(NULL != pAttDef)
		{
			if (Adesk::kFalse == pAttDef->isConstant())
			{
				pHdrData->append(pAttDef->tag()); // Append the attribute TAG for header
			}
		}
		
		pEnt->close();
		pBTRItr->step();
	}
	
	pRwData->append(pHdrData);
	
	// Clean up
	delete pBTRItr;

	// Get the attribute data for every block reference
	AcDbObjectIdArray idObjs;
	pBTR->getBlockReferenceIds(idObjs,true);
	
	// Done with the block table record
	pBTR->close();
	
	// Some sanity check, check if the block references are in anonymous blocks
	for(int nCtr1 = 0;nCtr1 < idObjs.length(); nCtr1++)
	{
		bool bValid = true;
		AcDbBlockReference *pBlkRef = NULL;
		if(Acad::eOk == acdbOpenObject((AcDbEntity *&)pBlkRef,idObjs.at(nCtr1),AcDb::kForRead,false))
		{
			AcDbObject *pObj = NULL;

			if(Acad::eOk == acdbOpenObject(pObj,pBlkRef->ownerId(),AcDb::kForRead,false))
			{
				if (!pObj->objectId().isValid()) bValid = false;
				
				AcDbBlockTableRecord *pBTR;
				if(NULL != (pBTR = AcDbBlockTableRecord::cast(pObj)))
				{
					const TCHAR *pName;
					pBTR->getName(pName);
					if((!pBTR->isLayout()) && (_T('*') == (int)*pName)) bValid = false;
				}
				pObj->close();
			}
			pBlkRef->close();
		}
		
		if(!bValid) idObjs.remove(idObjs.at(nCtr1));
	}

	if(0 == idObjs.length())
	{
		acutPrintf(_T("\nNo block references found"));
		return Acad::eNotApplicable;
	}
	
	// Start iterating all the valid block references for the attribute data
	int nSlNoCtr = 1;
	for(int nCtr1 = 0;nCtr1 < idObjs.length(); nCtr1++)
	{
		AcDbBlockReference *pBlkRef = NULL;
		if(Acad::eOk == acdbOpenObject((AcDbEntity *&)pBlkRef,idObjs.at(nCtr1),AcDb::kForRead,false))
		{
			FieldData *pFldData = new FieldData();
			
			// Add the Sl No
			TCHAR *pSlNo = new TCHAR[8];
			memset(pSlNo,0,8 * sizeof(TCHAR));
			_stprintf(pSlNo,_T("%d"),nSlNoCtr);
			pFldData->append(pSlNo);
			
			// Add the block reference handle
			TCHAR *pHndNo = new TCHAR[17];
			memset(pHndNo,0,17 * sizeof(TCHAR));
			AcDbHandle hnd;
			pBlkRef->getAcDbHandle(hnd);
			hnd.getIntoAsciiBuffer(pHndNo);
			
			pFldData->append(pHndNo);
			
			// Get the attribute data from the block reference. Create attribute name<->value map
			// this is required to fill data in correct sequence
			// irrespective of how we read the attributes
			HdrRwMap *pHdrRw = new HdrRwMap(); 
			
			AcDbObjectIterator *pAttItr = NULL;
			pAttItr = pBlkRef->attributeIterator();

			while (!pAttItr->done())
			{
				AcDbAttribute *pAtt;
				if (Acad::eOk == acdbOpenObject((AcDbEntity *&)pAtt,pAttItr->objectId(),AcDb::kForRead))
				{
					// If link is true then add a field
					if(bLink)
					{
						TCHAR *pAcFld = new TCHAR[512];
						memset(pAcFld,0,512 * sizeof(TCHAR));
						_stprintf(pAcFld,_T("%%<\\AcObjProp Object(%%<\\_ObjId %d>%%).TextString>%%"),pAttItr->objectId().asOldId());
						
						pHdrRw->insert(Char_Pair(pAtt->tag(),pAcFld));
					}
					else
					{
						pHdrRw->insert(Char_Pair(pAtt->tag(),pAtt->textString()));
					}
					pAtt->close();
				}

				pAttItr->step();
			}
			
			// Note start filling in from index 2 as we already filled the first two column data
			for(int nCtr2 = 2; nCtr2 < pHdrData->length();nCtr2++)
			{
				HdrRwMap::const_iterator itr = pHdrRw->begin();
				
				while(!(itr == pHdrRw->end()))
				{
					if(!_tcscmp(itr->first,pHdrData->at(nCtr2))) break;
					itr++;
				}
				
				// Duplicate the string as the pHdrRw will be deleted within this function scope
				TCHAR *pAttText = _tcsdup(itr->second);
				pFldData->append((NULL == pAttText?_T("-"):pAttText));
			}
			
			pRwData->append(pFldData);
			nSlNoCtr++; // Increment the block reference counter
			
			pBlkRef->close(); // Close the block reference
			
			delete pAttItr; // Clean up
			deleteHdrRwMap(pHdrRw);
		}
	}
	
	return Acad::eOk;
}

//-----------------------------------------------------------------------------
//----- Merge cells
Acad::ErrorStatus mergeCellsForTitleAndHeader(AcDbTable *&pTbl, const TCHAR *pBlkName)
{
	// Sanity check
	if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)

	// Merge Title row. Note that when you create table using UI the title row is merged
	// automatically but when adding using API, we will have to explicitly merge the cells
	pTbl->mergeCells(0,0,0,pTbl->numColumns() - 1);
	
	// Merge for showing header
	// Still more sanity check, we will merge third and fourth row
	if (3 > pTbl->numRows()) return Acad::eNotApplicable;

	// Lets add a row and then merge
	pTbl->insertRows(1,pTbl->rowHeight(1));

	// Merge the cells in steps
	pTbl->mergeCells(1,1,0,1);
	pTbl->mergeCells(1,1,2,pTbl->numColumns() - 1);
	
	// Type in the 'Attributes'
	pTbl->setTextString(1,2,_T("Attributes"));
	
	// Show the block in the cell 1,0
	// Set the block id
	AcDbBlockTable *pBT = NULL;
	AcDbBlockTableRecord *pBTR = NULL;

	// Get the block table	
	acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT,AcDb::kForRead);
	// Get the blocktablerecordid
	AcDbObjectId objId;
	pBT->getAt(pBlkName,objId);
	pBT->close();
	
	pTbl->setBlockTableRecordId(1,0,objId,true);
	
	// Lets copy the header rows properties to the third row
	// since we cannot specify a row to be a header row
	AcCmColor col = pTbl->contentColor(AcDb::kHeaderRow);
	AcDbObjectId objID =  pTbl->textStyle(AcDb::kHeaderRow);
	double nHt = pTbl->textHeight(AcDb::kHeaderRow);
	
	for(int nCtr1 = 0;nCtr1 < pTbl->numColumns(); nCtr1++)
	{
		pTbl->setContentColor(2,nCtr1,col);
		pTbl->setTextStyle(objID);
		pTbl->setTextHeight(nHt);
	}	
	
	pTbl->recomputeTableBlock();
	
	return Acad::eOk;
}

//-----------------------------------------------------------------------------
//----- Fit column width with text width
Acad::ErrorStatus fitColumnWidth(AcDbTable *&pTbl,double maxWidth)
{
	// Sanity check
	if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)

	for(int nCtr1 = 0;nCtr1 < pTbl->numColumns();nCtr1++)
	{
		double nWidth;
		for(int nCtr2 = 2;nCtr2 < pTbl->numRows();nCtr2++) // Include the second header row
		{
			// Get the textstyle for the data cells
			AcGiTextStyle txtStyle;
			fromAcDbTextStyle(txtStyle,pTbl->textStyle(nCtr2,nCtr1));
			txtStyle.setTextSize(pTbl->textHeight(nCtr2,nCtr1));
			
			// Get the text width
			AcGePoint2d pt = txtStyle.extents(pTbl->textString(nCtr2,nCtr1),Adesk::kTrue,-1,Adesk::kFalse);
			
			if (2 == nCtr2)	
				nWidth = pt.x; 
			else 
				nWidth = (pt.x > nWidth?pt.x:nWidth);	
		}
		
		// Set the column width as we should have the widest width by now
		pTbl->setColumnWidth(nCtr1,(nWidth > maxWidth?maxWidth:nWidth) * 1.2);
	}	
	
	pTbl->recomputeTableBlock();
		
	return Acad::eOk;
}

//-----------------------------------------------------------------------------
//----- Fit row height with text height
Acad::ErrorStatus fitRowHeight(AcDbTable *&pTbl,double maxHeight)
{
	// Sanity check
	if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)

		for(int nCtr1 = 0;nCtr1 < pTbl->numRows();nCtr1++) // Include all the rows
		{
			double nHeight = pTbl->textHeight(nCtr1,0); // Height of the first column
			for(int nCtr2 = 1;nCtr2 < pTbl->numColumns();nCtr2++) 
			{
				// Get the text height for this cell
				double nCurHeight = pTbl->textHeight(nCtr1,nCtr2);
				nHeight = (nCurHeight > nHeight?nCurHeight:nHeight);	
			}

			// Set the row height with the maximum height
			pTbl->setRowHeight(nCtr1,(nHeight > maxHeight?maxHeight:nHeight) * 3);
		}	

		pTbl->recomputeTableBlock();

		return Acad::eOk;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -