admin 发表于 2024-3-13 23:01:02

objectarx 常用反应器种类

常用反应器种类
类型        派生        示例
数据库反应器        派生于AcDbDatabaseReactor,负责接收与数据库状态相关的事件        对象被加入、删除、修改到数据库中,这种反应器的通知发送者是数据库,此种反应器被加入到数据库的反应器列表中
对象反应器(自定义类中详述)        派生于AcDbObjectReactor,
负责接收对象(object)级别的事件        复制、删除、修改一个对象,它也可以被加入到任何AcDbObject对象的反应器列表中
编辑反应器        派生于AcEditorReactor,
负责接收AutoCAD的特殊事件        例如加载或卸载一张图,开始或结束一个命令以及其他类型的用户交互。AcEditor对象是AcEditorReactor反应器的唯一通知发送者
配置文件管理器反应器        派生于AcApProfileManagerReactor,负责接收配置文件操作的事件        例如对配置文件的增删改查
输入上下文反应器        派生于AcEdInputContextReactor,负责接收用户输入动作的事件        例如:用户在屏幕上点选、获取角度、获取距离等
反应器使用原则
不要依赖反应器激活的顺序
不要依赖通知间操作的顺序:通知只负责告知有无,不负责先后
不要在通知回调函数中使用任何用户交互函数
临时反应器
使用过程:从ARX内建的一系列反应器类中挑选一个合适的类派生,实现相关函数并注册反应器。
特点:非数据库对象,由开发者负责注册、卸载
包含:数据库反应器、编辑反应器
永久反应器
特点:永久反应器由AutoCAD负责删除
包含:对象反应器

admin 发表于 2024-3-13 23:01:51

类文件修改
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]
查看完整版本: objectarx 常用反应器种类