明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 412|回复: 0

ObjectArx 事务封装

  [复制链接]
发表于 2025-6-28 10:07:36 | 显示全部楼层 |阅读模式
  1. #pragma once
  2. #include <acadstrc.h>
  3. #include <AcApDocWindow.h>
  4. #include <acarray.h>
  5. #include <acdb.h>
  6. #include <acdocman.h>
  7. #include <acestext.h>
  8. #include <AcString.h>
  9. #include <acutads.h>
  10. #include <adesk.h>
  11. #include <dbdict.h>
  12. #include <dbid.h>
  13. #include <dbmain.h>
  14. #include <dbObject.h>
  15. #include <dbsymtb.h>
  16. #include <dbtrans.h>
  17. #include <vector>
  18. #include <Windows.h>
  19. class DbTrans {
  20. private:
  21.   Acad::ErrorStatus m_es = Acad::eOk;
  22. public:

  23.   AcApDocument* pDoc;
  24.   AcDbDatabase* pDb;
  25.   AcDbTransactionManager* pTm;
  26.   AcTransaction* pTrans;
  27.   bool IsOk() const { return m_es == Acad::eOk; }


  28.   DbTrans()
  29.   {
  30.     pDoc = curDoc();
  31.     acDocManager->lockDocument(pDoc);
  32.     pDb = pDoc->database();
  33.     pTm = pDb->transactionManager();
  34.     pTrans = pTm->startTransaction();
  35.   }
  36.   ~DbTrans()
  37.   {
  38.     Commit();
  39.     acDocManager->unlockDocument(pDoc);
  40.   }

  41.   void Commit()
  42.   {

  43.     if (IsOk())
  44.     {
  45.       pTm->endTransaction();

  46.       /*acutPrintf(L"\n提交事务\n");*/
  47.     }
  48.     else
  49.     {
  50.       pTm->abortTransaction();
  51.       acutPrintf(L"\n异常操作,退出事务\n");
  52.     }

  53.   }

  54.   template <class T = AcDbEntity>
  55.   T* getObject(AcDbObjectId objid, AcDb::OpenMode mode = AcDb::OpenMode::kForRead, bool openErased = false)
  56.   {
  57.     T* pObj = nullptr;
  58.     m_es = pTrans->getObject<T>(pObj, objid, mode, openErased);
  59.     if (IsOk()) {
  60.       return pObj;
  61.     }
  62.     else {
  63.       return nullptr;
  64.     }
  65.   }

  66.   template<typename T = AcDbEntity>
  67.   std::vector <T*> getObjects(AcArray<AcDbObjectId> ids, AcDb::OpenMode mode = AcDb::OpenMode::kForRead, bool openErased = false) {
  68.     std::vector<T*> ents;
  69.     for (auto objid : ids) {
  70.       T* pObj = NULL;
  71.       m_es = pTrans->getObject<T>(pObj, objid, mode, openErased);
  72.       if (IsOk()) {
  73.         ents.push_back(pObj);
  74.       }
  75.     }
  76.     return ents;
  77.   }

  78.   template<typename TableType>
  79.   AcDbObjectId getDictId(TableType* table, AcString name) {
  80.     AcDbObjectId tableId = AcDbObjectId::kNull;
  81.     auto es = table->getAt(name, tableId);
  82.     if (es != Acad::eOk)
  83.       acutPrintf(L"不存在%ls的记录\n", name);
  84.     return tableId;
  85.   }

  86.   AcDbBlockTableRecord* currentSpace()
  87.   {
  88.     return this->getObject<AcDbBlockTableRecord>(pDb->currentSpaceId(), AcDb::kForWrite);
  89.   }

  90.   AcDbBlockTableRecord* paperSpace()
  91.   {
  92.     return this->getObject<AcDbBlockTableRecord>(pDb->paperSpaceVportId(), AcDb::kForWrite);
  93.   }
  94.   AcDbBlockTable* getBlockTable() {
  95.     return this->getObject<AcDbBlockTable>(pDb->blockTableId(), AcDb::kForWrite);
  96.   }
  97.   AcDbRegAppTable* getRegAppTable() {
  98.     return this->getObject<AcDbRegAppTable>(pDb->regAppTableId(), AcDb::kForWrite);
  99.   }
  100.   AcDbDimStyleTable* getDimStyleTable() {
  101.     return this->getObject<AcDbDimStyleTable>(pDb->dimStyleTableId(), AcDb::kForWrite);
  102.   }
  103.   AcDbLayerTable* getLayerTable() {
  104.     return this->getObject<AcDbLayerTable>(pDb->layerTableId(), AcDb::kForWrite);
  105.   }
  106.   AcDbLinetypeTable* getLineTypeTable() {
  107.     return this->getObject<AcDbLinetypeTable>(pDb->linetypeTableId(), AcDb::kForWrite);
  108.   }
  109.   AcDbTextStyleTable* getTextStyleTable() {
  110.     return this->getObject<AcDbTextStyleTable>(pDb->textStyleTableId(), AcDb::kForWrite);
  111.   }
  112.   AcDbUCSTable* getUcsTable() {
  113.     return this->getObject<AcDbUCSTable>(pDb->UCSTableId(), AcDb::kForWrite);
  114.   }
  115.   AcDbViewTable* getViewTable() {
  116.     return this->getObject<AcDbViewTable>(pDb->viewTableId(), AcDb::kForWrite);
  117.   }
  118.   AcDbViewportTable* getViewportTable() {
  119.     return this->getObject<AcDbViewportTable>(pDb->viewportTableId(), AcDb::kForWrite);
  120.   }
  121.   AcDbDictionary* getMLeaderStyleDictionary() {
  122.     return this->getObject<AcDbDictionary>(pDb->mleaderStyleDictionaryId(), AcDb::kForWrite);
  123.   }
  124.   AcDbDictionary* getMlineStyleDictionary() {
  125.     return this->getObject<AcDbDictionary>(pDb->mLStyleDictionaryId(), AcDb::kForWrite);
  126.   }
  127.   AcDbDictionary* getMaterialDictionary() {
  128.     return this->getObject<AcDbDictionary>(pDb->materialDictionaryId(), AcDb::kForWrite);
  129.   }
  130.   AcDbDictionary* getPlotSettingsDictionary() {
  131.     return this->getObject<AcDbDictionary>(pDb->plotSettingsDictionaryId(), AcDb::kForWrite);
  132.   }
  133.   AcDbDictionary* getPlotStyleNameDictionary() {
  134.     return this->getObject<AcDbDictionary>(pDb->plotStyleNameDictionaryId(), AcDb::kForWrite);
  135.   }
  136.   AcDbDictionary* getLayoutDictionary() {
  137.     return this->getObject<AcDbDictionary>(pDb->layoutDictionaryId(), AcDb::kForWrite);
  138.   }


  139.   AcDbObjectId addEntity(AcDbBlockTableRecord* btr, AcDbEntity* ent)
  140.   {
  141.     AcDbObjectId objId;
  142.     if (!btr) {
  143.       acutPrintf(L"\n错误:块表记录指针为空");
  144.       return objId;
  145.     }

  146.     Acad::ErrorStatus es = btr->appendAcDbEntity(objId, ent);
  147.     if (es != Acad::eOk) {
  148.       acutPrintf(L"\n错误:无法将实体添加到块表记录 (错误码: %s)", acadErrorStatusText(es));
  149.       return objId;
  150.     }

  151.     es = pTm->addNewlyCreatedDBRObject(ent, true);
  152.     if (es != Acad::eOk) {
  153.       acutPrintf(L"\n错误:无法将实体添加到事务管理器 (错误码: %s)", acadErrorStatusText(es));
  154.       return objId;
  155.     }
  156.     return objId;
  157.   }

  158.   template<typename T>
  159.   AcArray<AcDbObjectId> addEntities(AcDbBlockTableRecord* btr, AcArray<T*> ents)
  160.   {
  161.     AcArray<AcDbObjectId> objIds;
  162.     for (AcDbEntity* ent : ents) {
  163.       auto  objId = addEntity(btr, ent);
  164.       if (objId == AcDbObjectId::kNull) continue;
  165.       objIds.append(objId);
  166.     }
  167.     return objIds;
  168.   }

  169.   bool upopen(AcDbObject* pobj) {
  170.     // 确保对象在事务中
  171.     bool isWritable = pobj->isWriteEnabled();
  172.     if (!isWritable) {
  173.       pobj->upgradeOpen();
  174.       return pobj->isWriteEnabled();
  175.     }
  176.     return isWritable;
  177.   }

  178.   void erase(AcDbObject* pObj) {
  179.     if (!pObj->isErased() && !pObj->isNewObject()) {
  180.       if (upopen(pObj)) {
  181.         pObj->erase();
  182.       }
  183.     }
  184.   }

  185.   void flushScreen()
  186.   {
  187.     pTm->queueForGraphicsFlush();
  188.   }
  189. };



  190. inline static void setFocusDoc() {
  191.   auto windowHwnd = acDocWindowManager->activeDocumentWindow()->windowHandle();
  192.   SetFocus(windowHwnd);
  193. }
使用示例:不需要对line 进行close 或者delete

  1. void addLine() {

  2.   DbTrans tr;
  3.   auto btr = tr.currentSpace();
  4.   AcDbLine* line = new AcDbLine({ 0,0,0 }, { 50,50,0 });
  5.   tr.addEntity(btr, line);
  6. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-7-27 04:16 , Processed in 0.158679 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表