简介数据库基本操作演示说明操作函数符号表说明通用的遍历及操作遍历各种符号表字典的遍历方式操作符号表及实体对象代码:
简介

此实例将演示如何获取图纸上常用的一些信息,如符号表(块表、层表、文字样式表、线型表、点样式表)、字典,演示程序在MxDraw52\Src\MxDraw5.2\samples\Tech-Database目录下即可编译运行, 运在行如下图:


1.png

数据库基本操作

首先我们得到当前活动的数据库,有三种方式,具体代码如下:


    方式1: MxDraw::GetDatabase(MxDraw::GetCurOcxHandle());

    方式2: acdbHostApplicationServices()->workingDatabase();

    方式3: pDatabase = Mx::mcdbCurDwg();


再为当前的数据库添加一些内容,如在图上添加一些实体、图层、块引用,或者使用数据库来读取图纸,如:


Mcad::ErrorStatus readDwgFile(
LPCTSTR pszFileName,    // DWG文件路径
int shmode = 0x40,    // 暂没有使用
bool bAllowCPConversion = false, // 暂没有使用
LPCTSTR wszPassword = NULL,  // 暂没有使用
int rc = Mcad::kReadAll,   //    指定需要读取的内容,不需要读取的内容可以不读取,这样能提高读取dwg文件的速度,可以取如下值:
byte* pInData  = NULL,   // 如果从内存打开文件,pInData指向内存数据。
long lInDataLength =0   // 内存数据的长度。
 
);


或者使用下图中红框内的按钮或命令来打开:

2.png

以上操作等同于这段命令:


    acDocManager->sendStringToExecute(pDatabase->GetDocument(), L"OpenDwg");

得到当前数据库的文件名:


    Mx::mcdbCurDwg()->GetDocument()->fileName();


获取所有块并获取块中的所有实体信息:


//获取块表的一些信息
{
McDbBlockTable * pBlockTable = nullptr;
pDatabase->getBlockTable(pBlockTable, McDb::kForRead);
OnInitBlockTable(pBlockTable, hRootDatabase);
}
void CMxDatabaseDlg::OnInitBlockTable(McDbBlockTable * pBlockTable, HTREEITEM pRootDatabase)
{
McDbBlockTableIterator* pIterator = nullptr;
McDbBlockTableRecordIterator * pEntIt = nullptr;
HTREEITEM pTreeBlockTable = nullptr;
HTREEITEM pTreeBlock = nullptr;
McDbObjectPointer<AcDbEntity> spEntity;
McDbBlockTableRecordPointer spBlkRec;
McDbObjectId tempId;
CString sBlockName;
CString sTemp;
 
pBlockTable->newIterator(pIterator);
std::auto_ptr<McDbBlockTableIterator> spIterator(pIterator);
if (pIterator == NULL)
return;
else
{
pTreeBlockTable = m_DatabaseInfo.InsertItem(L"块表", pRootDatabase);//将块表挂载到当前数据库下
 
for (; !pIterator->done(); pIterator->step())
{
pIterator->getRecordId(tempId);//获取块ID
sBlockName = MrxDbgUtils::getSymbolTableRecordName(tempId);//获取块名称
sTemp.Format(_T(FORMAT), sBlockName, tempId.asOldId());
pTreeBlock = m_DatabaseInfo.InsertItem(sTemp, pTreeBlockTable);//将当前的块挂载到当前的块表下
 
   //读取块信息
spBlkRec.open(tempId, McDb::kForRead);
if (spBlkRec.openStatus() == Mcad::eOk)
{
spBlkRec->newIterator(pEntIt);
std::auto_ptr<McDbBlockTableRecordIterator> spIterator(pEntIt);
for (; !pEntIt->done(); pEntIt->step())
{
pEntIt->getEntityId(tempId);
spEntity.open(tempId, McDb::kForRead);
if (spEntity.openStatus() == Mcad::eOk)
{
sTemp.Format(_T(FORMAT), spEntity->appName(), tempId.asOldId());
m_DatabaseInfo.InsertItem(sTemp, pTreeBlock);//将当前实体的类型与ID挂在到当前块下
}
}
}
}
}
}


下面将获取层表、文字样式表、线型表、点样式表的信息,因为在获取信息的方式上方法极其相似,所以我们使用模板函数来完成:


//Iterator   - 迭代器
//TableRec   - 表记录
//McDbTable   - 表
template<typename Iterator, typename TableRec, typename McDbTable>
inline void CMxDatabaseDlg::CommonInitFunc(const wchar_t *  sTableName, McDbTable pTable, HTREEITEM pRootDatabase)
{
Iterator * pIterator = nullptr;
HTREEITEM pTreeTable = nullptr;
McDbObjectPointer<TableRec> spTempRec;
McDbObjectId tempId;
CString sTemp;
CString pszName;
//////////////////////////////////////////////////////////////////////////
 
//创建一个遍历器,准备遍历块表
pTable->newIterator(pIterator);
std::auto_ptr<Iterator> spIterator(pIterator);//该迭代器的生命周期绑定到智能指针
 
if (pIterator)
{
pTreeTable = m_DatabaseInfo.InsertItem(sTableName, pRootDatabase);//将层表挂载到当前数据库下
  //遍历所有记录
for (; !pIterator->done(); pIterator->step())
{
pIterator->getRecordId(tempId);
 
//读方式打开记录
spTempRec.open(tempId, McDb::kForRead);
if (Mcad::eOk == spTempRec.openStatus())
{
spTempRec->getNameEx(pszName);
sTemp.Format(_T(FORMAT), pszName, tempId.asOldId());
m_DatabaseInfo.InsertItem(sTemp, pTreeTable);//将层表挂载到当前数据库下
}
}
}
}


然后我们分别调用来获取信息:


//获取层表的一些信息
{
McDbLayerTable* pLayerTable = nullptr;
pDatabase->getLayerTable(pLayerTable, McDb::kForRead);
CommonInitFunc<McDbLayerTableIterator, McDbLayerTableRecord, McDbLayerTable*>(L"层表", pLayerTable, hRootDatabase);
}
 
//获取文字样式的一些信息
{
McDbTextStyleTable * pTextStyleTable = nullptr;
pDatabase->getTextStyleTable(pTextStyleTable, McDb::kForRead);
CommonInitFunc<McDbTextStyleTableIterator, McDbTextStyleTableRecord, McDbTextStyleTable*>(L"文字样式表", pTextStyleTable, hRootDatabase);
}
 
//获取线型的一些信息
{
McDbLinetypeTable * pLinetypeTable = nullptr;
pDatabase->getLinetypeTable(pLinetypeTable, McDb::kForRead);
CommonInitFunc<McDbLinetypeTableIterator, McDbLinetypeTableRecord, McDbLinetypeTable*>(L"线型表", pLinetypeTable, hRootDatabase);
}
 
//获取点样式的一些信息
{
McDbDimStyleTable * pDimStyleTable = nullptr;
pDatabase->getDimStyleTable(pDimStyleTable, McDb::kForRead);
CommonInitFunc<McDbDimStyleTableIterator, McDbDimStyleTableRecord, McDbDimStyleTable*>(L"点样式表", pDimStyleTable, hRootDatabase);
}



下面将获取字典下的一些信息:


//获取字典的一些信息
{
McDbDictionary * pDictionary = nullptr;
pDatabase->getNamedObjectsDictionary(pDictionary, McDb::kForRead);
hRootDatabase = m_DatabaseInfo.InsertItem(L"字典", hRootDatabase);//将信息挂载到当前数据库下
OnInitDictionary(pDictionary, hRootDatabase);
}
void CMxDatabaseDlg::OnInitDictionary(McDbDictionary * pDictionary, HTREEITEM pRootDatabase)
{
AcDbDictionaryIterator * pIterator = nullptr;
HTREEITEM pSaleNode = nullptr;
McDbObjectId tempId;
LPCTSTR pTemp;
CString sTemp;
CString sAppName;
 
//获取指点迭代器
pIterator = pDictionary->newIterator();
std::auto_ptr<AcDbDictionaryIterator> spIterator(pIterator);
 
const CString sMcDbDictionary(L"McDbDictionary");
const CString sMcDbLayout(L"McDbLayout");
const CString sMcDbMlineStyle(L"McDbMlineStyle");
 
if (pIterator)
{
for (; !pIterator->done(); pIterator->next())
{
AcDbObject* pObj = NULL;
if (pIterator->getObject(pObj, AcDb::kForRead) == Acad::eOk)
{
sAppName = pObj->isA()->name();
sTemp.Format(_T(FORMAT), sAppName, pObj->objectId().asOldId());
pSaleNode = m_DatabaseInfo.InsertItem(sAppName, pRootDatabase);//将信息挂载到当字典下
if (sMcDbDictionary == sAppName)
{
OnInitDictionary(McDbDictionary::cast(pObj), pSaleNode);
}
else if (sMcDbLayout == sAppName)
{
auto pLayout = McDbLayout::cast(pObj);
pLayout->getLayoutName(pTemp);
m_DatabaseInfo.InsertItem(sTemp, pSaleNode);//将信息挂载到当字典下
}
else if (sMcDbMlineStyle == sAppName)
{
m_DatabaseInfo.InsertItem(sMcDbMlineStyle, pSaleNode);//将信息挂载到当字典下
}
}
}
}
}
演示说明

此实例将演示如何获取图纸上常用的一些信息,如符号表(块表、层表、文字样式表、线型表、点样式表)、字典,演示程序运行如下图:

4.png

 

我们打开一张图纸用作测试,首先我们得到当前活动的数据库,对于获取当前的数据库,我们可以使用如下的几种方式:

//获得当前的数据库

McDbDatabase * pDatabase = nullptr;

{

MxDraw::GetDatabase(MxDraw::GetCurOcxHandle());  //1方式

acdbHostApplicationServices()->workingDatabase(); //2方式

pDatabase = Mx::mcdbCurDwg();      //3方式

}

再为当前的数据库添加一些内容,如在图上添加一些实体、图层、块引用,或者使用数据库来读取图纸,比如调用:

Mcad::ErrorStatus readDwgFile(

LPCTSTR pszFileName,    - DWG文件路径

int shmode = 0x40,    - 暂没有使用

bool bAllowCPConversion = false, - 暂没有使用

LPCTSTR wszPassword = NULL,  - 暂没有使用

int rc = Mcad::kReadAll,   -    指定需要读取的内容,不需要读取的内容可以不读取,这样能提高读取dwg文件的速度,可以取如下值:

byte* pInData  = NULL,   - 如果从内存打开文件,pInData指向内存数据。

long lInDataLength =0   - 内存数据的长度。

 

);    

或者使用如下命令来打开图纸文件:

acDocManager->sendStringToExecute(pDatabase->GetDocument(), L"OpenDwg");

此方式将以选择文件的方式来打开图纸,如图:

5.png


操作函数

得到当前数据库的文件名,在我们的当前数据库加载进数据之后,我们测试提取一些信息,比如获得文件名:


 //获得文件名
    HTREEITEM hRootDatabase = nullptr;
    {
     auto sFileName = Mx::mcdbCurDwg()->GetDocument()->fileName();
   
     //长度为零则返回
     if (!wcslen(sFileName))
      return FALSE;
   
     hRootDatabase = m_DatabaseInfo.InsertItem(sFileName);
    }


下面将介绍如何获取个符号表的一些信息,如下图:


图片3.png

符号表说明

在数据库下包含了各种符号表与一个字典。符号表的在控件的类声明如下:

// -------------------------------------------------------------------------

// Summary:

//  McDbSymbolTable是控件的内建符号表的所有类的基类

// -------------------------------------------------------------------------

class ARXDLL McDbSymbolTable : public McDbObject  

而在符号变中,我们使用获取迭代器的接口来获取一个迭代器,接口如下:

// -------------------------------------------------------------------------

// Summary:

//  创建一个遍历器对象,用于遍历SymbolTable中的内容,在不使用时调用delete释放内存

// Parameters:

//  pIterator - 新创建的遍历器的指针

//  atBeginning - 输入布尔值,表示从表的开始处或结束处开始

//  skipDeleted - 输入布尔值,表示是否忽略已删除的记录

// Returns:

//  如果成功返回Mcad::eOk

// -------------------------------------------------------------------------

    Mcad::ErrorStatus newIterator(McDbSymbolTableIterator*& pIterator,

                                  bool atBeginning = true,

                                  bool skipDeleted = true);

而在迭代器中,我们将获取到符号表记录,符号表记录类声明如下:

// -------------------------------------------------------------------------

// Summary:

//  符号表记录型类型,是不同符号表的记录的基类

// -------------------------------------------------------------------------

class ARXDLL McDbSymbolTableRecord : public  McDbObject在控件中,已有的符号表包括:

McDbBlockTable  - 块表

McDbLayerTable  - 层表

McDbTextStyleTable - 文字样式表

McDbLinetypeTable  - 线性表

McDbDimStyleTable  - 标注样式表

他们都继承自上文的符号表(McDbSymbolTable ),而它们各自的获取迭代器接口(newIterator)中,迭代器可获取各自对应的表记录(McDbSymbolTableRecord 

通用的遍历及操作

对于符号表记录,在各种类型中对应不同的内容,在实例中将体现出来,在此实例中,我们将使用一个模板函数进行对于各个符号表进行读取数据并将他们的句柄挂载至树形结构图,该函数实现如下:


template<
typename IteratorType,
typename Value,
typename Container
>
 
 
void CMxDatabaseDlg::CommonInitFunc(
Container * pContainer,
std::function<void(Value*, HTREEITEM)> func,
HTREEITEM pParentNode)
{
IteratorType * pIterator = nullptr;
McDbObjectPointer<Value> spValue;
McDbObjectId mValueId;
HTREEITEM pNode = nullptr;
HTREEITEM pNextNode = nullptr;
CString sFormatTemp;
 
//将当前的表挂载至控件
if (pParentNode)
pNode = m_DatabaseInfo.InsertItem(pContainer->isA()->name(), pParentNode);
else
pNode = m_DatabaseInfo.InsertItem(pContainer->isA()->name());
 
//创建一个遍历器,准备遍历块表
pContainer->newIterator(pIterator);
std::auto_ptr<IteratorType> spIterator(pIterator);//该迭代器的生命周期绑定到智能指针
 
if (pIterator)
{
//遍历所有记录
for (; !pIterator->done(); pIterator->step())
{
//获取ID
pIterator->getRecordId(mValueId);
 
//打开表
spValue.open(mValueId, McDb::kForRead);
 
//获取符号表名
CString sTableName;
{
//1方式
spValue->getNameEx(sTableName);
//2方式
sTableName = MrxDbgUtils::getSymbolTableRecordName(mValueId);
}
 
//获取句柄
TCHAR szHandle[256] = {};
{
McDbHandle hTableRechandle;
spValue->getAcDbHandle(hTableRechandle);
hTableRechandle.getIntoAsciiBuffer(szHandle);
}
 
//格式化字符串
sFormatTemp.Format(FORMAT, szHandle, sTableName);
//将层表挂载到当前数据库下
pNextNode = m_DatabaseInfo.InsertItem(sFormatTemp, pNode);
 
//上述代码是将符号记录表通用信息加载至控件,使用以下函数附加操作
func(spValue.object(), pNextNode);
}
}
}
 
template<>
inline void CMxDatabaseDlg::CommonInitFunc<
McDbBlockTableRecordIterator,
McDbEntity,
McDbBlockTableRecord
>(
McDbBlockTableRecord * pTable,
std::function<void(McDbEntity*, HTREEITEM)> func,
HTREEITEM pParentNode)
{
McDbBlockTableRecordIterator * pIterator = nullptr;
McDbObjectPointer<McDbEntity> spValue;
McDbObjectId mValueId;
CString sFormatTemp;
 
//创建一个遍历器,准备遍历块表
pTable->newIterator(pIterator);
std::auto_ptr<McDbBlockTableRecordIterator> spIterator(pIterator);//该迭代器的生命周期绑定到智能指针
 
if (pIterator)
{
//遍历所有记录
for (; !pIterator->done(); pIterator->step())
{
//获取ID
pIterator->getEntityId(mValueId);
 
//打开表
spValue.open(mValueId, McDb::kForRead);
 
//获取句柄
TCHAR szHandle[256] = {};
{
McDbHandle hTableRechandle;
spValue->getAcDbHandle(hTableRechandle);
hTableRechandle.getIntoAsciiBuffer(szHandle);
}
 
//格式化字符串
sFormatTemp.Format(FORMAT, szHandle, spValue->isA()->name());
//将层表挂载到当前数据库下
m_DatabaseInfo.InsertItem(sFormatTemp, pParentNode);
}
}
}
遍历各种符号表

对于每个符号表,我们进行如下调用:


//获取块表的一些信息
{
McDbBlockTable * pBlockTable = nullptr;
pDatabase->getBlockTable(pBlockTable, McDb::kForRead);
CommonInitFunc<McDbBlockTableIterator, McDbBlockTableRecord, McDbBlockTable>(
pBlockTable, [&](McDbBlockTableRecord * pTableRec, HTREEITEM pTreeTable) {
this->CommonInitFunc<
McDbBlockTableRecordIterator,
McDbEntity,
McDbBlockTableRecord>(
pTableRec,
[](McDbEntity*, HTREEITEM) {},
pTreeTable);
});
}
 
//获取层表的一些信息
{
McDbLayerTable* pLayerTable = nullptr;
pDatabase->getLayerTable(pLayerTable, McDb::kForRead);
CommonInitFunc<McDbLayerTableIterator, McDbLayerTableRecord, McDbLayerTable>(
pLayerTable, [&](McDbLayerTableRecord *, HTREEITEM) {});
}
 
//获取文字样式的一些信息
{
McDbTextStyleTable * pTextStyleTable = nullptr;
pDatabase->getTextStyleTable(pTextStyleTable, McDb::kForRead);
CommonInitFunc<McDbTextStyleTableIterator, McDbTextStyleTableRecord, McDbTextStyleTable>(
pTextStyleTable, [&](McDbTextStyleTableRecord *, HTREEITEM) {});
}
 
//获取线型的一些信息
{
McDbLinetypeTable * pLinetypeTable = nullptr;
pDatabase->getLinetypeTable(pLinetypeTable, McDb::kForRead);
CommonInitFunc< McDbLinetypeTableIterator, McDbLinetypeTableRecord, McDbLinetypeTable>(
pLinetypeTable, [&](McDbLinetypeTableRecord *, HTREEITEM) {});
}
 
//获取标注样式的一些信息
{
McDbDimStyleTable * pDimStyleTable = nullptr;
pDatabase->getDimStyleTable(pDimStyleTable, McDb::kForRead);
CommonInitFunc<McDbDimStyleTableIterator, McDbDimStyleTableRecord, McDbDimStyleTable>(
pDimStyleTable, [&](McDbDimStyleTableRecord *, HTREEITEM) {});
}
字典的遍历方式

可以看到的是,除了块表,其他的符号表下只包含各自的记录表,而块表下包含块表记录,块表记录下包含了块,块下包含了一些实体,其中也包括块引用。而对于字典,我们使用初始化符号表的特化模板函数进行初始化,该函数实现如下:


template<>
inline void CMxDatabaseDlg::CommonInitFunc<
McDbDictionaryIterator,
McDbObject,
McDbDictionary
>(
McDbDictionary * pDictionary,
std::function<void(McDbObject*, HTREEITEM)> func,
HTREEITEM pParentNode)
{
McDbDictionaryIterator * pIterator = nullptr;
McDbObjectPointer<McDbObject> spValue;
McDbObjectId mValueId;
CString sFormatTemp;
HTREEITEM pNode = nullptr;
HTREEITEM pNextNode = nullptr;
 
//将当前的表挂载至控件
if (pParentNode)
pNode = m_DatabaseInfo.InsertItem(pDictionary->isA()->name(), pParentNode);
else
pNode = m_DatabaseInfo.InsertItem(pDictionary->isA()->name());
 
pIterator = pDictionary->newIterator();
std::auto_ptr<McDbDictionaryIterator> spIterator(pIterator);//该迭代器的生命周期绑定到智能指针
if (pIterator == NULL)
return;
 
for (; !pIterator->done(); pIterator->next())
{
mValueId = pIterator->objectId();
spValue.open(mValueId, McDb::kForRead);
 
//获取句柄
TCHAR szHandle[256] = {};
{
McDbHandle hTableRechandle;
spValue->getAcDbHandle(hTableRechandle);
hTableRechandle.getIntoAsciiBuffer(szHandle);
}
 
//格式化字符串
sFormatTemp.Format(FORMAT, szHandle, spValue->isA()->name());
//将当前内容挂载到当前数据库下
pNextNode = m_DatabaseInfo.InsertItem(sFormatTemp, pNode);
 
func(spValue.object(), pNextNode);
}
}


调用函数的代码如下:


//获取字典的一些信息
{
std::function<void(McDbObject*, HTREEITEM)> func;
func = [&](McDbObject* pMcDbObject, HTREEITEM pTreeTable) {
const CString sType = pMcDbObject->isA()->name();
const CString sMcDbDictionary(L"McDbDictionary");
if (sMcDbDictionary == sType)
{
this->CommonInitFunc<McDbDictionaryIterator, McDbObject, McDbDictionary>(
McDbDictionary::cast(pMcDbObject), func, pTreeTable);
}
};
 
McDbDictionary * pDictionary = nullptr;
pDatabase->getNamedObjectsDictionary(pDictionary, McDb::kForRead);
CommonInitFunc<McDbDictionaryIterator, McDbObject, McDbDictionary>(
pDictionary, func);
}
操作符号表及实体对象

至此,我们就读取到当前模型空间的所有符号表及字典,而对于如何取到具体的信息,我们在此实例的树形结构图的单击事件下进行读取,代码如下:


void CMxDatabaseDlg::OnTvnSelchangedDatabaseinfoTree(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
*pResult = 0;
 
CString strText; // 树节点的标签文本字符串   
 
 // 获取当前选中节点的句柄   
HTREEITEM hItem = m_DatabaseInfo.GetSelectedItem();
strText = m_DatabaseInfo.GetItemText(hItem);
GetObjectAndPring(strText);
}
 
void CMxDatabaseDlg::GetObjectAndPring(const CString sHandle)
{
//在此处我们得到所需的一些信息
McDbObjectPointer<McDbObject> spObject;
{
McDbObjectId mId;
McDbHandle mHandle(GetHandleStr(sHandle));
acdbHostApplicationServices()->workingDatabase()->getAcDbObjectId(mId, false, mHandle);
spObject.open(mId, McDb::kForRead);
}
 
if (Mcad::eOk == spObject.openStatus())
{
CString sTemp;
CString sType = spObject->isA()->name();
sTemp.Format(_T("\n类型:%s\t组码名:%s\nID:%d"), spObject->isA()->name(), spObject->isA()->DXF0(), spObject->objectId().asOldId());
Mx::mcutPrompt(sTemp);
sTemp.Format(_T("\t句柄:%s"), GetHandleStr(sHandle));
Mx::mcutPrompt(sTemp);
 
//  MrxDbgUtils::putEntityInView(spObject->objectId(), 10);
 
//符号表
if (McDbSymbolTableRecord::cast(spObject))
{
auto pDisSymUtilInfo = [&](McDbSymbolTableRecord* pMcDbSymbolTable) {
CString sName;
pMcDbSymbolTable->getNameEx(sName);
sTemp.Format(_T("\n符号记录表名:%s"), sName);
Mx::mcutPrompt(sTemp);
};
 
const CString sMcDbLayerTableRecord(L"McDbLayerTableRecord");
const CString sMcDbBlockTableRecord(L"McDbBlockTableRecord");
const CString sMcDbTextStyleTableRecord(L"McDbTextStyleTableRecord");
const CString sMcDbLinetypeTableRecord(L"McDbLinetypeTableRecord");
const CString sMcDbDimStyleTableRecord(L"McDbDimStyleTableRecord");
 
if (sMcDbLayerTableRecord == sType)
{
auto pEnt = McDbLayerTableRecord::cast(spObject);
pDisSymUtilInfo(pEnt);
sTemp.Format(_T("\n锁定状态:%s\t关闭状态:%s\n冻结状态:%s"), pEnt->isLocked() ? L"锁定" : L"未锁定",
pEnt->isOff() ? L"关闭" : L"未关闭", pEnt->isFrozen() ? L"冻结" : L"未冻结");
Mx::mcutPrompt(sTemp);
auto mColor = pEnt->color();
sTemp.Format(_T("\t颜色索引%d"), mColor.colorIndex());
Mx::mcutPrompt(sTemp);
}
else if (sMcDbTextStyleTableRecord == sType)
{
auto pEnt = McDbTextStyleTableRecord::cast(spObject);
pDisSymUtilInfo(pEnt);
LPCTSTR lpFileName;
pEnt->fileName(lpFileName);
sTemp.Format(_T("\n竖向绘制:%s\t文字高度:%f\t缩放比例:%f\t倾斜弧度%f\t字体文件名:%s"), pEnt->isVertical() ? L"是" : L"否",
pEnt->textSize(), pEnt->xScale(), pEnt->obliquingAngle(), lpFileName);
Mx::mcutPrompt(sTemp);
//...在此处介绍其他的信息
}
else if (sMcDbLinetypeTableRecord == sType)
{
auto pEnt = McDbLinetypeTableRecord::cast(spObject);
pDisSymUtilInfo(pEnt);
CString sCommentsEx;
pEnt->commentsEx(sCommentsEx);
sTemp.Format(_T("\n线型说明:%s"), sCommentsEx);
Mx::mcutPrompt(sTemp);
//...在此处介绍其他的信息
}
else if (sMcDbDimStyleTableRecord == sType)
{
auto pEnt = McDbDimStyleTableRecord::cast(spObject);
pDisSymUtilInfo(pEnt);
//...在此处介绍其他的信息
}
else if (sMcDbBlockTableRecord == sType)
{
auto pEnt = McDbBlockTableRecord::cast(spObject);
pDisSymUtilInfo(pEnt);
//...在此处介绍其他的信息
}
Mx::mcutPrompt(L"\n");
}
else if (auto spEnt = McDbEntity::cast(spObject))
{
auto pDisText = [&](McGePoint3d vPt, double dRotation, double dHeight, double dWidth, CString sText, CString sStyle) {
const CString sTextInfoFormat(L"\n文字位置:X = %.3lf Y = %.3lf\n旋转弧度%f\t行高%f\t宽度比例%f\n文字内容:%s\n文字样式%s\n");
sTemp.Format(sTextInfoFormat, vPt.x, vPt.y, dRotation,
dHeight, dWidth, sText, sStyle);
Mx::mcutPrompt(sTemp);
};
 
//基本实体
sTemp.Format(_T("\n层名:%s\t颜色索引:%d"), spEnt->layer(), spEnt->colorIndex());
Mx::mcutPrompt(sTemp);
 
const CString sMcDbLine(L"McDbLine");
const CString sMcDbPolyline(L"McDbPolyline");
const CString sMcDbArc(L"McDbArc");
const CString sMcDbCircle(L"McDbCircle");
const CString sMcDbSpline(L"McDbSpline");
const CString sMcDbEllipse(L"McDbEllipse");
const CString sMcDbPoint(L"McDbPoint");
const CString sMcDbBlockReference(L"McDbBlockReference");
const CString sMcDbAttributeDefinition(L"McDbAttributeDefinition");
const CString sMcDbText(L"McDbText");
const CString sMcDbMText(L"McDbMText");
const CString sMcDbHatch(L"McDbHatch");
const CString sMcDbDimension(L"McDbDimension");
 
if (sMcDbLine == sType)
{
auto pEnt = McDbLine::cast(spEnt);
auto vPt1 = pEnt->startPoint();
sTemp.Format(_T("\n起始点:X = %.3lf Y = %.3lf"), vPt1.x, vPt1.y);
Mx::mcutPrompt(sTemp);
auto vPt2 = pEnt->endPoint();
sTemp.Format(_T("\n结束点:X = %.3lf Y = %.3lf"), vPt2.x, vPt2.y);
Mx::mcutPrompt(sTemp);
sTemp.Format(_T("\n增量:X = %.3lf 增量Y = %.3lf"), vPt2.x - vPt1.x, vPt2.y - vPt1.y);
Mx::mcutPrompt(sTemp);
}
else if (sMcDbPoint == sType)
{
auto pEnt = McDbPoint::cast(spEnt);
auto vPt = pEnt->position();
sTemp.Format(_T("\n点:X = %.3lf Y = %.3lf"), vPt.x, vPt.y);
Mx::mcutPrompt(sTemp);
}
else if (sMcDbPolyline == sType)
{
auto pEnt = McDbPolyline::cast(spEnt);
sTemp.Format(_T("\n是否闭合%s"), pEnt->isClosed() ? L"闭合" : L"不闭合");
Mx::mcutPrompt(sTemp);
 
McGePoint2d vPt;
for (UINT i(0); i < pEnt->numVerts(); i++)
{
pEnt->getPointAt(i, vPt);
sTemp.Format(_T("\n点:X = %.3lf Y = %.3lf"), vPt.x, vPt.y);
Mx::mcutPrompt(sTemp);
}
}
代码:
else if (sMcDbText == sType)
{
auto pEnt = McDbText::cast(spEnt);
pDisText(pEnt->position(), pEnt->rotation(), pEnt->height(),
pEnt->widthFactor(), pEnt->textStringConst(), pEnt->textStyleEx());
}
else if (sMcDbMText == sType)
{
auto pEnt = McDbMText::cast(spEnt);
pDisText(pEnt->location(), pEnt->rotation(),
pEnt->textHeight(), pEnt->width(), pEnt->contents(), pEnt->textStyleEx());
}
else if (sMcDbCircle == sType)
{
auto pEnt = McDbCircle::cast(spEnt);
auto vCenter = pEnt->center();
sTemp.Format(_T("\n圆心:X = %.3lf Y = %.3lf"), vCenter.x, vCenter.y);
Mx::mcutPrompt(sTemp);
auto dRadius = pEnt->radius();
sTemp.Format(_T("\n半径:%f"), dRadius);
Mx::mcutPrompt(sTemp);
}
else if (sMcDbArc == sType)
{
auto pEnt = McDbArc::cast(spEnt);
auto vCenter = pEnt->center();
sTemp.Format(_T("\n圆心:X = %.3lf Y = %.3lf"), vCenter.x, vCenter.y);
Mx::mcutPrompt(sTemp);
auto dRadius = pEnt->radius();
sTemp.Format(_T("\n半径:%f"), dRadius);
Mx::mcutPrompt(sTemp);
auto dstartAngle = pEnt->startAngle();
sTemp.Format(_T("\n起始角度:%f"), dstartAngle);
Mx::mcutPrompt(sTemp);
auto dendAngle = pEnt->endAngle();
sTemp.Format(_T("\n结束角度:%f"), dendAngle);
Mx::mcutPrompt(sTemp);
}
else if (sMcDbBlockReference == sType)
{
auto pEnt = McDbBlockReference::cast(spEnt);
auto sName = pEnt->appName();
sTemp.Format(_T("\n块名:%s"), sName);
Mx::mcutPrompt(sTemp);
auto vPosition = pEnt->position();
sTemp.Format(_T("\n插入位置:X = %.3lf Y = %.3lf"), vPosition.x, vPosition.y);
Mx::mcutPrompt(sTemp);
auto dScale = pEnt->scaleFactors();
sTemp.Format(_T("\n缩放比例:%f"), dScale);
Mx::mcutPrompt(sTemp);
auto drotationAngle = pEnt->rotation();
sTemp.Format(_T("\n旋转角度:%f"), drotationAngle);
Mx::mcutPrompt(sTemp);
}
else if (sMcDbDimension == sType)
{
//标注类型
}
Mx::mcutPrompt(L"\n");
}
else
{
Mx::mcutPrompt(L"未说明的类型\n");
Mx::mcutPrompt(L"\n");
}
}
}


对于获取实体信息,重点在于获取它的句柄或ID,我们可用通过选择及或构造选择集的方式去过滤,也可以使用与用户交互的方式去选择需要的实体,而获取ID之后,我们使用以下的方式去打开,即可获取它的全部相关信息,如得到它的类型、DXF组码名。


McDbObjectPointer<McDbObject> spObject;
{
//...
spObject.open(mId, McDb::kForRead);
}
 
if (Mcad::eOk == spObject.openStatus())
{
CString sTemp;
CString sType = spObject->isA()->name();
}
MxDraw
MxDraw是由梦想凯德基于AutoDesk CAD平台开发的软件,拥有完全自主的核心技术和知识产权。MxDraw致力于为各企业提供最优秀的CAD平台整体解决方案。
技术服务
TEL:400-888-5703
185-8173-1060
QQ:827867134,6884123
产品购买
TEL:400-888-5703
185-8173-1060
QQ:827867134,6884123
用户交流
QQ群1:827867134
QQ群2:827867134
QQ群3:827867134