|
前面的废话:
最近因为一个业务需要实现两个实体之间的拖动联动,大牛建议用反应器实现,查找资料发现是需要用对象反应器实现。后来就找到了这篇文章
[url]https://blog.csdn.net/biggerass/article/details/21020465[/url] 对象反应器的使用
跟着照做,一步一步终于实现了联动。发现一个问题:虽然修改modefied时候有效,但是dwgOutFileds函数根本不被调用!!!网上到处都是这个帖子,但是却不能用。图纸中的关联关系不能被保存,关联关系只能当时有效,这肯定是要被产品小哥哥追着打的,没办法,只能继续开拓寻找别的道路走了。
后来大牛建议集成AcDbEntity实现,重载subworlddraw实现。
后来搜索资料找到方法,重新实现。
附件中的例子是可以实现的,其中的理论与objectarx.chm上对于AcDbObjectReactor类的介绍相符:
(以下是从文档上copy过来的,方便与代码相对应参照)
AcDbObjectReactor类
AcDbObjectReactor类作为反应器类的基类,在反应器类中重载方法对于需要通知的事件被调用。当这些派生类之一的一个对象被实例化且增加至需要通知的对象的反应器链中时,反应器对象中适当的方法在访问“通知的”对象时被调用。
继承自
AcRxObject
包含文件
dbmain.h
提示
定义一个继承自AcDbObjectReactor的类使用这个类。实例化从AcDbObjectReactor派生的类的一个对象,并通过调用希望通知定位的对象的addReactor方法将新创建的反应器对象增加至反应器链中。
参见
AcDbEntity, AcDbObject, AcDbDatabase, AcDbEntityReactor
成员
AcDbObjectReactor建构器和析构器
AcDbObjectReactor::AcDbObjectReactor 函数
AcDbObjectReactor();
这个默认建构器声明为保护的,因此这个类只能作为一个基类使用。
这个建构器有一个空的执行。
AcDbObjectReactor通知函数
AcDbObjectReactor::cancelled 函数
virtual void
cancelled(
const AcDbObject* dbObj);
dbObj
在常指针中传递那些打开被取消的对象
当一个对象被打开用于写入时调用,且它的cancel()方法被调用以代替它的close()方法,为了结束打开操作。
AcDbObjectReactor::copied 函数
virtual void
copied(
const AcDbObject* dbObj,
const AcDbObject* newObj);
dbObj
在常指针中传递正被复制的对象
newObj
在常指针中传递由复制操作创建的对象
此函数在dbObj指向的对象被复制时被调用。newObj是新创建的对象的指针。此函数在被复制的对象被关闭时(复制操作结束后)调用。贴附至原始对象的暂时反应器将不复制至新对象,但贴附的永久反应器将被复制。
AcDbObjectReactor::erased 函数
virtual void
erased(
const AcDbObject* dbObj,
Adesk::Boolean pErasing = true);
dbObj
在常指针中传递被删除的对象
pErasing
传递布尔标记表示对象dbObj被删除或恢复
此函数在dbObj指向的对象从一个AcDbDatabase中删除或恢复时被调用(即,调用它的erase()方法)。pErasing参数是一个布尔值,表示对象被删除或被恢复。Adesk::kTrue值表示对象被删除,Adesk::kFalse值表示对象被恢复。
当dbObj指向的对象被关闭时(在删除操作结束后),此函数被调用。
除了通过AutoCAD的ERASE命令删除一个实体外,erase()还在以下情况下被调用:对象从词典中删除,当词典被删除时而对象在那些词典中,当符号表记录被清除时而对象在那些符号表记录中,一个块表记录的内容被清除时而对象在那些内容中。
AcDbObjectReactor::goodbye 函数
virtual void
goodbye(
const AcDbObject* dbObj);
dbObj
在常指针中传递被注销的对象
此函数在dbObj指向的对象从内存中删除时被调用。例如,当AutoCAD编辑器关闭一个图形时,当前在编辑器中的数据库对象被删除,也包括数据库中所有对象。在每个对象被注销之前,goodbye通知将送至所有贴附的反应器。
接收这个通知表示反应器将不从被注销的对象中接收任何更多的通知,而且反应器不在任何将来的清除中试图将它自身从那个对象中删除,因为那个对象将不会存在。
AcDbObjectReactor::modified 函数
virtual void
modified(
const AcDbObject* dbObj);
dbObj
在常指针中传递已修改的对象
此函数在dbObj指向的对象被打开用于写入且它的调用assertWriteEnabled的一个方法时被调用时调用。通知在对象的关闭或取消方法被调用时发生。如果对象的取消方法被调用,则canceled和modifyUndone通知都将发出。
AcDbObjectReactor::modifiedXData 函数
virtual void
modifiedXData(
const AcDbObject* dbObj);
dbObj
在常指针中传递那个已将其实体数据修改的对象
此函数在一个对象的扩展实体数据元素被修改时调用。通知在提高警惕的实体数据被修改后发生。
AcDbObjectReactor::modifyUndone 函数
virtual void
modifyUndone(
const AcDbObject* dbObj);
dbObj
在常指针中传递恢复修改的对象
此函数在dbObj指向的对象恢复修改时被调用。例如,设置一个线对象的终点再执行AutoCAD的Undo命令以取消修改将导致此通知被送出。
当一个对象打开用于写时,通过调用assertWriteEnabled的方法进行修改,再调用它的cancel方法代替它的close方法,然后此通知和修改通知都将被送出。
此通知在对象在恢复后被关闭时或它的cancel方法在修改后被调用时发生。
AcDbObjectReactor::objectClosed 函数
virtual void
objectClosed(
const AcDbObjectId objId);
objId
传递现在关闭的对象的objectID
此通知在对象ID为objId的对象之前被打开用于写入且调用它的close和cancel方法时发生。
这个特殊的函数在发送通知的对象关闭时被调用。不支持重新打开对象用于写入,因为它导致重复通知。这样做将在打开操作时返回Acad::eWasNotifying。
AcDbObjectReactor::openedForModify 函数
virtual void
openedForModify(
const AcDbObject* dbObj);
dbObj
在常指针中传递被打开用于修改的对象
此函数在dbObj指向的对象打开用于写入且它的调用assertWriteEnabled的一个方法被调用时调用。通知在assertWriteEnabled被调用时(在对象被修改前)发生。
AcDbObjectReactor::reappended 函数
virtual void
reappended(
const AcDbObject* dbObj);
dbObj
在常指针中传递被“重新增加的”对象
此通知在dbObj指向一个UNDO操作中将增加至AcDbDatabase的操作取消并由于AutoCAD的REDO命令执行时重新增加至数据库中时发生。
AcDbObjectReactor::subObjModified 函数
virtual void
subObjModified(
const AcDbObject* dbObj,
const AcDbObject* subObj);
dbObj
在常指针中传递作为已修改的子对象的宿主的主对象
subObj
在常指针中传递已被修改的子对象的指针
此函数在subObj指向的子对象被打开用于写入且它的调用assertWriteEnabled的方法被调用时调用。它个通知在对象的close或cancel方法被调用时发生。
注意:此通知只对以下对象发生:
AcDb2dPolylines, AcDb3dPolylines, AcDbPolygonMeshs和AcDbPolyFaceMeshes的顶点
AcDbPolyFaceMeshs的AcDbFaceRecords
AcDbBlockReferences拥有的、从AcDbBlockReference和AcDbMInsertBlocks派生的AcDbAttributes
AcDbObjectReactor::unappended 函数
virtual void
unappended(
const AcDbObject* dbObj);
dbObj
在常指针中传递被取消增加的对象
此通知在dbObj指向的对象在一个UNDO操作中将向一个AcDbDatabase中的增加操作取消时发生。
使用方法:
下载文件,解压之后打开项目编译,将生成的arx文件拖进去cad中,命令行输入test即可看到五条线,可以随意拖动。保存之后再打开图纸关联关系仍然存在。
|
|