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