1. 说明

       本篇演示了创建新的层表记录、删除已有的层表记录、使用“颜色”对话框设置某一图层的颜色,以及导出和导入所有图层及特性的方法,基本涵盖了所有的层表操作。
2. 思路
        创建新的图层,实际上就是创建一个新的层表记录,并将其添加到层表中。
修改图层的颜色,可以从层表中获得指定的记录,然后使用 AcDbLayerTableRecord 类的setColor 函数设置层表记录的颜色。

        删除一个图层,需要首先从层表中获得指定的层表记录,然后将层表记录设置一个“删除”的标记。

        导出图层列表和图层特性,需要使用层表遍历器访问每一个层表记录,将层表记录的名称、颜色、线型和线宽以“,”作分隔符连接成一个 CString 类型的字符串对象,然后使用 CStdioFile 类的 WriteString 函数写入到文本文件中。
        导入图层列表的步骤和导出的步骤完全相反,先使用 CstdioFile 类的 ReadString 函数逐行读取文本文件的内容,以“,”作分隔符解析出图层名称、颜色、线型和线宽,并在当前图形中加入这些图层。
3. 步骤
(1) 新建一个 CLayerOper 类, 添加 NewLayer 函数
        由于要在块表中添加新的块表记录,在获得块表的时候需要将其以“写”模式打开,对
应于代码中就是在 getLayerTable 函数中使用了 AcDb::kForWrite 参数。向块表添加新的记录
之前,可以使用 has 函数判断图形中是否已经包含了同名的层。

    //新建图层static void NewLayer(); //新建图层
//新建图层
void CLayerOper::NewLayer()
{// 提示用户输入新建图层的名称TCHAR layerName[100];if (acedGetString(Adesk::kFalse, _T("\n输入新图层的名称:"), layerName) != RTNORM) { return;} // 获得当前图形的层表AcDbLayerTable *pLayerTbl;acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTbl, AcDb::kForWrite);// 是否已经包含指定的层表记录if (pLayerTbl->has(layerName)) { pLayerTbl->close(); return; } // 创建新的层表记录AcDbLayerTableRecord *pLayerTblRcd; pLayerTblRcd = new AcDbLayerTableRecord(); pLayerTblRcd->setName(layerName); // 将新建的层表记录添加到层表中AcDbObjectId layerTblRcdId; pLayerTbl->add(layerTblRcdId, pLayerTblRcd); //AcDbDatabase 类的 setClayer 函数能够设置图形的当前图层。acdbHostApplicationServices()->workingDatabase()->setClayer(layerTblRcdId); pLayerTblRcd->close(); pLayerTbl->close();
}

(2) 修改指定图层的颜色: 添加新类 CModifyLayer, 添加 ModifyLayerColor 函数

        在获得特定的块表记录指针时,使用了 AcDbLayerTable 类的 getAt 函数,并且使用 AcDb::kForWrite 参数,将块表记录以“写”模式打开。
        AcedSetColorDialog 函数能够弹出 [选择颜色对话框] ,并且返回用户选择的结果,
        AcCmColor 代表颜色对象,可以通过颜色索引来构建一个新的颜色对象。        
       
 该函数定义为:
Adesk::Boolean acedSetColorDialog( int& nColor,  //nColor 参数指定了显示【选择颜色】对话框时的默认颜色,并且在函数返回值后保存用户选择的新颜色Adesk::Boolean bAllowMetaColor,  //bAllowMetaColor 参数限定在【选择颜色】对话框中是否可以选择“随层”或“随块”int nCurLayerColor);             //nCurLayerColor 参数指定当前图层的颜色。AcCmColor //代表颜色对象,可以通过颜色索引来构建一个新的颜色对象。//通过颜色索引,可以将【选择颜色】对话框的结果设置为指定图层的颜色,
其相关代码为:AcCmColor color;
color.setColorIndex(nNewColor);
pLayerTblRcd->setColor(color);
    void ModifyLayerColor(); //修改图层颜色

//修改图层颜色
void CModifyLayer::ModifyLayerColor()
{// 提示用户输入要修改的图层名称TCHAR layerName[100];if (acedGetString(Adesk::kFalse, _T("\n输入图层的名称:"), layerName) != RTNORM){return;}// 获得当前图形的层表AcDbLayerTable *pLayerTbl;acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTbl, AcDb::kForRead);// 判断是否包含指定名称的层表记录if (!pLayerTbl->has(layerName)){pLayerTbl->close();return;}// 获得指定层表记录的指针AcDbLayerTableRecord *pLayerTblRcd;pLayerTbl->getAt(layerName, pLayerTblRcd, AcDb::kForWrite);// 弹出“颜色”对话框AcCmColor oldColor = pLayerTblRcd->color();int nCurColor = oldColor.colorIndex(); // 图层修改前的颜色int nNewColor = oldColor.colorIndex(); // 用户选择的颜色if (acedSetColorDialog(nNewColor, Adesk::kFalse, nCurColor)){AcCmColor color;color.setColorIndex(nNewColor);pLayerTblRcd->setColor(color);}// 关闭pLayerTblRcd->close();pLayerTbl->close();
}

(3) 删除一个数据库对象非常简单:将其以“写”模式打开,调用 AcDbObject 类的 erase 函数,最后关闭该对象

    void DelLayer(); //删除图层

//删除图层
void CModifyLayer::DelLayer()
{// 提示用户输入要修改的图层名称TCHAR layerName[100];if (acedGetString(Adesk::kFalse, _T("\n输入图层的名称:"), layerName) != RTNORM) {return;}// 获得当前图形的层表AcDbLayerTable *pLayerTbl;acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTbl, AcDb::kForRead);// 判断是否包含指定名称的层表记录if (!pLayerTbl->has(layerName)){pLayerTbl->close();return;}// 获得指定层表记录的指针AcDbLayerTableRecord *pLayerTblRcd;pLayerTbl->getAt(layerName, pLayerTblRcd, AcDb::kForWrite);pLayerTblRcd->erase(); // 为其设置“删除”标记pLayerTblRcd->close();pLayerTbl->close();
}

(4) 将当前图形中存在的所有图层及其特性导出到一个文本文件中, 添加函数 ExportLayer()
        CStdioFile 类的 Open 函数能够打开指定位置的文件,这里使用 CFile::modeCreate 作为打开标记,能够在指定的位置创建文件。
        
        最终的结果是将图层的信息以“图层名称,颜色,线型,线宽”格式输出,因此在获得图层的名称和特性之后,关键在于将这些特性组合成一个 CString 类型的变量。所幸,CString 类提供了“+”运算符,能够将两个字符串连接起来组成一个新的字符串,例如:
                strLayerInfo += strLineWeight;
        
        像文件中写入字符串使用了 CStdioFile 类的 WriteString 函数,注意需要单独写入一个换行字符,保证每个图层的特性单独成行。

    void ExportLayer(); //导出图层到文本文档

//导出图层到文本文档
void CModifyLayer::ExportLayer()
{// 创建所要导出的文本文件CStdioFile f;CFileException e;TCHAR *pFileName = _T("C:\\layers.txt");if (!f.Open(pFileName, CFile::modeCreate | CFile::modeWrite, &e)){acutPrintf(_T("\n创建导出文件失败!"));return;}// 获得层表指针AcDbLayerTable *pLayerTbl;AcDbLayerTableRecord *pLayerTblRcd;acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTbl, AcDb::kForRead);// 使用遍历器访问每一条层表记录AcDbLayerTableIterator *pItr;pLayerTbl->newIterator(pItr);for (pItr->start(); !pItr->done(); pItr->step()){pItr->getRecord(pLayerTblRcd, AcDb::kForRead);// 输出图层的信息CString strLayerInfo; // 图层名称TCHAR *layerName;pLayerTblRcd->getName(layerName);strLayerInfo = layerName;free(layerName);strLayerInfo += ","; // 分隔符CString strColor; // 图层颜色AcCmColor color = pLayerTblRcd->color();strColor.Format(_T("%d"), color.colorIndex());strLayerInfo += strColor;strLayerInfo += ",";CString strLinetype; // 图层线型AcDbLinetypeTableRecord *pLinetypeTblRcd;acdbOpenObject(pLinetypeTblRcd, pLayerTblRcd->linetypeObjectId(), AcDb::kForRead);TCHAR *linetypeName;pLinetypeTblRcd->getName(linetypeName);pLinetypeTblRcd->close();strLinetype = linetypeName;free(linetypeName);strLayerInfo += strLinetype;strLayerInfo += ",";CString strLineWeight; // 图层的线宽AcDb::LineWeight lineWeight = pLayerTblRcd->lineWeight();strLineWeight.Format(_T("%d"), lineWeight);strLayerInfo += strLineWeight;// 将图层特性写入到文件中f.WriteString(strLayerInfo);f.WriteString(_T("\n"));pLayerTblRcd->close();}delete pItr;pLayerTbl->close();
}

(5) 按照文本文件中的图层列表在当前图形中创建图层,并且符合图层列表中的各项特性:

        使用 CFile::modeRead 参数调用 CstdioFile 类的 Open 函数,打开指定位置的文本文件,然后使用 ReadString 函数逐行读取文本文件中的内容。
        读取一行文本之后,需要根据分隔符(“,”)来解析出图层的名称、颜色、线型和线宽,使用 GetFieldText 函数来实现.
        Cstring 类提供了一系列用于查找字符或者切割字符串的函数,使得解析字符串变量非常简单。例如: 
        Find 函数能在指定的字符串中查找匹配子串的第一个位置,
        Mid 函数则能解析出指定字符串中指定长度的子串。
       

        该函数的实现代码为:
//解析文本(图层的名称、颜色、线型和线宽)
BOOL GetFieldText(CString strLineText, CStringArray &fields); //解析文本(图层的名称、颜色、线型和线宽)
//解析文本(图层的名称、颜色、线型和线宽)
BOOL CModifyLayer::GetFieldText(CString strLineText, CStringArray &fields)
{if (strLineText.Find(_T(","), 0) == -1) // 如果找不到英文逗号,函数退出{return FALSE;}int nLeftPos = 0, nRightPos = 0; // 查找分隔符的起始位置while ((nRightPos = strLineText.Find(_T(","), nRightPos)) != -1){fields.Add(strLineText.Mid(nLeftPos, nRightPos - nLeftPos));nLeftPos = nRightPos + 1;nRightPos++;}// 最后一个列的数据fields.Add(strLineText.Mid(nLeftPos));return TRUE;
}
        获得某一图层的名称、颜色、线型和线宽之后,就可以创建新的层表记录,并且使用
        setColor 函数设置图层的颜色,
        setLinetypeObjectId 函数设置图层的线型,
        setLineWeight 函数设置图层的线宽。

//从文本文档到导入图层
void ImportLayer(); //从文本文档到导入图层

//从文本文档到导入图层
void CModifyLayer::ImportLayer()
{// 打开所要导入的文本文件CStdioFile f;CFileException e;TCHAR *pFileName = _T("C:\\layers.txt");if (!f.Open(pFileName, CFile::modeRead, &e)){acutPrintf(_T("\n打开导入文件失败!"));return;}// 获得层表指针AcDbLayerTable *pLayerTbl;AcDbLayerTableRecord *pLayerTblRcd;acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTbl, AcDb::kForWrite);// 读取文件中的每一行数据CString strLineText; // 一行文字while (f.ReadString(strLineText)){// 跳过空行if (strLineText.IsEmpty())continue;// 解析出图层名称、颜色、线型和线宽CStringArray layerInfos;if (!GetFieldText(strLineText, layerInfos))continue;// 创建新的层表记录,或者打开存在的块表记录AcDbLayerTableRecord *pLayerTblRcd;AcDbObjectId layerTblRcdId;if (pLayerTbl->has(layerInfos.GetAt(0))){pLayerTbl->getAt(layerInfos.GetAt(0), layerTblRcdId);}else{ pLayerTblRcd = new AcDbLayerTableRecord();pLayerTblRcd->setName(layerInfos.GetAt(0));pLayerTbl->add(layerTblRcdId, pLayerTblRcd);pLayerTblRcd->close();}acdbOpenObject(pLayerTblRcd, layerTblRcdId, AcDb::kForWrite);// 设置层表记录的颜色AcCmColor color;Adesk::UInt16 colorIndex = _wtol(layerInfos.GetAt(1));color.setColorIndex(colorIndex);pLayerTblRcd->setColor(color);// 设置线型AcDbLinetypeTable *pLinetypeTbl;AcDbObjectId linetypeId;acdbHostApplicationServices()->workingDatabase()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead);if (pLinetypeTbl->has(layerInfos.GetAt(2))){pLinetypeTbl->getAt(layerInfos.GetAt(2), linetypeId);}else {pLinetypeTbl->getAt(_T("Continous"), linetypeId);}pLayerTblRcd->setLinetypeObjectId(linetypeId);pLinetypeTbl->close();// 设置线宽AcDb::LineWeight lineWeight = (AcDb::LineWeight)_wtol(layerInfos.GetAt(3));pLayerTblRcd->setLineWeight(lineWeight);pLayerTblRcd->close();}pLayerTbl->close();
}

(6) 在acrxEntryPoint.cpp中

ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyNewLayer, MyNewLayer, ACRX_CMD_MODAL, NULL) //新建图层
ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyDelLayer, MyDelLayer, ACRX_CMD_MODAL, NULL) //删除图层
ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyModifyLayerColor, MyModifyLayerColor, ACRX_CMD_MODAL, NULL) //插入图层
ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyExportLayer, MyExportLayer, ACRX_CMD_MODAL, NULL) //导出图层
ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyImportLayer, MyImportLayer, ACRX_CMD_MODAL, NULL) //导入图层
    //当前项目中注册命令 新建/删除/插入/导出/导入static void MidasMyGroupMyNewLayer(){CLayerOper m_layerOper;m_layerOper.NewLayer();}static void MidasMyGroupMyDelLayer(){CModifyLayer m_modifyLayer;m_modifyLayer.DelLayer();}static void MidasMyGroupMyModifyLayerColor(){CModifyLayer m_modifyLayer;m_modifyLayer.ModifyLayerColor();}static void MidasMyGroupMyExportLayer(){CModifyLayer m_modifyLayer;m_modifyLayer.ExportLayer();}static void MidasMyGroupMyImportLayer(){CModifyLayer m_modifyLayer;m_modifyLayer.ImportLayer();}

效果展示:

(23)ObjectARX2015 + vs2012操作图层相关推荐

  1. (15)ObjectARX2015 + vs2012创建三维实体

    1. 说明         ObjectARX 中提供了三类创建三维实体的方法:                 (1)创建标准形状的实体                 (2)拉伸面域创建实体    ...

  2. (7)ObjectARX2015 + vs2012创建多段线以及实体的旋转移动放缩

    提示:看之前的博客(1)和(4),那里已经分析了创建一个图形对象的基本过程,在之前的基础上本节开始就要将着眼点放在创建实体的参数上. (1)ObjectARX2015 + vs2012创建直线_qq_ ...

  3. (9)ObjectARX2015 + vs2012创建面域

    提示:看之前的博客(1)和(4),那里已经分析了创建一个图形对象的基本过程,在之前的基础上本节开始就要将着眼点放在创建实体的参数上. (1)ObjectARX2015 + vs2012创建直线_qq_ ...

  4. (12)ObjectARX2015 + vs2012创建尺寸标注

    提示:看之前的博客(1)和(4),那里已经分析了创建一个图形对象的基本过程,在之前的基础上本节开始就要将着眼点放在创建实体的参数上. (1)ObjectARX2015 + vs2012创建直线_qq_ ...

  5. (14)ObjectARX2015 + vs2012创建和编辑对象时的动态拖动技术

    提示:看之前的博客(1)(4)和(12),那里已经分析了创建一个图形对象的基本过程,在之前的基础上本节开始就要将着眼点放在创建实体的参数上. (1)ObjectARX2015 + vs2012创建直线 ...

  6. (6)ObjectARX2015 + vs2012创建圆弧

    提示:看之前的博客(1)和(4),那里已经分析了创建一个图形对象的基本过程,在之前的基础上本节开始就要将着眼点放在创建实体的参数上. (1)ObjectARX2015 + vs2012创建直线_qq_ ...

  7. maptalks常见操作——图层置顶置底、添加清空图层、添加标注、切换底图、添加缩放工具、事件监听(点击面出弹框)、右键菜单、绘制mark、锁定视角

    maptalks常见操作--图层置顶置底.添加清空图层.添加标注.切换底图.添加缩放工具.事件监听(点击面出弹框).右键菜单.绘制mark.锁定视角 1.图层置顶 置底 layer.show().br ...

  8. C# VS2012操作word文档 (二).插入表格图片

    在上一篇文章"C# VS2012创建word文档.(一)"中我们讲述了如何使用VS2012引用COM中Miscrosoft Word 14.0 Object Library实现创建 ...

  9. C# VS2012操作word文档 (一).创建文档

    该文章主要是讲述如何使用VS2012创建word文档,因为在项目中我们可能需要点击一个按钮把数据库中的项目表单或图片显示到word文档中,因此该文章主要分析如何使用VS2012创建word文档并填写相 ...

  10. (31)ObjectARX2015 + vs2012选择集

    1. 说明         在 ObjectARX 开发过程中,经常需要用户和 AutoCAD 之间进行交互操作,除了前面介绍的acedGetXX系列函数之外,选择集是AutoCAD和用户交互操作的重 ...

最新文章

  1. mac terminal vim delete key
  2. C 指针的有意思的描述
  3. Redis资料汇总专题
  4. 原理图、PCB和实物是如何对应起来的
  5. 特征选择--文本分类: 信息增益
  6. 从实例入手学习Shiro与Web的整合
  7. 使用spring的@autowired注解,无法实例化dao
  8. 插入排序最优_排序专题插入排序
  9. 戴尔商台试机选购指南
  10. android 生成签名和SHA1签名信息
  11. CCLayer中Touch事件(Standard Touch Delegate Targeted Touch Delegate)
  12. mssql 不能连接mysql,ASP连接MSSQL的错误:拒绝访问_MySQL
  13. Aspose.Excel模板输出中名称管理器的使用
  14. fillna填充某一列_DataFrame基础运算以及空值填充的案例分析
  15. Android 开发中渐变背景的简单使用
  16. 《手把手教你构建自己的 Linux 系统》学习笔记(9)
  17. 信息系统项目管理师必背整体核心考点
  18. 秒懂Retrofit2之GsonConverter
  19. 简单归纳一下32位、64位、x86、x64的区别和联系
  20. 兼莱宝分享:不想一直打工,可以做这5个冷门生意,竞争比较小,利润却很不错

热门文章

  1. 开发一款游戏需要什么技术
  2. 上计算机课的心得体会作文,计算机学习心得体会范文
  3. 数据应用系统的压力测试方案
  4. 【LaTex】 Font “FandolSong-Regular“ does not contain requested(fontspec)Script “CJK“.如何抑制此种警告?
  5. 原生js获取浏览器语言配置,设置文本多语言(小demo)
  6. linux下kegg注释软件,如何使用KAAS进行KEGG注释
  7. 【RDMA】MPI over InfiniBand, Omni-Path, Ethernet/iWARP, and RoCE 测试结果
  8. 在latex中设置表格背景色
  9. jqGrid设置表格列的背景色
  10. MySQL中临时表(TEMPORARY)