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

news2024/12/27 13:48:53

目录

  • 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 once

class 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;
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/622483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于html+css的图展示115

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

2023年湖北下半年中级职称申报中级职称评审申报条件是什么?

2023年湖北下半年中级职称申报中级职称评审申报条件是什么&#xff1f; 2023年湖北中级职称申报条件&#xff1a;本科毕业5年&#xff0c;专科毕业7年&#xff0c;相关专业 助工满4年这个条件目前不是硬性要求&#xff0c;意思就是有肯定更好&#xff0c;没有也没有太大的影响 …

穿越火线几次体验良好的游戏优化方案

文章目录 介绍救世主模式终结者模式30人生化模式挑战模式英雄级武器源武器英雄级武器皮肤英雄级武器游戏玩偶英雄级武器万化包、光效英雄级武器强化英雄级武器音效卡免费获取挑战强化武器戒指击杀效果个人竞技击杀效果人机训练模式交易所火线币快速加入跳跳乐爆头战HS间谍模式地…

做了一个日内信号可视化系统

量化策略开发&#xff0c;高质量社群&#xff0c;交易思路分享等相关内容 大家好&#xff0c;半年过去了。松鼠Quant计划6月内发布本年度最重要的一个策略:盘口策略。这个策略群友们的呼声很高&#xff0c;也是花了比较多时间去弄。整个策略有多个python脚本: CTP数据生成order…

如何提高浪涌保护器的使用寿命和安全性

浪涌保护是保护设施免受电气事件影响的基本要求。具体来说&#xff0c;浪涌保护器&#xff08;SPD&#xff09;旨在限制瞬态电压并转移浪涌电流以保护系统和设备。 SPD浪涌保护器必须考虑的一种现象是临时过电压&#xff08;TOV&#xff09;。传统设备处理 TOV 的方式可能会导…

【unity数据持久化】游戏排行榜信息简单的存储,你还知道吗?数据管理类_PlayerPrfs

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

谈一谈冷门的C语言爬虫

C语言可以用来编写爬虫程序&#xff0c;但是相对于其他编程语言&#xff0c;C语言的爬虫开发可能会更加复杂和繁琐。因为C语言本身并没有提供现成的爬虫框架和库&#xff0c;需要自己编写网络请求、HTML解析等功能。 不过&#xff0c;如果你对C语言比较熟悉&#xff0c;也可以…

FPGA认识-LCMXO3LF-9400C-5BG400C 什么是低功耗FPGA

莱迪思深力科超低密度FPGA 是最新的立即启用、非挥发性、小型覆盖区 FPGA&#xff0c;采用先进的封装技术&#xff0c;能让每个元件达到最低成本。此系列采用最新的小型封装&#xff0c;不仅具有低功率、成本优势并结合快速效能。FPGA 现场可编程逻辑器件,小尺寸&#xff0c;高…

SSRS rdlc报表 八 报表项目部署

开发环境 vs2022 sqlserver 2019 windows 11 参考文档&#xff1a;安装 SQL Server Reporting Services - SQL Server Reporting Services (SSRS) | Microsoft Learn 配置 URL (Configuration Manager) - SQL Server Reporting Services (SSRS) | Microsoft Learn 项目右键…

问道价值互联网,区块链的下一个十年 | 2023 开放原子全球开源峰会区块链分论坛即将启幕

随着全球 Web3 浪潮经由数字藏品、元宇宙的日渐普及而实现落地&#xff0c;区块链在“信息互联网”转向“价值互联网”中的重要作用正得到进一步认可。在数字经济蓬勃发展、数据成为重要生产要素的时代&#xff0c;区块链已不仅仅是一项技术、一种工具&#xff0c;更是一种思维…

大型城市综合体建筑智能消防应急照明和疏散系统的具体应用 安科瑞 许敏

摘要&#xff1a;随着我国社会经济的迅猛发展与城市化建设进程的加快&#xff0c;大型城市综合体建筑越来越多&#xff0c;随之而来的消防安全管理问题不容忽视。智能消防应急照明和疏散系统作为保证人员安全疏散不可或缺的消防设施&#xff0c;是保障消防安全的重要组成部分。…

重磅!MyBatis-Plus 可视化代码生成器来啦,开发效率提升2倍 !!

前言 一、mybatis-plus-generator-ui是什么&#xff1f; 二、 mybatis-plus-generator-ui怎么用&#xff1f; 1、maven pom引入2、新建程序入口&#xff0c;以main函数的方式运行3、实例运行 三、mybatis-plus-generator-ui代码生成 1、Table的查询和浏览2、输出配置3、策…

Vue+springboot茶馆管理系统的设计与实现

在网络购物的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;茶馆只能以客户为导向&#xff0c;按茶叶分类&#xff0c;以商品的持续创新作为商家最重要的竞争手段。 系…

JDK8-1-Lambda表达式(2)-方法传递(行为参数化)

JDK8-1-Lambda表达式&#xff08;2&#xff09;-方法传递&#xff08;行为参数化&#xff09; Java 8 允许程序将方法作为参数传递&#xff0c;先看一个例子&#xff1a; 苹果实体类&#xff1a; public class Apple {//颜色private String color;//重量&#xff0c;单位克&…

【Golang Leetcode】总目录(Day1~100)

Leetcode Golang Day1~10 Golang每日一练(leetDay0001) 1. 两数之和 Two Sum 2. 两数相加 Add Two Numbers 3. 无重复字符的最长子串 Longest-substring-without-repeating-characters Golang每日一练(leetDay0002) 4. 寻找两个正序数组的中位数 Median of two sorted arra…

【算法系列之链表I】leetcode206.反转链表

203.移除链表元素 力扣题目链接 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]解题思路 核心思路就是…

Hive数据类型和文件格式

文章目录 Hive数据类型和文件格式1 基本数据类型2. 集合数据类型2.1 Struct举例2.2 Array举例2.3 Map举例 3 数据类型转换3.1 隐式转换3.2 显示转换 4 文本文件数据编码 Hive数据类型和文件格式 Hive支持关系数据库中的大多数基本数据类型&#xff0c;同时也支持3种新的集合数…

KDZD绝缘油介质损耗电阻率测试仪参数

一、概述 测试仪依据GB/T5654-2007《液体绝缘材料相对电容率、介质损耗因数和直流电阻率的测量》设计制造。用于绝缘油等液体绝缘介质的介质损耗因数和直流电阻率的测量。 一体化结构。内部集成了介损油杯、温控仪、温度传感器、介损测试电桥、交流试验电源、标准电容器、高阻计…

无线无源中继采发仪在工程监测中的应用

无线无源中继采发仪在工程监测中的应用 随着科技的不断发展&#xff0c;无线传感技术在工程监测中的应用越来越广泛。其中&#xff0c;无线无源中继采发仪是一种新型的数据采集设备&#xff0c;能够将传感器数据通过无线信号传输到数据中心。本文旨在探讨无线无源中继采发仪在…

Scrum敏捷项目管理

在了解敏捷项目管理之前&#xff0c;我们先看下敏捷和传统项目管理有什么区别。 传统项目管理&#xff1a;阶段式项目管理模式。 制定详细的计划和步骤&#xff0c;按计划执行&#xff0c;直到所有的计划执行全部结束。咖 敏捷项目管理模式&#xff0c;从愿景和高价值的目标出…