admin 发表于 2024-5-4 19:15:30

ObjectArx图层操作封装

//新建图层
void CLayerOper::NewLayer()
{
    // 提示用户输入新建图层的名称
    TCHAR layerName;
    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();
}

admin 发表于 2024-5-4 19:15:41

Adesk::Boolean acedSetColorDialog(
    int& nColor,//nColor 参数指定了显示【选择颜色】对话框时的默认颜色,并且在函数返回值后保存用户选择的新颜色
    Adesk::Boolean bAllowMetaColor,//bAllowMetaColor 参数限定在【选择颜色】对话框中是否可以选择“随层”或“随块”
    int nCurLayerColor);             //nCurLayerColor 参数指定当前图层的颜色。



AcCmColor //代表颜色对象,可以通过颜色索引来构建一个新的颜色对象。
          //通过颜色索引,可以将【选择颜色】对话框的结果设置为指定图层的颜色,
其相关代码为:

AcCmColor color;
color.setColorIndex(nNewColor);
pLayerTblRcd->setColor(color);





//修改图层颜色
void CModifyLayer::ModifyLayerColor()
{
    // 提示用户输入要修改的图层名称
    TCHAR layerName;
    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();
}









admin 发表于 2024-5-4 19:16:06

//删除图层
void CModifyLayer::DelLayer()
{
    // 提示用户输入要修改的图层名称
    TCHAR layerName;
    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();
}

admin 发表于 2024-5-4 19:16:15

//导出图层到文本文档
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();
}

admin 发表于 2024-5-4 19:16:42

//解析文本(图层的名称、颜色、线型和线宽)
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;
}

admin 发表于 2024-5-4 19:16:52

//从文本文档到导入图层
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();
}

admin 发表于 2024-5-4 19:17:03



    //当前项目中注册命令 新建/删除/插入/导出/导入
    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();
    }














admin 发表于 2024-5-4 19:17:53

选择指定图层上的所有实体

Acad::ErrorStatus selectEntityInLayer(const std::wstring sLayerName, AcDbObjectIdArray& nIDs)
{
        Acad::ErrorStatus es = Acad::eOk;

        ads_name ents;
        struct resbuf *rb;
        rb = acutNewRb(AcDb::kDxfLayerName);
        rb->restype = 8;
        rb->resval.rstring = (ACHAR *)sLayerName.c_str();
        rb->rbnext = NULL;
        acedSSGet(L"X", NULL, NULL, rb, ents);
        Adesk::Int32 entNums = 0;
        acedSSLength(ents, &entNums);
        if (entNums == 0)
                es = Acad::eInvalidInput;
        else
        {
                for (long a = 0; a < entNums; a++)
                {
                        AcDbObjectId objId;
                        ads_name      ent;
                        acedSSName(ents, a, ent);
                        acdbGetObjectId(objId, ent);
                        nIDs.append(objId);
                }
        }
        acedSSFree(ents);
        acutRelRb(rb);
        return es;
}

admin 发表于 2024-5-4 19:18:08

设置当前层

Acad::ErrorStatus SetCurLayer(const std::wstring lpLayerName, AcDbDatabase* pDb/* = NULL */)
{
        AcDbDatabase* pCurDb = pDb;
        if (pCurDb == NULL)
        {
                pCurDb = acdbHostApplicationServices()->workingDatabase();
        }

        AcDbLayerTableRecordPointer spRecord(lpLayerName.c_str(), pCurDb, AcDb::kForRead);
        Acad::ErrorStatus es = spRecord.openStatus();
        if (es == Acad::eOk)
        {
                es = pCurDb->setClayer(spRecord->objectId());
        }
        return es;
}

admin 发表于 2024-5-4 19:21:59

锁定图层: layiso ;解锁图层:layuniso

创建图层记录:void ZffCHAP4NewLayer()
{
// 提示用户输入新建图层的名称
char layerName;
if (acedGetString(Adesk::kFalse, "\n输入新图层的名称:",layerName) != RTNORM)
   return;

// 获得当前图形的层表
AcDbLayerTable *pLayerTbl = NULL;
acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTbl, AcDb::kForWrite);

// 是否已经包含指定的层表记录
if (pLayerTbl->has(layerName))
{
pLayerTbl->close();
return;
}

// 创建新的层表记录
AcDbLayerTableRecord *pLayerTblRcd = new AcDbLayerTableRecord();
pLayerTblRcd->setName(layerName);

// 设置颜色,层的其他属性(线型等)都用缺省值
AcCmColor color;
color.setColorIndex(1);
pLayerTblRcd->setColor(color);

// 将新建的层表记录添加到层表中
AcDbObjectId layerTblRcdId;
pLayerTbl->add(layerTblRcdId, pLayerTblRcd);
acdbHostApplicationServices()->workingDatabase()->setClayer(layerTblRcdId);
pLayerTblRcd->close();
pLayerTbl->close();
}



页: [1] 2
查看完整版本: ObjectArx图层操作封装