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 字符串,因此 “椭圆” 和 “圆” 命令的标识符分别为 CAAAfrEllipseHdrCAAAfrCircleHdr。这两个标识符将与菜单项的启动器相关联。

如何运行 CAACafContextualMenu 用例

有关该用例运行方式的详细说明,请参阅 “CAAGeometry 示例” 用例中题为 **“如何运行 CAAGeometry 用例”** 的章节。具体操作流程如下:
  1. 文件菜单中单击新建
  2. 文件新建对话框中选择 CAAGeometry,然后单击确定
  3. 创建三个点
  4. 创建一个平面
  5. 创建一个椭圆
  6. 在椭圆上单击鼠标右键,并选择命令

查找 CAACafContextualMenu 代码位置

CAACafContextualMenu 用例仅由一个类构成,即 CAAECafContextualMenuEllipse 类,该类位于 CAACATIAApplicationFrm.edu 框架下的 CAACafContextualMenu.m 模块中:
  • Windows 平台:InstallRootDirectory\CAACATIAApplicationFrm.edu\CAACafContextualMenu.m\
  • Unix 平台:InstallRootDirectory/CAACATIAApplicationFrm.edu/CAACafContextualMenu.m/

其中 InstallRootDirectory 为 CAA 光盘的安装根目录。

分步实现

要实现 CATIContextualMenu 接口,需完成两个步骤:
  1. 创建上下文菜单描述类
  2. 创建上下文菜单

创建上下文菜单描述类

创建 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 控件之后。

下图展示了 _pMenu 在添加菜单项前后的对比效果:

图片

 

注释 1

GetContextualMenu 方法返回一个指向 CATCmdContainer 类实例的指针。CATExtIContextualMenu 类会持有该指针,当 CATExtIContextualMenu 类实例被销毁时,该容器以及在当前实现中创建的各类访问对象(控件)将一并被释放。

注释 2

本用例中是获取并扩展了 UIActive 对象的上下文菜单。但你也可以创建自定义上下文菜单:重写 GetContextualMenu 方法,使其返回你自己的 CATCmdContainer 类实例即可。该实例可在构造函数中创建(适用于固定菜单),或在 GetContextualMenu 方法中创建(适用于动态菜单)。

注释 3

CATCmdContainer 类实例销毁(通过调用 Release)时,会自动销毁其所有子对象。

小结

本用例讲解了如何实现上下文菜单,以及如何获取命令头标识符。
 
posted @ 2026-04-20 11:14  Breadss  阅读(4)  评论(0)    收藏  举报