objectarx 常用反应器种类
常用反应器种类类型 派生 示例
数据库反应器 派生于AcDbDatabaseReactor,负责接收与数据库状态相关的事件 对象被加入、删除、修改到数据库中,这种反应器的通知发送者是数据库,此种反应器被加入到数据库的反应器列表中
对象反应器(自定义类中详述) 派生于AcDbObjectReactor,
负责接收对象(object)级别的事件 复制、删除、修改一个对象,它也可以被加入到任何AcDbObject对象的反应器列表中
编辑反应器 派生于AcEditorReactor,
负责接收AutoCAD的特殊事件 例如加载或卸载一张图,开始或结束一个命令以及其他类型的用户交互。AcEditor对象是AcEditorReactor反应器的唯一通知发送者
配置文件管理器反应器 派生于AcApProfileManagerReactor,负责接收配置文件操作的事件 例如对配置文件的增删改查
输入上下文反应器 派生于AcEdInputContextReactor,负责接收用户输入动作的事件 例如:用户在屏幕上点选、获取角度、获取距离等
反应器使用原则
不要依赖反应器激活的顺序
不要依赖通知间操作的顺序:通知只负责告知有无,不负责先后
不要在通知回调函数中使用任何用户交互函数
临时反应器
使用过程:从ARX内建的一系列反应器类中挑选一个合适的类派生,实现相关函数并注册反应器。
特点:非数据库对象,由开发者负责注册、卸载
包含:数据库反应器、编辑反应器
永久反应器
特点:永久反应器由AutoCAD负责删除
包含:对象反应器 类文件修改
CDatabaseReactor.h
class /*DLLIMPEXP*/ CDatabaseReactor : public AcDbDatabaseReactor {
...
public:
...
// 重写基类AcDbDatabaseReactor 相应方法
virtual void objectAppended(const AcDbDatabase* dwg, const AcDbObject* dbObj);
virtual void objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObj);
virtual void objectErased(const AcDbDatabase* dwg, const AcDbObject* dbObj,
Adesk::Boolean bErased);
} ;
...
CDatabaseReactor.cpp
#include "StdAfx.h"
#include "CDatabaseReactor.h"
// 定义全局变量
class CDatabaseReactor;
CDatabaseReactor *pDRec = NULL;
...
void printObj(const AcDbObject* pObj)
{ // 纠错:防止传入空对象
if (pObj == NULL)
{
acutPrintf(采用T("(NULL)"));
return;
}
// 句柄:用于获取对象句柄对象
AcDbHandle objHand;
// 句柄名称:用于获取对象句柄名称字符串
ACHAR handbuf;
// 获取 句柄对象 的方法
pObj->getAcDbHandle(objHand);
// 获取 对象句柄 名称字符串 方法:通过句柄对象
objHand.getIntoAsciiBuffer(handbuf, 128);
// s表示字符串,l表示数据为长整型,x表示输出十六进制
acutPrintf(采用T("\n (类名:%s, 句柄:%s, 对象id:%lx)"),
// 类名
pObj->isA()->name(),
// 句柄对象 名称
handbuf,
// asOldId方法:将对象id转换为长整型 long 格式
pObj->objectId().asOldId());
}
// 新增实体后,反应器进行的操作
void CDatabaseReactor::objectAppended(const AcDbDatabase* dwg,
const AcDbObject* dbObj)
{
acutPrintf(采用T("\n调用反应器 对象新增 方法"));
printObj(dbObj);
}
// 修改实体后,反应器进行的操作
void CDatabaseReactor::objectModified(const AcDbDatabase* dwg,
const AcDbObject* dbObj)
{
acutPrintf(采用T("\n调用反应器 对象修改 方法"));
printObj(dbObj);
}
// 删除实体后,反应器进行的操作
void CDatabaseReactor::objectErased(const AcDbDatabase* dwg,
const AcDbObject* dbObj,
Adesk::Boolean bErased)
{
if (bErased)
{
acutPrintf(采用T("\n调用反应器 对象删除 方法"));
printObj(dbObj);
}
else
{
acutPrintf(采用T("\n调用反应器 对象删除 方法(恢复删除)"));
printObj(dbObj);
}
}
2.3 注册卸载反应器
Commands.h
#include "stdafx.h"
void AddCommands();
void addReactor();
void removeReactor();
Commands.cpp
#include "stdafx.h"
#include "Commands.h"
#include "Editor.h"
#include "CDatabaseReactor.h"
// 声明全局变量pDRec:数据库反应器指针
extern CDatabaseReactor *pDRec;
void AddCommands()
{
Editor::AddCommand(L"c-addReactor", ACRX采用CMD采用MODAL, addReactor);
Editor::AddCommand(L"c-removeReactor", ACRX采用CMD采用MODAL, removeReactor);
}
void addReactor()
{
if (pDRec == NULL)
{
pDRec = new CDatabaseReactor();
}
// 在当前活动数据库中添加 数据库反应器
acdbHostApplicationServices()->workingDatabase()->addReactor(pDRec);
acutPrintf(采用T("\n反应器已经添加!"));
}
void removeReactor()
{
if (pDRec)
{
// 在当前活动数据库中删除 数据库反应器
acdbHostApplicationServices()->workingDatabase()->removeReactor(pDRec);
// 释放内存
delete pDRec;
// 重置指针
pDRec = NULL;
}
acutPrintf(采用T("\n数据库反应器已经删除!"));
}
遇到问题:拉伸操作,CAD也会调用反应器删除、修改函数
页:
[1]