【CAD二次开发】-ObjectARX-双击实体的响应 (AcDbDoubleClickEdit)

思路:

一、基本双击响应实现

(1)在vs2015中使用ObjectARX创建一个新项目DoubleClick,并选择 MFC支持。

向工程中添加一个普通类CDoubleClickCircle,它的基类设置为AcDbDoubleClickEdit:

类的头文件为:

class CDoubleClickCircle :
	public AcDbDoubleClickEdit
{
public:
	CDoubleClickCircle();
	virtual ~CDoubleClickCircle();

	//开始编辑时调用的函数
	void startEdit(AcDbEntity *pEnt, AcGePoint3d pt);

	//完成编辑之后调用的函数
	void finishEdit(void);
};

 (2)startEdit函数是在用户双击指定类型实体之后触发,

实现代码:

void CDoubleClickCircle::startEdit(AcDbEntity *pEnt, AcGePoint3d pt)
{
	//获得当前文档
	AcApDocument *pDoc = acDocManager->curDocument();

	//将AcDbEntity指针转换为AcDbLine指针
	if (pEnt->isKindOf(AcDbCircle::desc()))
	{
		AcDbCircle *pCircle = AcDbCircle::cast(pEnt);

		//锁定文档
		acDocManager->lockDocument(pDoc);

		//将实体的打开状态升级为可写状态
		pCircle->upgradeOpen();

		//指定新的颜色
		pCircle->setColorIndex(1);
		pCircle->close();

		//解锁文档
		acDocManager->unlockDocument(pDoc);

		//清理PickFirst选择集中的内容
		acedSSSetFirst(NULL, NULL);

		//更新图形的显示
		pCircle->draw(); //在关闭之后还能使用
		actrTransactionManager->flushGraphics();
		acedUpdateDisplay();

	}
	else
	{
		acutPrintf(TEXT("\n无效的AcDbCircle对象..."));
		pEnt->close();
		return;
	}
}

(3)本例子并不在finishEdit函数中添加任何处理,但是这个函数的实现部分是一定要有,否则就会产生连接错误。

实现代码:

void CDoubleClickCircle::finishEdit(void)
{
	//此处不处理
}

(4)在acrxEntryPoint.cpp 文件中的  On_kInitAppMsg (void *pkt) 函数中,添加双击处理基类的初始化,并且为圆的实体类型添加AcDbCircle添加双击处理的协议。

实现代码:

	virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
		// TODO: Load dependencies here

		// You *must* call On_kInitAppMsg here
		AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
		
		// TODO: Add your initialization code here

		//初始化AcDbDoubleClickEdit类
		AcDbDoubleClickEdit::rxInit();

		//为AcDbCircle类添加协议扩展
		CDoubleClickCircle *pCircleEdit = new CDoubleClickCircle;
		AcDbCircle::desc()->addX(AcDbDoubleClickEdit::desc(), pCircleEdit);

		return (retCode) ;
	}

(5)在acrxEntryPoint.cpp 文件中的On_kUnloadAppMsg (void *pkt) 函数中,从AcDbCircle类中删除双击处理的协议,确保应用程序在卸载之后圆地双击处理仍然是AutoCAD提供的默认方式。

实现代码:

	virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
		// TODO: Add your code here

		// You *must* call On_kUnloadAppMsg here
		AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;

		// TODO: Unload dependencies here

		//删除AcDbCircle类的协议扩展
		AcDbCircle::desc()->delX(AcDbDoubleClickEdit::desc());

		return (retCode) ;
	}

(6)此时,编译代码,会显示连接错误,在附加依赖项中添加  AcDblClkEditPE.lib

在链接库AcDblClkEditPE.lib 的时候,还是出现了编译错误: 

 是因为 64位的机子你引用了32位的模块。

这时候您先不要着急,继续往下看。

二、通过对话框接收用户输入的颜色值

(1)添加一个对话框资源:

设置ID和caption:

设置字体:

(2)在对话框资源中添加一个标签控件:

 在对话框资源中添加一个文本框控件:

(3)保存工程。使用ObjectARX MFC工具为当前的对话框添加关联的类,类名为CGetColorDlg,基类设置为CAcUiDialog,

(4)添加CGetColorDlg的两个消息映射函数。

添加对话框的初始化消息(WM_INITDIALOG):

 同样的方法,添"确定"消息(OnOK):

(5)添加文本对话框控件IDC_COLOR_INDEX控件的映射成员变量m_colorIndex,并将它的有效范围设置为0~256

右击示例编辑框->添加成员变量:

(6)在OnInitDialog消息中,调用UpdateDate函数来将成员变量的值更新到关联的界面控件中去

实现代码:

BOOL CGetColorDlg::OnInitDialog()
{
	CAcUiDialog::OnInitDialog();

	// TODO:  在此添加额外的初始化
	//根据成员变量更新资源控件
	UpdateData(FALSE);

	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}

 (7)OnOk函数的实现

void CGetColorDlg::OnOK()
{
	// TODO: 在此添加专用代码和/或调用基类
	//根据资源控件更新成员变量
	if (!UpdateData(TRUE))
	{
		return;
	}

	CAcUiDialog::OnOK();
}

(8)在对话框类CGetColorDlg中添加两个成员函数SetParams 和GetParams

声明:

public:
	void SetParams(int colorIndex);
	void GetParams(int &colorIndex);

实现: 

//设置对话框中的初始颜色值:
void CGetColorDlg::SetParams(int colorIndex)
{
	m_colorIndex = colorIndex;
}

//获取对话框中用户输入的新颜色值
void CGetColorDlg::GetParams(int &colorIndex)
{
	colorIndex = m_colorIndex;
}

(9)在  startEdit 函数中添加显示对话框获取用户输入的相关代码

修改DoubleClickCircle.cpp 的 startEdit 函数:

//startEdit函数是在用户双击指定类型实体之后触发
void CDoubleClickCircle::startEdit(AcDbEntity *pEnt, AcGePoint3d pt)
{
	//获得当前文档
	AcApDocument *pDoc = acDocManager->curDocument();

	//将AcDbEntity指针转换为AcDbLine指针
	if (pEnt->isKindOf(AcDbCircle::desc()))
	{
		AcDbCircle *pCircle = AcDbCircle::cast(pEnt);

		//锁定文档
		acDocManager->lockDocument(pDoc);

		//将实体的打开状态升级为可写状态
		pCircle->upgradeOpen();

		//提示用户指定新的颜色
		int oldColorIndex = pCircle->colorIndex();
		CAcModuleResourceOverride myResource; //防止资源冲突
		CGetColorDlg dlg;
		dlg.GetParams(oldColorIndex);
		if (dlg.DoModal() == IDOK)
		{
			int newColorIndex = 0;
			dlg.GetParams(newColorIndex);
			pCircle->setColorIndex(newColorIndex);
		}
		//pCircle->setColorIndex(1);
		pCircle->close();

		//解锁文档
		acDocManager->unlockDocument(pDoc);

		//清理PickFirst选择集中的内容
		acedSSSetFirst(NULL, NULL);

		//更新图形的显示
		pCircle->draw(); //在关闭之后还能使用
		actrTransactionManager->flushGraphics();
		acedUpdateDisplay();

	}
	else
	{
		acutPrintf(TEXT("\n无效的AcDbCircle对象..."));
		pEnt->close();
		return;
	}
}

并添加头文件:

#include "GetColorDlg.h"

三、解决AcDblClkEditPE.lib 连接失败的问题

从AutoCAD2010开始,双击响应不是在 AcDbClkEditPE.arx 中实现,只需要做以下修改:

1)将 On_kInitAppMsg 函数中的下面代码注释掉:

AcDbDoubleClickEdit::rxInit();

2)只在acrxEntryPoint.cpp 文件中添加下面代码(在头文件的后面添加):

ACRX_DEFINE_MEMBERS(AcDbDoubleClickEdit);

 3)工程设置中不在需要依赖AcDbClkEditPE.lib.

此时,编译程序,出现下面错误,

需要包含下下面的头文件即可。 

#include "resource.h"

 此时,打开CAD,加载程序:

可见,程序可以加载了。

此时我们双击圆,发现只会弹出属性对话框:

不要着急,还有最后一步...

四、消除CUI中的双击处理带来的影响

在CAD的命令栏执行命令:CUI

找到 “圆” ,右键->删除:

效果:

编译运行程序,启动AutoCAD2018,加载应用程序,创建一个圆,双击,

圆的颜色发生改变 :

动画效果:
 

完整的实现代码:

https://pan.baidu.com/s/1sVEVzkgVixi7My5ayQhTLg

<本文完> 

猜你喜欢

转载自blog.csdn.net/qq_40416052/article/details/82730799
今日推荐