Inserting Commands in Contextual Menus-实现 CATIContextualMenu 接口
摘要
本文演示了当选择命令为活动命令时,如何在上下文菜单中插入命令。
- 本用例将学习的内容
- CAACafContextualMenu 用例
- CAACafContextualMenu 的功能
- 如何运行 CAACafContextualMenu
- 在哪里可以找到 CAACafContextualMenu 代码
- 分步实现
- 简要总结
- 参考文献
通过本用例您将学到什么
本用例旨在向您演示,当选择命令为当前活动命令时,如何在对象的上下文菜单中插入命令。简单来说,本文将讲解如何实现 CATIContextualMenu 接口。
CAACafContextualMenu 用例
CAACafContextualMenu 是 CAACATIAApplicationFrm.edu 框架的一个用例,用于演示 CATIAApplicationFrame 框架的各项功能。
CAACafContextualMenu 实现的功能
CAACafContextualMenu 可以让你在选择命令激活期间,右键单击椭圆对象时,显示如下上下文菜单:

该菜单分为三部分:
- 当前窗口添加到菜单中的项。居中图形、适配显示等项由 CATFrmGraphAnd3DWindow 类添加。这部分与椭圆上的 CATIContextualMenu 接口实现无关。
- 在 UIActive 对象的上下文菜单中定义、并由椭圆上的 CATIContextualMenu 实现添加到菜单中的项 [1]。
- 由椭圆上的 CATIContextualMenu 实现自行定义并添加到菜单中的项。
这两个命令分别是椭圆和圆,它们是在 “CAA 几何” 文档所属工作台中定义的命令。若要复用这些命令,你需要获取它们的命令头标识符 [2]。使用工作台展示命令即可查找到这些标识符。
启动 CATIA,待程序加载完成后:
- 在文件菜单中单击新建
- 在文件新建对话框中选择 CAA 几何,然后单击确定
- 在工具菜单中单击自定义
- 弹出自定义对话框:
- 切换到命令选项卡
- 选择 XCAA2 类别
- 将工作台展示命令拖放到任意工具栏
- 单击关闭
- 运行工作台展示命令
![图片]()
-
选择 CAAAfrGeometryWks 工作台
- 在目录编辑器中输入一个路径
- 点击打印—— 将生成 CAAAfrGeometryWks.txt 文件
- 点击确定
-
在 CAAAfrGeometryWks.txt 文件中查找 “Ellipse”(椭圆)和 “Circle”(圆)字符串:

命令头实例的标识符为对应的 Id 字符串,因此 “椭圆” 和 “圆” 命令的标识符分别为 CAAAfrEllipseHdr 和 CAAAfrCircleHdr。这两个标识符将与菜单项的启动器相关联。
如何运行 CAACafContextualMenu 用例
有关该用例运行方式的详细说明,请参阅 “CAAGeometry 示例” 用例中题为 **“如何运行 CAAGeometry 用例”** 的章节。具体操作流程如下:
- 在文件菜单中单击新建
- 在文件新建对话框中选择 CAAGeometry,然后单击确定
- 创建三个点
- 创建一个平面
- 创建一个椭圆
- 在椭圆上单击鼠标右键,并选择圆命令
查找 CAACafContextualMenu 代码位置
CAACafContextualMenu 用例仅由一个类构成,即 CAAECafContextualMenuEllipse 类,该类位于 CAACATIAApplicationFrm.edu 框架下的 CAACafContextualMenu.m 模块中:
- Windows 平台:
InstallRootDirectory\CAACATIAApplicationFrm.edu\CAACafContextualMenu.m\ - Unix 平台:
InstallRootDirectory/CAACATIAApplicationFrm.edu/CAACafContextualMenu.m/
其中 InstallRootDirectory 为 CAA 光盘的安装根目录。
分步实现
要实现 CATIContextualMenu 接口,需完成两个步骤:
- 创建上下文菜单描述类
- 创建上下文菜单
创建上下文菜单描述类
创建 CAAECafContextualMenuEllipse.h 文件
#include "CATExtIContextualMenu.h"
class CAAECafContextualMenuEllipse : public CATExtIContextualMenu
{
CATDeclareClass;
public:
CAAECafContextualMenuEllipse();
virtual ~CAAECafContextualMenuEllipse();
private:
CAAECafContextualMenuEllipse(const CAAECafContextualMenuEllipse &iObjectToCopy);
CAAECafContextualMenuEllipse& operator = (const CAAECafContextualMenuEllipse
&iObjectToCopy);
};
该实现类继承自 CATExtIContextualMenu 适配器类。
创建 CAAECafContextualMenuEllipse.cpp 文件
#include "CAAECafContextualMenuEllipse.h"
#include "CATCreateWorkshop.h"
CATImplementClass(CAAECafContextualMenuEllipse,
DataExtension, CATBaseUnknown,
CAASysEllipse);
#include "TIE_CATIContextualMenu.h"
TIE_CATIContextualMenu(CAAECafContextualMenuEllipse);
...
借助 TIE_CATIContextualMenu 宏,CAAECafContextualMenuEllipse 类声明其实现了 CATIContextualMenu 接口。通过 DataExtension 关键字,CATImplementClass 宏将 CAAECafContextualMenuEllipse 类声明为数据扩展对象,用于扩展 CAASysEllipse 类。对于任何类型的扩展,第三个参数必须始终设置为 CATBaseUnknown 或 CATNull。
...
CAAEMmrCombinedCurveContSubMenu::CAAEMmrCombinedCurveContSubMenu()
{
// 创建上下文菜单
}
CAAEMmrCombinedCurveContSubMenu::~CAAEMmrCombinedCurveContSubMenu()
{
}
构造函数中包含主体代码,而析构函数为空。
更新接口字典
更新接口字典文件(例如名为 CAACATIAApplicationFrm.dico 的文件)。该文件所在目录路径会在运行时被拼接进 CATDictionaryPath 环境变量中。文件内需包含如下声明,用于指明 CAASysEllipse 组件实现了 CATIContextualMenu 接口,且其代码位于 libCAACafContextualMenu 共享库或动态链接库(DLL)中。
CAASysEllipse CATIContextualMenu libCAACafContextualMenu
创建上下文菜单
在本用例中,首先获取与UIActive对象关联的上下文菜单。这一操作通过适配器类的
GetContextualMenu方法实现。随后,向这个名为pMenu的菜单中添加圆和椭圆两个命令,同时添加一条分隔线。...
CATCmdContainer * pMenu = NULL ;
// 获取上下文菜单
CATExtIContextualMenu::GetContextualMenu(pMenu);
if ( NULL != pMenu )
{
// 创建命令启动器与分隔条对象
NewAccess(CATCmdStarter,pStEllipse,CAACafContextualMenuEllipseStr);
NewAccess(CATCmdStarter,pStCircle,CAACafContextualMenuCircleStr);
NewAccess(CATCmdSeparator,pSep1,CAACafContextualMenuSep);
// 为启动器绑定对应的命令头
SetAccessCommand(pStEllipse,"CAAAfrEllipseHdr");
SetAccessCommand(pStCircle,"CAAAfrCircleHdr");
// 将椭圆命令添加为菜单的子项
AddAccessChild(pMenu,pStEllipse);
// 设置菜单项的先后顺序:椭圆 → 圆 → 分隔线
SetAccessNext(pStEllipse,pStCircle);
SetAccessNext(pStCircle,pSep1);
}
...
菜单 pMenu 的构建通过 CATCreateWorkshop 文件中包含的宏完成:
- NewAccess
- 使用
NewAccess宏创建命令启动器,类型为CATCmdStarter实例。pStEllipse是用于管理该实例指针的变量,CAACafContextualMenuEllipseStr是其标识符。 - 同样使用
NewAccess宏创建分隔条控件,类型为CATCmdSeparator实例。pSep1是用于管理该实例指针的变量,CAACafContextualMenuSep是其标识符。
- 使用
- SetAccessCommand
- 使用
SetAccessCommand宏将命令头与命令启动器相关联。该宏的第二个参数为命令头标识符,即命令头构造函数的第一个参数,例如CAAAfrEllipseHdr。 - 在实现上下文菜单或上下文子菜单时,不建议直接创建命令头。因此,你应复用之前已创建好的命令头标识符。
为确保菜单被调用时命令头能够正常创建,应使用在工作台或工作台插件中创建的标识符。
- 有关命令头标识符复用的完整说明,请参阅题为《命令头》[2] 的技术文章。
- 使用
-
AddAccessChild / SetAccessNext
- AddAccessChild 宏用于将
pStEllipse控件关联到_pMenu的最后一个控件上。SetAccessNext 宏用于将其他控件依次串联到pStEllipse控件之后。
- AddAccessChild 宏用于将
下图展示了 _pMenu 在添加菜单项前后的对比效果:

注释 1
GetContextualMenu 方法返回一个指向 CATCmdContainer 类实例的指针。CATExtIContextualMenu 类会持有该指针,当 CATExtIContextualMenu 类实例被销毁时,该容器以及在当前实现中创建的各类访问对象(控件)将一并被释放。
注释 2
本用例中是获取并扩展了 UIActive 对象的上下文菜单。但你也可以创建自定义上下文菜单:重写 GetContextualMenu 方法,使其返回你自己的 CATCmdContainer 类实例即可。该实例可在构造函数中创建(适用于固定菜单),或在 GetContextualMenu 方法中创建(适用于动态菜单)。
注释 3
CATCmdContainer 类实例销毁(通过调用 Release)时,会自动销毁其所有子对象。
希望和大家一起交流学习


浙公网安备 33010602011771号