ObjectARX如何监控实体双击事件(利用钩子函数或者反应器)

2023-11-09 10:10

本文主要是介绍ObjectARX如何监控实体双击事件(利用钩子函数或者反应器),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1 实现方法1——钩子函数
    • 1.1 钩子函数的作用
    • 1.2 利用钩子函数监控双击事件
  • 2 实现方法2——反应器
    • 2.1 反应器的作用
    • 2.2 利用编辑器反应器监控双击事件

 在ObjectARX开发中,常常要监控鼠标的双击事件,比如,往一个实体中写了扩展数据,然后你希望用户双击这个实体的时候进行特殊处理。怎么办呢?
 ObjectARX至少提供了两种方法:钩子函数和反应器。

1 实现方法1——钩子函数

1.1 钩子函数的作用

 在ObjectARX中,可以在CAD的窗口消息循环中注册一个钩子函数。注册钩子函数的函数原型为:

BOOL acedRegisterFilterWinMsg( const AcedFilterWinMsgFn pfn);

 其中,AcedFilterWinMsgFn 的类型为:

 BOOL (* AcedFilterWinMsgFn)(MSG*);

 acedRegisterFilterWinMsg中形参pfn指向的函数就是钩子函数,它可以更改传递进入的消息值。如果pfn返回FALSE,这个消息将继续传递给其他钩子函数和AutoCAD(假设其他钩子函数没有终止该消息的处理);如果返回TRUE,则消息不再传递。
 在CAD的窗口消息循环中,所有窗口消息都会进入到钩子函数,你可以在钩子函数中对特定消息进行处理。

1.2 利用钩子函数监控双击事件

 在加载arx时会调用OnLoadApp,在卸载时会调用OnUnloadApp。因此,我们可以在OnLoadApp注册钩子函数,在OnUnloadApp删掉注册的钩子函数,注册与反注册的代码如下:

void OnLoadApp()
{//..........省略//注册一个钩子函数//If the function returns TRUE, the message will not be passed to other hook functions or AutoCAD. The message is terminated. acedRegisterFilterWinMsg(FilterEntDBClick);
}void OnUnloadApp()
{//..........省略//remove the hook function.acedRemoveFilterWinMsg(FilterEntDBClick);
}

 上述钩子函数具体实现为

bool FilterEntDBClick(MSG *pMsg)
{if (pMsg->message == WM_LBUTTONDBLCLK){ads_name ss;if (RTNORM != acedSSGet(_T("I"), NULL, NULL, NULL, ss))return false;ads_name ent;int32_t lLen;acedSSLength(ss, &lLen);acedSSName(ss, lLen-1, ent);acedSSFree(ss);AcDbObjectId idObj;if (Acad::eOk == acdbGetObjectId(idObj, ent)){AcDbEntity* pEnt = NULL;if (Acad::eOk == acdbOpenObject(pEnt, idObj)){CString sDxfName = pEnt->isA()->dxfName();acutPrintf(_T("\n\t当前双击实体的dxf名称:%s"), sDxfName);CString sClassName = pEnt->isA()->name();acutPrintf(_T("\n\t当前双击实体的类名称:%s"), sClassName);pEnt->close();}}}//消息继续传递return false;
}

 当双击某个实体的时候,这个钩子函数会获取实体的对象类型、类名称等信息。关于这个函数还有几点说明:
 1.对象的图元类型、类名称信息存在在AcRxClass类对象中,通过IsA()方法,获取对象的AcRxClass类对象。然后进一步获取对象类型、类名称等信息。
 2.双击某个对象的时候,可能出现一种情况,就是已经选择了多个对象;所以,在钩子函数中,我们应当获取当前选择集的最后一个对象,这才是双击的对象,这是通过acedSSName方法来完成的。
 最后效果如下:
在这里插入图片描述

2 实现方法2——反应器

2.1 反应器的作用

 反应器实际上就是给ObjectARX提供了捕获AutoCAD特定事件的接口,例如,通过文档反应器捕获到创建新文档、打开图形文档、关闭图形文档的事件,通过数据库反应器捕获到添加新实体、修改实体、删除实体的事件,就可以针对这些事件做一些特定的处理。
 AutoCAD提供了多种类型的反应器,供ObjectARX处理特定的事件,包括:
 1. 编辑器反应器:AcEditorReactor
 2. 文档反应器:AcApDocManagerReactor
 3. 数据库反应器:AcDbDatabaseReactor
 4. 对象反应器:AcDbObject
 每个反应器的用法都有差异,监控实体双击事件,我们需要使用编辑器反应器。

2.2 利用编辑器反应器监控双击事件

 以下反应器实例监控对象的双击事件,并且当对象是组中成员的时候,在命令行输出组的名称。
 从AcEditorReactor派生出一个新类CDBClickReactor,头文件为:

#pragma onceclass CDBClickReactor : public AcEditorReactor
{
public:CDBClickReactor() {};~CDBClickReactor() {};virtual void beginDoubleClick(const AcGePoint3d& clickPoint);
};

 该类的实现为:

#include "stdafx.h"
#include "CDBClickReactor.h"
#include <dbgroup.h>void CDBClickReactor::beginDoubleClick(const AcGePoint3d& clickPoint)
{//获取预选择集ads_name ss;if (RTNORM != acedSSGet(_T("I"), NULL, NULL, NULL, ss))return;ads_name ent;acedSSName(ss, 0, ent);acedSSFree(ss);AcDbObjectId objId;acdbGetObjectId(objId, ent);AcDbEntity* pEnt = NULL;if (Acad::eOk == acdbOpenObject(pEnt, objId)){const AcDbVoidPtrArray *pReactors;void *pSomething;AcDbObjectReactor *pObjReactor;AcDbObjectId persObjId;AcDbGroup *pGroup;pReactors = pEnt->reactors();if (pReactors != NULL && pReactors->length() > 0) {for (int i = 0; i < pReactors->length(); i++) {pSomething = pReactors->at(i);// Is it a persistent reactor?if (acdbIsPersistentReactor(pSomething)) {persObjId = acdbPersistentReactorObjectId(pSomething);// 如果是组,就打开,输出组名称if ((Acad::eOk == acdbOpenObject(pGroup, persObjId, AcDb::kForRead))){acutPrintf(_T("\n\t当前组的名称为:%s\n"), pGroup->name());pGroup->close();break;}}}}}
}

 关于类的实现,着重说明以下几点:
 1.用户双击对象以后,会进入到CDBClickReactor::beginDoubleClick,我们为了演示方便,针对用户双击组对象的情况,做了特殊处理,输出组的名称;其他情况没有特殊处理。
 2.用户双击组时,实际上双击的是组中的某个成员实体,但是这个实体添加了一个永久反应器,这个永久反应器关联的对象才是组对象。上述例程用到的acdbPersistentReactorObjectId,返回的就是永久反应器关联的实体ID。
 除了上述实现文件以外,需要声明全局变量

CDBClickReactor* g_ReactorDBClick = NULL;

 在加载arx时,往CAD编辑器加载这个反应器

void OnLoadApp()
{//.........省略g_ReactorDBClick = new CDBClickReactor();acedEditor->addReactor(g_ReactorDBClick);
}

 在卸载arx时,需要删掉这个反应器

void OnUnloadApp()
{//.........省略acedEditor->removeReactor(g_ReactorDBClick);delete g_ReactorDBClick;
}

 实现效果如下:
在这里插入图片描述
 以上,就是利用编辑器反应器监控对象双击的简单示例。

这篇关于ObjectARX如何监控实体双击事件(利用钩子函数或者反应器)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/375492

相关文章

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

FreeRTOS内部机制学习03(事件组内部机制)

文章目录 事件组使用的场景事件组的核心以及Set事件API做的事情事件组的特殊之处事件组为什么不关闭中断xEventGroupSetBitsFromISR内部是怎么做的? 事件组使用的场景 学校组织秋游,组长在等待: 张三:我到了 李四:我到了 王五:我到了 组长说:好,大家都到齐了,出发! 秋游回来第二天就要提交一篇心得报告,组长在焦急等待:张三、李四、王五谁先写好就交谁的

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to