CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

编辑器反应器通知函数

2022-12-31 17:50| 发布者: admin| 查看: 286| 评论: 0|来自: AutoCAD

Theclass 提供了四个通知函数,这些函数在深层克隆操作中的某些点将控制权返回给应用程序。在所有深度克隆和 wblock 克隆操作期间调用以下函数:AcEditorReactor

  • beginDeepClone()
  • beginDeepCloneXlation()
  • abortDeepClone()
  • endDeepClone()

该函数在创建实例之后和克隆任何对象之前调用。ID 映射将为空,但此时可以查询。beginDeepClone()AcDbIdMappingdestDb()deepCloneContext()

在克隆主选择集中的所有对象之后和转换引用之前调用该函数。这是第一次可以看到ID映射中克隆的整个集合。这也是克隆任何其他对象并将它们添加到 ID 映射的时候。请记住,此时克隆的任何对象的对象 ID 都在不断变化。beginDeepCloneXlation()

该函数在两者之间的任何时间被调用。abortDeepClone()beginDeepClone()endDeepClone()

该函数在克隆和翻译过程结束时调用。对象 ID 不再变化。但是,此调用并不意味着实体对于正在执行的任何命令都处于最终状态。通常会在克隆过程之后转换克隆的实体或执行其他操作。还有其他回调函数可用于稍后访问实体,包括。endDeepClone()commandEnded()

除了前面的四个功能外,wblock 克隆操作中还提供了以下通知功能:

  • wblockNotice()
  • beginWblock()
  • beginWblockObjects()
  • otherWblock()
  • abortWblock()
  • endWblock()

这些调用与深度克隆函数一起按以下顺序出现:

  1. wblockNotice()此调用在进行任何 wblock 处理之前发送。它允许应用程序有机会调用以强制克隆 wblock* 操作。AcDbDatabase::forceWblockDatabaseCopy()
  2. beginDeepClone()创建目标实例后,将立即发送此调用,但它处于“原始”状态,尚未准备好追加。AcDbDatabase
  3. beginWblock()新数据库现在具有其基本元素,例如句柄表、类 ID 映射以及模型空间和图纸空间块表记录。它仍然是空的。克隆尚未开始,但新数据库现已准备好追加。
  4. otherWblock()并且这两个调用是连续进行的,可用于相同的目的。主对象集已克隆,但参考转换尚未开始。beginDeepCloneXlation()
  5. endDeepClone()翻译过程现已完成,但实体尚未处于最终状态。
  6. endWblock() 现在已转换实体,并已设置模型空间和图纸空间原点。新数据库已完成,但尚未保存。

beginWblockObjects()仅在调用函数并正在执行时发送。在克隆每个源数据库的第一个对象之前,将为每个源数据库发送一次该对象。对于,通知序列为:AcDbDatabase::wblockCloneObjects()wblockCloneObjects()

  1. beginDeepClone()
  2. beginWblockObjects()
  3. ...
  4. beginWblockObjects()
  5. endDeepClone

有三种类型。此处列出了它们及其相应的功能:AcEditorReactor::beginWblock()AcDbDatabase

布洛克*

virtual void
AcEditorReactor::beginWblock(
    AcDbDatabase* pTo,
    AcDbDatabase* pFrom)
 
Acad::ErrorStatus
AcDbDatabase::wblock(
    AcDbDatabase*& pOutputDatabase)

用户定义块的 WBLOCK

virtual void
AcEditorReactor::beginWblock(
    AcDbDatabase* pTo,
    AcDbDatabase* pFrom,
    AcDbObjectId blockId)
 
Acad::ErrorStatus 
AcDbDatabase::wblock(
    AcDbDatabase*& pOutputDatabase, 
    AcDbObjectId nObjId)

选择集的 WBLOCK

virtual void
AcEditorReactor::beginWblock(
    AcDbDatabase* pTo, 
    AcDbDatabase* pFrom, 
    const AcGePoint3d& insertionPoint)
 
Acad::ErrorStatus
AcDbDatabase::wblock(
    AcDbDatabase*& pOutputDatabase,
    const AcDbObjectIdArray& pIdSet,
    const AcGePoint3d& pPoint3d)

All three versions clone both the model space and paper space before calling . However, for the entities within these block table records, the order of notification will appear to come differently in the first type and last two types. In version one, entities in model space that are being cloned will receive the call for before the . In versions two and three, entities in the or the selection set will get their call after the notification call. AcDbBlockTableRecordbeginWblock()wblockClone()AcEditorReactor::beginWblock()AcDbBlockTableRecordwblockClone()AcEditorReactor::beginWblock()

Objects that have been cloned during a partial XBIND are automatically redirected just after notification. This means that their in the externally referenced database are forwarded to the of the clone objects in the host drawing, and the objects in the externally referenced database are deleted. Objects that reference the forwarded end up referencing the clones in the host drawing. If you need to disable this automatic redirection for your objects, then remove the from the , for your cloned objects, during notification. endDeepClone()AcDbObjectIdsAcDbObjectIdsAcDbObjectIdsidPair()idMapendDeepClone()

The following function calls occur during an INSERT or INSERT* command:

  • beginInsert()
  • otherInsert()
  • abortInsert()
  • endInsert()

These calls come in the following order with the deep clone functions:

  1. beginInsert() and These calls come back-to-back and can be used for the same purpose. beginDeepClone()
  2. otherInsert() and These calls also come back-to-back and can be used for the same purpose. beginDeepCloneXlation()
  3. endDeepClone() The cloning and translation processes are completed. The entities are cloned but have not been appended to a block, so they are not graphical. You cannot use the entities in a selection set yet.
  4. endInsert() The entities have now been transformed and have been appended to a block. If this is an INSERT*, they are now in model space and have their graphics. They can be used in selection sets. However, if this is an INSERT, they have only been appended to a block table record; that record has not yet been added to the block table. In this case, you must wait until notification to use these entities in a selection set. commandEnded()

The sample code in this section uses the notification function. This sample illustrates how you could write a reactor to add behavior to the WBLOCK command to tell it to include all text styles in the new drawing, instead of only the text styles that are referenced by the entities. It thus shows how to use wblock with nonentities. beginDeepCloneXlation()

AcDbIdMapping has a function, , which returns the context in which the deep clone function was called. The contexts are the following: deepCloneContext()

kDcCopy

Copying within a database; uses COPY, ARRAY, MIRROR (if you are not deleting the original), LEADER acquisition, or copy of an INSERT

kDcExplode

EXPLODE of a block reference

kDcBlock

BLOCK creation

kDcXrefBind

XREF Bind and XBIND

kDcSymTableMerge

XREF Attach, Resolve, and Reload

kDcSaveAs

SAVEAS when VISRETAIN is set to 1 (only symbol table records are cloned here)

kDcInsert

INSERT of a drawing

kDcWblock

WBLOCK

kDcObjects

AcDbDatabase::deepCloneObjects()

The function is called when a call to is made. AcEditorReactor::abortDeepClone()AcDbDatabase::abortDeepClone()

The following code uses a transient editor reactor derived from and overrides the function for the reactor. AcEditorReactorbeginDeepCloneXlation()

//  Since AcDbDatabase::wblock() only supports AcDbEntities
//  in its array of IDs, this code demonstrates how to add
//  additional objects during beginDeepCloneXlation(). If
//  it is a WBLOCK command, it asks the user if all text
//  styles should be wblocked.  Otherwise, only those text
//  styles referenced by entities being wblocked
//  will be included (wblock's default behavior).
// AsdkEdReactor is derived from AcEditorReactor.
//
void AsdkEdReactor::beginDeepCloneXlation(AcDbIdMapping& idMap,
    Acad::ErrorStatus* es)
{
    if (idMap.deepCloneContext() == AcDb::kDcWblock
        && getYorN("Wblock all Text Styles"))
    {
        AcDbDatabase *pOrigDb, *pDestDb;
        if (idMap.origDb(pOrigDb) != Acad::eOk)
            return;
        *es = idMap.destDb(pDestDb);
        if (*es != Acad::eOk)
            return;
        AcDbTextStyleTable *pTsTable;
        *es = pOrigDb->getSymbolTable(pTsTable,
            AcDb::kForRead);
        if (*es != Acad::eOk)
            return;
        AcDbTextStyleTableIterator *pTsIter;
        *es = pTsTable->newIterator(pTsIter);
        if (*es != Acad::eOk) {
            pTsTable->close();
            return;
        }
        AcDbTextStyleTableRecord *pTsRecord;
        AcDbObject *pClonedObj;
        for (; !pTsIter->done(); pTsIter->step()) {
            *es = pTsIter->getRecord(pTsRecord,
                AcDb::kForRead);
            if (*es != Acad::eOk) {
                delete pTsIter;
                pTsTable->close();
                return;
            }
            // It is not necessary to check for already cloned
            // records.  If the text style is already
            // cloned, wblockClone() will return Acad::eOk
            // and pCloneObj will be NULL.
            //
            pClonedObj = NULL;
            *es = pTsRecord->wblockClone(pDestDb,
                pClonedObj, idMap, Adesk::kFalse);
            if (*es != Acad::eOk) {
                pTsRecord->close();
                delete pTsIter;
                pTsTable->close();
                return;
            }
            *es = pTsRecord->close();
            if (*es != Acad::eOk) {
                delete pTsIter;
                pTsTable->close();
                return;
            }
            if (pClonedObj != NULL) {
                *es = pClonedObj->close();
                if (*es != Acad::eOk) {
                    delete pTsIter;
                    pTsTable->close();
                    return;
                }
            }
        }
        delete pTsIter;
        *es = pTsTable->close();
    }
}

路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 14:28

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部