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