
思路:

一、基本双击响应实现
(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
<本文完>




![[ObjectARX] ArxDbg介绍、自动加载及其下载-卡核](https://www.caxkernel.com/wp-content/uploads/2022/08/20220827091756-6309e1442305c-259x300.png)










