找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 5093|回复: 1

[老徐讲堂] ObjectARX 反应器

[复制链接]

已领礼包: 12个

财富等级: 恭喜发财

发表于 2016-5-22 09:47:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
第二十四章 反应器操作实例    这一章我们介绍创建反应器的方法,并通过几个实例来讲述用合适的对象注册该法宁器来接受通知的方法。

本章的主要内容:
反应器概述
反应器的使用
创建编辑器反应器
创建数据库反应器
创建对象反应器
创建实体反应器
创建反应器的注意事项
[本章配合视频详见光盘文件]
24.1反应器概述当系统中有事件发生时,一个叫做通知者的对象,就会自动将这个事件传递给其他对象。比如,当用户复制、删除或修改对象时,或者当用户输入命令时,就会为每个事件自动触发相应的通知。
接受事件的对象称之为反应器。反应器在被明确地加入到通知者的反应器表中之后,才能接受通知者的事件。一个给定的通知者在其反应器表中可以有许多反应器。反应器类定义包含多种通知函数。当一个事件发生时,通知者会自动调用反应器表中的每个反应所对应的通知函数。
在应用程序中使用反应器的方法为:
(1)派生一个新反应器类并实现将响应事件的通知函数。
(2)建立反应器类的实例。
(3)将反应器加到通知者的反应器表中。
24.1.1反应器类反应器类是从AcRxObject类中派生而来的,而不是从AcDbObject类派生而来的。这是由于反应器不是数据库对象,与它没有隶属关系,而且它没有对象ID值。
不同的反应器能接受不同类型事件的通知。从AcDbDatabaseReactor类派生的数据库反应器所能接受的事件与数据库的状态有关,例如,可以接受在数据库
中。从AcDbObjectReactor类派生的对象反应器在对象级上响应事件,比如复制、删除或修改对象。它能被加入到所有AcDbObject对象的反应器表中。从AcEditorReactor类派生的编辑反应器可响应AutoCAD专用的事件,比如加载和卸载图形、开始或结束命令和其他各种各样的用户交互操作。反应器类的层次结构关系如下图所示:
                              
24.1.2对象反应器的类型
在上节最后的图中显示的反应器类引用作为临时反应器类。如果在程序中需要接受事件通知,通常就要使用临时反应器,用它来监视发生在数据库对象中的事件、用户交互操作和当应用程序运行时发生的其他系统事件。
另一种反应器称为永久反应器,使用一个数据库对象作为反应器。数据库对象能接受并发送通知。永久反应器是数据库的一部分,因此它们能被保存在DWG或DXF文件之中,并且能在装入图形时被重建。
24.2反应器的使用要使用临时反应器,就要从反应器基类中派生出一个新类,在大多数情况下,只有使用标准的C++能新建临时反应器类。而为新建反应器类创建类描述符对象的ObjectARX宏,通常不用来从这些反应器类派生新类。
每个父类都包含一系列能被派生类进行重载的虚函数。例如,AcDbObjectReactor类包含下列能响应与对象有关事件的通知函数:
cancelled()
copied()
erased()
goodbye()
openedForModify()
modified()
subObjModified()
modifyUndone()
modifiedXData()
unappended()
reappended()
objectClosed()
上述函数要求有个指向事件通知者的指针。AcDbObjectReactor基类实现了这些函数,但内容为空。这样,我们派生的反应器类就可以对那些响应我们所感兴趣的通知类型的函数进行重载。然后建立反应器实例,并用AcDbObject::addReactor()函数给任意数目的数据库对象加入这个实例。给通知者对象加入或删除一个临时反应器时,对象可以是以任何模式(读、写或通知模式)打开的。加入或删除临时反应器时,AutoCAD撤销机制不会进行记录。而对于永久反应器,通知者对象必须是以写模式打开,并且加入或删除永久反应器,撤销机制都会进行记录。这是由于创建了临时反应器对象,最后就要由应用程序负责删除它。
例如,当一个对象被删除时,表中的每个反应器调用对应的在erase()通知函数。如果为自己的反应器实现了erase()函数,则数据库对象就会调用该函数,我们就能够在对象被删除时进行一些与应用程序有关的适当处理操作。
当接收一个数据库对象的erase()函数通知时,对象就已经被打上了删除标记,但它仍然作为数据库的一部分存在。当接收到一个unappended()函数通知时,对象就已经被打上非添加标记,并且不作为数据库的一部分,除非它被重新添加才作为数据库的一部分存在。只有当对象要完全被清除之前才发送对象的goodbye()函数通知,该通知说明对象将马上从数据库和内存中被完删除。
当接收erased()unappend()函数通知后,我们也许想从一个对象中删除反应器。然而,这时一旦删除了反应器,就再也不会接受到该对象erased() unappend()函数的通知了。所以要监视这些通知,我们不仅能使用对象的通知,还可以使用在数据库中与之等价的通知,它们是:
AcDbDatabaseReactor::objectErased()
AcDbDatabaseReactor::objectUnappended()
AcDbDatabaseReactor::objectReappended()
当对对象进行修改工作之后,就通过请求调用AcDbObject类的虚函数subClose()关闭对象。在自定义类的这个重载函数中,可以通知其他需要在修改之后关闭的函数。这些通知必须是在类中自定义函数的自定义通知。在这种情况下,就不能再使用AcDbObjectReactor类所提供的通知了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 859个

财富等级: 财运亨通

发表于 2016-5-22 10:08:59 | 显示全部楼层
还没有百度文库的详细,来点实用的吧
http://wenku.baidu.com/link?url= ... Z-osnbsnq-EmihFMi3K
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-29 01:27 , Processed in 0.173408 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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