Editing Objects-使自定义对象支持编辑 / 将对象设为可编辑状态
摘要
-
本用例学习目标
-
CAAAfrGeoEdition 用例
-
- CAAAfrGeoEdition 用例功能说明
- CAAAfrGeoEdition 代码存放位置
-
分步实现
-
内容小结
-
参考文献
本用例学习要点
CAAAfrGeoEdition 用例
CAAAfrGeoEdition 用例功能

CAAAfrGeoEdition 启动方法
- 选择【文件】→【新建】;
- 在新建窗口中选择 CAAGeometry,点击【确定】;
- 使用【基本图元】工具栏,至少创建一个点;
- 右键单击该点,选择【定义】命令。
CAAAfrGeoEdition 代码位置
Windows 系统路径
安装根目录\CAAApplicationFrame.edu\CAAAfrGeoEdition.m\Unix 系统路径
安装根目录/CAAApplicationFrame.edu/CAAAfrGeoEdition.m/其中,安装根目录 指 CAA 安装包的安装目录。
- CAAEAfrEditPoint:CAASysPoint 组件的扩展类
- CAAAfrPointEditCmd:编辑命令类
- CAAAfrPointEditDlg:编辑命令对应的对话框类
分步实现
| 序号 | 操作步骤 | 对应实现类 |
|---|---|---|
| 1 | 令点对象实现 CATIEdit 接口 | CAAEAfrEditPoint 类 |
| 2 | 创建编辑命令 | CAAAfrPointEditCmd 类 |
| 3 | 创建编辑对话框 | CAAAfrPointEditDlg 类 |
使点对象实现 CATIEdit 接口
创建 CAAEAfrEditPoint 类的头文件
#include "CATExtIEdit.h" // 继承 CATExtIEdit 必需的头文件
class CAAEAfrEditPoint : public CATExtIEdit
{
CATDeclareClass;
public :
CAAEAfrEditPoint();
virtual ~CAAEAfrEditPoint();
virtual CATCommand * Activate(CATPathElement * iPath);
private :
// 禁用拷贝构造函数
CAAEAfrEditPoint(const CAAEAfrEditPoint &iObjectToCopy);
};
说明:CATDeclareClass 宏声明 CAAEAfrEditPoint 属于一个组件。该类仅重写 CATIEdit 接口的 Activate 方法。
在类的源文件中添加对象建模器代码
...
CATImplementClass(CAAEAfrEditPoint,
DataExtension,
CATBaseUnknown,
CAASysPoint);
#include "TIE_CATIEdit.h"
TIE_CATIEdit(CAAEAfrEditPoint);
...
CATImplementClass宏的含义:CAAEAfrEditPoint 是 CAASysPoint 的数据扩展类。- 对于所有类型的扩展,第三个参数必须固定为
CATBaseUnknown或CATNull。 TIE宏为 CATIEdit 接口创建对应的 TIE 类。
实现 Activate 方法
...
CATCommand * CAAEAfrEditPoint::Activate(CATPathElement * pPath)
{
CAAAfrPointEditCmd * pEdtCmd = NULL;
CAAISysPoint * pISysPointOnPoint = NULL;
HRESULT rc = QueryInterface(IID_CAAISysPoint, (void**)&pISysPointOnPoint);
if (SUCCEEDED(rc))
{
CAAAfrPointEditCmd * pEdtCmd = new CAAAfrPointEditCmd(pISysPointOnPoint);
pISysPointOnPoint->Release();
}
return (CATCommand*) pEdtCmd;
}
Activate 方法执行流程:
- 获取对象接口指针
首先获取待编辑对象所实现的接口指针,用于传递给编辑对话框。此处选择获取 CAASysPoint 的类型接口指针,因为该接口提供了管理对象参数的方法 —— 我们需要在对话框中显示并修改这些参数,即点的坐标。 - 构建编辑命令对象
创建编辑命令类CAAAfrPointEditCmd的实例,并将上述待编辑对象的指针传入该命令。 - 返回编辑命令指针
最终以CATCommand基类指针的形式返回创建的编辑命令。
创建编辑命令
该命令除了重写从 CATCommand 继承的三个方法(用于管控命令可用性与生命周期:Activate、Desactivate、Cancel)以外,还包含 CloseBox 方法。当用户关闭编辑对话框时,会触发该方法,请求销毁对话框。
CAAAfrPointEditCmd.cpp 源码内容。下面以事件驱动的逻辑逐段解析。构造函数
CAAAfrPointEditCmd::CAAAfrPointEditCmd(CAAISysPoint * ipEdit)
: CATCommand ("PointEditCommandId",CATCommandModeExclusive),
_pEdit(ipEdit),_DialogPoint(NULL)
{
if (_pEdit) _pEdit -> AddRef();
}
构造函数在调用父类 CATCommand 构造时,传入第二个参数 CATCommandModeExclusive,将当前命令设为独占模式,会终止所有正在运行的其他命令。所有会修改文档内容的命令,都必须设置为独占模式。同时,构造函数获取待编辑对象的 CAAISysPoint 接口指针,并手动增加引用计数。
Activate 方法
CATStatusChangeRC CAAAfrPointEditCmd::Activate(CATCommand *iCmd,
CATNotification *iNotif)
{
if ( ! _DialogPoint)
{
CATDlgStyle style = CATDlgWndOK|CATDlgWndAPPLY|CATDlgWndCANCEL|
CATDlgWndHELP| // Unix 平台帮助按钮(长帮助)
CATDlgWndTitleBarHelp| // 标题栏帮助(仅 Windows 平台)
CATDlgGridLayout ;
CATString id ("CAAAfrPointEditDlgId");
CATDialog * pParent = (CATApplicationFrame::GetFrame())->GetMainWindow() ;
_DialogPoint = new CAAAfrPointEditDlg(pParent,id,style,_pEdit);
AddAnalyseNotificationCB(_DialogPoint, _DialogPoint->GetWindCloseNotification(),
(CATCommandMethod)&CAAAfrPointEditCmd::CloseBox,
NULL);
_DialogPoint->Build();
}
_DialogPoint->SetVisibility(CATDlgShow);
return (CATStatusChangeRCCompleted);
}
- 若对话框未创建,则定义对话框样式:包含确定、应用、取消、帮助按钮,并启用网格布局;
- 获取应用主窗口作为对话框父级窗口;
- 实例化点编辑对话框,并传入点对象接口指针;
- 注册窗口关闭消息回调,绑定至
CloseBox方法; - 执行对话框初始化构建;
- 显示对话框,返回命令执行完成状态。
当命令选择器将焦点赋予当前命令时,就会触发 Activate 方法执行。触发场景包括:用户手动选中该命令,或是当前命令被共享命令置为非激活状态后重新获得焦点。
Activate 会新建对话框、将其显示,并返回方法正常执行完成。- 第一个参数:传入命令树结构中的父级对象。对话框的父级通常应为其他对话框,因此这里统一设置为框架主窗口。
- 第二个参数:传入对话框名称。
- 样式组合参数:组合样式标识,使对话框自带确定(OK)、应用(Apply)、** 取消(Cancel)** 三个按钮。
- 在 UNIX 系统下,会额外显示 ** 帮助(Help)** 按钮;
- 在 Windows 系统下,则在标题栏显示问号帮助图标;
- 同时指定对话框采用网格布局进行页面排版。
- 第四个参数:传入
CAAISysPoint接口指针,用于操作目标点对象。
Build 方法,完成界面控件的初始化与布局填充。原因是:构造阶段资源文件可能尚未完成加载。界面赋值、文本填充等初始化逻辑统一交由 Build 方法实现,完成后即可正常显示对话框。更多细节可参考「创建编辑对话框」章节。
其余方法实现与说明如下:
CATStatusChangeRC CAAAfrPointEditCmd::Desactivate(CATCommand * iCmd,
CATNotification * iNotif)
{
_DialogPoint->SetVisibility(CATDlgHide);
return (CATStatusChangeRCCompleted);
}
CATStatusChangeRC CAAAfrPointEditCmd::Cancel(CATCommand * iCmd,
CATNotification * iNotif)
{
_DialogPoint->SetVisibility(CATDlgHide);
RequestDelayedDestruction();
return (CATStatusChangeRCCompleted);
}
void CAAAfrPointEditCmd::CloseBox(CATCommand * iSendingCommand,
CATNotification * iSentNotification,
CATCommandClientData iUsefulData)
{
_DialogPoint->SetVisibility(CATDlgHide);
RequestDelayedDestruction();
}
方法功能说明
- Desactivate(停用)
当命令选择器收回当前命令焦点时调用,常见于被共享命令抢占焦点的场景。该命令会保留在命令栈中,待共享命令执行完毕后可重新恢复焦点。方法仅隐藏对话框,不销毁任何资源,避免命令停用期间用户误操作;保留资源以便后续重新获取焦点时快速恢复对话框。 - Cancel(取消)
当命令永久失去焦点、需要销毁时触发,一般在用户切换至其他独占式命令时调用。该方法隐藏对话框,并申请延迟销毁当前编辑命令。 - CloseBox(关闭窗口)
用户点击确定、取消按钮,或直接关闭对话框窗口时触发。功能逻辑与 Cancel 一致,但它是对话框消息回调触发,而非由命令选择器主动调用。RequestDelayedDestruction用于通知命令选择器释放当前命令焦点,系统会自动切换并激活默认命令(通常为选择命令)。
析构函数由 RequestDelayedDestruction 触发执行,会先移除对话框绑定的消息回调,再申请销毁对话框对象:
CAAAfrPointEditCmd::~CAAAfrPointEditCmd()
{
if (_DialogPoint)
{
RemoveAnalyseNotificationCB(_DialogPoint,
_DialogPoint->GetWindCloseNotification(),
NULL);
_DialogPoint->RequestDelayedDestruction();
}
}
创建编辑对话框
Activate 方法创建生成的。该对话框高度依赖待编辑对象本身,其设计与编码方式和普通对话框完全一致:采用空构造函数,并依靠 Build 方法完成界面构建。以下为 CAASysPoint 类对应的编辑对话框实现说明:

- 确定(OK) 按钮:应用新参数并关闭对话框;
- 应用(Apply) 按钮:仅保存修改参数,对话框保持打开;
- 取消(Cancel) 按钮:关闭窗口,还原坐标初始值。
Build 方法负责创建界面控件、完成对话框布局,同时从资源文件读取文本标签、或通过 CAAISysPoint 接口读取数值并完成界面赋值。ClickOK、ClickApply、ClickCancel、CloseBox。确定按钮回调 — ClickOK
void CAAAfrPointEditDlg::ClickOK(CATCommand * iSendingCommmand,
CATNotification * iSentNotification,
CATCommandClientData UsefulData)
{
ModifyModelAndVisu(_XSpinner->GetCurrentValue(),
_YSpinner->GetCurrentValue(),
_ZSpinner->GetCurrentValue());
CloseBox();
}
用户点击确定按钮时触发该方法。首先调用 ModifyModelAndVisu,读取三个坐标微调框的当前值,完成点坐标修改与视图刷新;随后调用 CloseBox 方法,执行对话框关闭逻辑。
应用按钮回调 — ClickApply
void CAAAfrPointEditDlg::ClickApply(CATCommand * iSendingCommmand,
CATNotification * iSentNotification,
CATCommandClientData UsefulData)
{
ModifyModelAndVisu(_XSpinner->GetCurrentValue(),
_YSpinner->GetCurrentValue(),
_ZSpinner->GetCurrentValue());
}
用户点击应用按钮时触发。功能与确定按钮一致:更新点坐标并刷新显示,但不会关闭对话框,界面保持打开状态。
取消按钮回调 — ClickCancel
void CAAAfrPointEditDlg::ClickCancel(CATCommand * iSendingCommmand,
CATNotification * iSentNotification,
CATCommandClientData UsefulData)
{
ModifyModelAndVisu(_Xfirst,_Yfirst,_Zfirst);
CloseBox();
}
用户点击取消按钮时触发。读取保存的初始 X/Y/Z 坐标,还原点原始数据并刷新视图,最后关闭对话框。
窗口关闭回调 — ClickClose
void CAAAfrPointEditDlg::ClickClose(CATCommand * iSendingCommmand,
CATNotification * iSentNotification,
CATCommandClientData UsefulData)
{
CloseBox();
}
用户点击窗口关闭按钮时执行,直接调用 CloseBox 完成关闭流程。
窗口关闭核心方法 — CloseBox
void CAAAfrPointEditDlg::CloseBox()
{
SetVisibility(CATDlgHide);
RemoveAnalyseNotificationCB(this, this->GetDiaOKNotification(),NULL);
RemoveAnalyseNotificationCB(this, this->GetDiaAPPLYNotification(),NULL);
RemoveAnalyseNotificationCB(this, this->GetDiaCANCELNotification(),NULL);
RemoveAnalyseNotificationCB(this, this->GetWindCloseNotification(),NULL);
SendNotification(GetFather(),CATDlgDialog::GetWindCloseNotification());
}
该方法首先隐藏对话框,再逐一移除确定、应用、取消、窗口关闭的消息回调,避免内存泄漏与消息残留。随后向父级窗口发送窗口关闭通知。该父窗口在对话框构造时被指定为程序框架主窗口。关闭通知会沿着命令树向上传递,直至匹配到注册了对应回调的命令。由于上层通常无匹配命令,通知最终会送达命令选择器,并转发至当前激活的编辑命令,触发其绑定的关闭回调方法。
模型与视图更新方法 — ModifyModelAndVisu
void CAAAfrPointEditDlg::ModifyModelAndVisu(const float iX, const float iY, const float iZ)
{
_pPointEdit->SetCoord(iX, iY, iZ);
CATIModelEvents * pModelEvents = NULL;
HRESULT rc = _pPointEdit -> QueryInterface(IID_CATIModelEvents, (void**)&pModelEvents);
if (SUCCEEDED(rc))
{
CATModify * pNotif = new CATModify(pModelEvents);
pModelEvents->Dispatch(*pNotif);
delete pNotif;
pModelEvents->Release();
}
}
- 调用
SetCoord写入新的 X、Y、Z 坐标; - 查询模型事件接口
CATIModelEvents; - 构造模型修改事件并分发通知,通知框架数据已变更;
- 释放临时资源与接口指针,保证内存安全。
简要总结
专属编辑对话框的开发方式与普通对话框完全一致:通过各类控件绑定的回调函数,调用对象自身接口修改业务数据;同时向可视化管理器分发更新通知,刷新对象的图形显示。

浙公网安备 33010602011771号