长事务

长事务用于支持 AutoCAD 参照编辑功能,对于 ObjectARX 应用程序非常有用。这些类和函数为应用程序提供了一种方案,用于签出实体以进行编辑并将其签回其原始位置。此操作会将原始对象替换为已编辑的对象。有三种类型的长期交易结帐:

  • 从同一图形中的普通块
  • 从图形的外部参照 (外部参照)
  • 从不相关的临时数据库

长事务类和函数概述

主要的长事务类和函数是

  • .class
  • .class
  • .class
  • .class

是包含跟踪长事务所需信息的类。该类负责创建A对象并将其追加到数据库。然后它返回对象的。与所有其他驻留在数据库的对象一样,其销毁由数据库处理。

对象在处于活动状态时添加到数据库中,并在事务完成后擦除。它们不存储在 DWG 或 DXF 文件中,因此不是持久性的。

提供对工作集中对象的只读访问权限。在构造期间,可以将其设置为仅包含活动工作集,或者包括添加到工作集的对象,因为它们被工作集中的对象(辅助对象)引用。它还可以处理从工作集中移除的对象,无论是通过擦除还是被擦除。

提供特定于长事务操作的通知。它旨在与也将发送的深层克隆通知结合使用,但会因正在执行的签出/签入类型而异。要将这些通知与深层克隆通知连接起来,可以通过调用函数来检索用于克隆的对象。

AcApLongTransactionManager Class

是用于启动和控制多头事务的管理器。每个 AutoCAD 会话只有一个acapLongTransactionManager,可通过对象返回的指针进行访问。

AcDbDatabase::wblockCloneObjects() Function

函数是的成员。它将对象从一个数据库深度克隆到另一个数据库,并遵循硬引用,以便所有依赖对象也被克隆。当发现重复项时,符号表记录的行为由类型参数确定。下图显示了符号表类型 () 和深层克隆类型 () 之间的关系。

 

长事务示例

这个简单的示例演示如何从另一个数据库中签出实体,在当前数据库中修改它们,然后将其签回原始数据库。作为长事务过程一部分的调用以粗体显示。

void
refEditApiExample()
{
AcDbObjectId transId;
AcDbDatabase* pDb;
TCHAR *fname;
struct resbuf *rb;
    // Get a dwg file from the user.
    //
    rb = acutNewRb(RTSTR);
    int stat = acedGetFileD(_T("Pick a drawing"), NULL, _T("dwg"),
 0, rb);
if ((stat != RTNORM) || (rb == NULL)) {
        acutPrintf(_T("\nYou must pick a drawing file."));        return;    }
fname = (TCHAR*)acad_malloc((_tcslen(rb->resval.rstring) + 1) *
 sizeof(TCHAR));
    _tcscpy(fname, rb->resval.rstring);
    acutRelRb(rb);
// Open the dwg file.
    //
    pDb = new AcDbDatabase(Adesk::kFalse);
    if (pDb->readDwgFile(fname) != Acad::eOk) {
        acutPrintf(_T("\nSorry, that drawing is probably already
          open."));
        return;
    }
    // Get the Block Table and then the model space record.
    //
    AcDbBlockTable *pBlockTable;
    pDb->getSymbolTable(pBlockTable, AcDb::kForRead);
    AcDbBlockTableRecord *pOtherMsBtr;
    pBlockTable->getAt(ACDB_MODEL_SPACE, pOtherMsBtr,
      AcDb::kForRead);
    pBlockTable->close();
    // Create an iterator.
    //
    AcDbBlockTableRecordIterator *pIter;
    pOtherMsBtr->newIterator(pIter);
    // Set up an object ID array.
    //
    AcDbObjectIdArray objIdArray;
    // Iterate over the model space BTR. Look specifically 
    // for lines and append their object ID to the array.
    //
    for (pIter->start(); !pIter->done(); pIter->step()) {
        AcDbEntity *pEntity;
        pIter->getEntity(pEntity, AcDb::kForRead);
        // Look for only AcDbLine objects and add them to the 
        // object ID array.
        //
        if (pEntity->isKindOf(AcDbLine::desc())) {
            objIdArray.append(pEntity->objectId());
        }
        pEntity->close();
    }
    delete pIter;
    pOtherMsBtr->close();
    if (objIdArray.isEmpty()) {
        acad_free(fname);
        acutPrintf(_T("\nYou must pick a drawing file that contains
          lines."));
        return;
    }
    // Now get the current database and the object ID for the
    // current database's model space BTR.
    //
    AcDbBlockTable *pThisBlockTable;
    acdbHostApplicationServices()->workingDatabase()->
      getSymbolTable(pThisBlockTable, AcDb::kForRead);
    AcDbBlockTableRecord *pThisMsBtr;
    pThisBlockTable->getAt(ACDB_MODEL_SPACE, pThisMsBtr,
      AcDb::kForWrite);
    pThisBlockTable->close();
    AcDbObjectId id = pThisMsBtr->objectId();
    pThisMsBtr->close();
    // Create the long transaction. This will check all the entities 
    // out of the external database.
    //
    AcDbIdMapping errorMap;
    acapLongTransactionManagerPtr()->checkOut(transId, objIdArray,
      id, errorMap);
    // Now modify the color of these entities.
    //
    int colorIndex;
    acedGetInt(_T("\nEnter color number to change entities to: "),
      &colorIndex);
    AcDbObject* pObj;
    if (acdbOpenObject(pObj, transId, AcDb::kForRead) == Acad::eOk) {
        // Get a pointer to the transaction.
        //
        AcDbLongTransaction* pLongTrans =
          AcDbLongTransaction::cast(pObj);
        if (pLongTrans != NULL) {
            // Get a work set iterator.
            //
            AcDbLongTransWorkSetIterator* pWorkSetIter;
            pLongTrans->newWorkSetIterator(pWorkSetIter);
            // Iterate over the entities in the work set and change
            // the color.
            for (pWorkSetIter->start(); !pWorkSetIter->done();
               pWorkSetIter->step()) {
                AcDbEntity *pEntity;
                acdbOpenAcDbEntity(pEntity, pWorkSetIter->objectId(),
                  AcDb::kForWrite);
                pEntity->setColorIndex(colorIndex);
                pEntity->close();
            }
            delete pWorkSetIter;
        }
        pObj->close();
    }
    // Pause to see the change.
    //
    TCHAR str[132];
    acedGetString(0, _T("\nSee the new colors. Press return to check
      the object into the original database"), str);
    // Check the entities back in to the original database.
    //
    acapLongTransactionManagerPtr()->checkIn(transId, errorMap);
    // Save the original database, since we have made changes.
    //
    pDb->saveAs(fname);
    // Close/Delete the database
    //
    delete pDb;
    pDb = NULL;
    acad_free(fname);
}
11-05 10:52