Creating a Property Page for Application Properties-自定义 工具 -> 选项

摘要

本文介绍如何为指定工作台,在「工具 - 选项」对话框的属性表单中添加自定义属性页

通过本用例你将掌握的内容

CAACafEltToolsOptions 用例

  • CAACafEltToolsOptions 功能说明
  • 如何运行 CAACafEltToolsOptions 用例
  • CAACafEltToolsOptions 源码路径

实现步骤

内容小结

参考资料

 

通过本用例你将学到什么

本用例旨在演示如何为指定工作组或工作台创建属性页 [1]。阅读本文前,请务必先参阅技术文档《应用程序属性访问》[2]。
每个属性页包含若干选项,这些选项以设置属性的方式进行管理 [3]:相关配置会持久化保存到磁盘的设置文件中,同时在内存中由 CATSettingRepository 类实例进行维护。

「工具 - 选项」命令和其他所有命令一样,禁止直接操作设置仓库,只能通过对应的设置控制器进行交互 [4]。

CAACafEltToolsOptions 用例

CAACafEltToolsOptions 是 CAACATIAApplicationFrm.edu 框架下的一个示例用例,用于演示 CATIAApplicationFrame 应用框架的功能特性。

CAACafEltToolsOptions 功能作用

CAACafEltToolsOptions 会创建图元属性页,该属性页包含三个框架:标识符每条曲线最大点数隐含点
此属性页关联至开始菜单基础架构子菜单中的 CAA V5:几何创建 工作台 [1]。对应的对话框界面如下所示:

图片

 对话框左侧区域以树形结构专供工作组 / 工作台选择使用。右侧区域则显示所选工作组或工作台对应的属性表单。该树形结构会在运行时依据已加载的工作组与工作台自动生成。

CAA V5:几何创建 工作台的属性表单仅包含一个名为图元的属性页,其中设有三个分组框架:

  1. **“标识符”** 分组框架用于管控当前工作台可创建图元的标识符显示状态。
  • 图元标识符可设置为永久以下三种状态:  
  • 隐藏
  • 始终显示
  • 仅预选图元时显示(即鼠标悬停在图元上方时显示)
    该属性可通过三个单选按钮进行设置。
  1. **“每条曲线最大点数”** 分组框架用于设置一条曲线允许包含的最大点数。该配置可通过滑块调节,取值范围为 2 至 100
  2. **“隐含点”** 分组框架用于控制隐含点的显示或隐藏状态。可通过两个单选按钮对该属性进行设置。

这三项配置选项会保存在名为 CAACafGeometryEltSetting.CATSetting 的设置文件中,并由设置控制器进行管理。

该控制器是一个名为 CAACafGeometryEltSettingCtrl 的组件 [5]。此组件实现了以下接口:

  1. CATIIniSettingManagment该接口定义于交互接口框架中,用于管理设置仓库的通用方法,如提交(Commit)、保存(Save)等。
  2. CAAICafGeometryEltSettingAtt该接口专为当前设置文件定制,允许各应用程序在无需了解内部存储结构的前提下,读取和修改设置属性。

如何运行 CAACafEltToolsOptions

如需了解本用例的详细运行步骤,请参阅 《CAAGeometry 示例》 用例中标题为 **「如何运行 CAAGeometry 用例」** 的章节。
但在启动运行之前,需要编辑接口字典文件:
CAACATIAApplicationFrm.edu.dico该文件位于 CAACATIAApplicationFrm.edu 框架的字典目录下:
Windows 系统路径安装根目录\CAACATIAApplicationFrm.edu\CNext\code\dictionary\
UNIX 系统路径安装根目录/CAACATIAApplicationFrm.edu/CNext/code/dictionary/
其中 InstallRootDirectory 指 CAA 安装光盘的安装根目录
在该文件中,移除以下两行前面的 # 号,然后运行 mkCreateRuntimeView 命令。
# CAACafElementPropertyPageEdt CATIUserSettings libCAACafEltToolsOptions
# CAACafViewPropertyPageEdt    CATIUserSettings libCAACafViewToolsOptions

第二行对应视图属性页,该属性页由另一个未做说明的用例 CAACafViewToolsOptions 创建,此用例位于 CAACafViewToolsOptions.m 模块中。

然后,在执行 mkrun 命令的窗口中,不要在命令行输入模块名称,而是输入 CNEXT。应用程序就绪后,请执行以下操作:

  • 指向【工具】并点击【选项】
  • 在对话框左侧点击【基础结构】
  • 在显示的工作台列表中,点击 CAA V5:几何创建

CAACafEltToolsOptions 代码的查找位置

CAACafEltToolsOptions 用例由各类类与接口组成,这些内容存放于 CAACafEltToolsOptions.m 模块,以及 CAACATIAApplicationFrm.edu 框架的 ** 受保护接口(ProtectedInterfaces)** 目录中:

  • Windows 系统:安装根目录\CAACATIAApplicationFrm.edu\CAACafEltToolsOptions.m\
  • Unix 系统:安装根目录/CAACATIAApplicationFrm.edu/CAACafEltToolsOptions.m/

其中,安装根目录指 CAA 光盘的安装目录。

这些类和接口分别为:

CAACafElementPropertyPageEdt  属性页编辑器类

CAACafElementPropertyPageEdtFactory  属性页编辑器类的工厂类

CAAICafElementPropertyPageEdtFactory  由 CAACafElementPropertyPageEdtFactory 实现的工厂接口

TIE_CAAICafElementPropertyPageEdtFactory  工厂接口的 TIE 类(接口实现绑定类)

CAACafElementPropertyPageDlg  与属性页关联的对话框类

分步流程

创建一个属性页,主要包含七个步骤:
  1. 创建属性页编辑器工厂接口
  2. 创建属性页编辑器工厂
  3. 创建属性页编辑器
  4. 配置属性页编辑器资源
  5. 创建属性页对话框
  6. 配置属性页对话框资源
  7. 以管理员模式进行测试

创建属性页编辑器工厂接口

该工厂接口命名为 CAAICafElementPropertyPageEdtFactory。创建此接口需要生成以下文件:
  • 头文件
  • 源文件
  • TIE 接口绑定源文件(tsrc 文件)

具体说明如下。

头文件:CAAICafElementPropertyPageEdtFactory.h 内容如下

#include <CATIGenericFactory.h>

 

extern IID IID_CAAICafElementPropertyPageEdtFactory;

 

class CAAICafElementPropertyPageEdtFactory : public CATIGenericFactory

{

  CATDeclareInterface;  

  public :

};

 

工厂接口是一种接口,也就是继承自 CATIGenericFactory 的抽象类。与所有接口一样,它拥有一个以 IID_ 开头、后接接口名称的接口标识符(IID),并且包含 CATDeclareInterface 宏,该宏用于声明此抽象类为一个接口。除了 CATIGenericFactory 自带的方法外,无需定义额外方法。不要忘记添加 TIE 编译器所要求的 public 关键字。

源文件:CAAICafElementPropertyPageEdtFactory.cpp 内容如下

#include "CAAICafElementPropertyPageEdtFactory.h"

IID IID_CAAICafElementPropertyPageEdtFactory = {
    0x4ee83c16,
    0xd55d,
    0x11d3,
    {0xb7, 0xf5, 0x00, 0x08, 0xc7, 0x4f, 0xe8, 0xdd}
  };

CATImplementInterface(CAAICafElementPropertyPageEdtFactory, CATIGenericFactory);

该文件包含一个全局唯一标识符(GUID),以粗体显示。头文件中的CATDeclareInterface宏与源文件中的CATImplementInterface宏共同将这个 C++ 类定义为接口。CATImplementInterface宏声明CAAICafElementPropertyPageEdtFactoryCATIGenericFactory进行对象模型(OM)继承。

TIE 文件:为了使组件能够实现该接口,请在 src 目录下创建一个名为 TIE_CAAICafElementPropertyPageEdtFactory.tsrc 的文件,文件内容如下:

#include "CAAICafElementPropertyPageEdtFactory.h"

多工作区应用程序构建工具(mkmk)会自动为该接口生成对应的 TIE 文件,即在 ProtectedGenerated 目录下为你生成 TIE_CAAICafElementPropertyPageEdtFactory.h 文件。

 

创建属性页编辑器工厂

 

可借助宏来创建该类。这些宏会生成一个类,类名由属性页编辑器类名后拼接字符串 Factory 组成。这也是头文件命名为 CAACafElementPropertyPageEdtFactory.h、源文件命名为 CAACafElementPropertyPageEdtFactory.cpp 的原因。
创建该类需完成以下操作:
  • 利用 CAT_EDITOR_DECLARE_FACTORY 宏编写头文件
  • 利用 CAT_EDITOR_DEFINE_FACTORY2 宏编写源文件
  • 更新接口字典与工厂字典

借助上述宏即可生成对应类,类名规则为属性页编辑器类名后追加 Factory,因此该类命名为 CAACafElementPropertyPageEdtFactory

头文件:CAACafElementPropertyPageEdtFactory.h 内容如下

#include <CATEditorFactory.h>

#include <CAACafElementPropertyPageEdt.h>

 

#define ExportedByNOTHING

 

CAT_EDITOR_DECLARE_FACTORY(NOTHING,

                CAACafElementPropertyPageEdt,

                CAACafElementPropertyPageEdt);

CAT_EDITOR_DECLARE_FACTORY 宏用于生成工厂类的头文件内容。本例中所有使用 NOTHING 的位置必须保持一致,这一点十分重要。

 

ExportedByNOTHING 为该类指定一个不存在的共享库或动态链接库(DLL)。指定有效库名并无意义,因为该类是 CATUserSettingManager 的扩展类;当 CATUserSettingManager 请求获取 CAAICafElementPropertyPageEdtFactory 的指针时,该类会完成实例化。这种情况下,系统会通过接口字典识别对应的共享库或动态链接库。

第二个参数为属性页编辑器类名,宏会在该名称后拼接 Factory 生成工厂类名,本例中即为 CAACafElementPropertyPageEdtFactory

 

第三个参数是为待创建类指定的类型,可通过 CATIGenericFactory::Support 方法获取;本例中未使用该功能,直接填写属性页编辑器类名即可。

源文件:CAACafElementPropertyPageEdtFactory.cpp 内容如下

 

#include <CAACafElementPropertyPageEdtFactory.h>

CAT_EDITOR_DEFINE_FACTORY2(CAACafElementPropertyPageEdt,
                           CAACafElementPropertyPageEdt);

#include <TIE_CAAICafElementPropertyPageEdtFactory.h>
TIE_CAAICafElementPropertyPageEdtFactory(CAACafElementPropertyPageEdtFactory);
CAT_EDITOR_DEFINE_FACTORY2 宏用于创建属性页编辑器工厂的实现类内容,并将其作为 CATUserSettingManager 组件的数据扩展。
 
CATUserSettingManager 负责管理「工具→选项」界面下的所有属性页编辑器工厂。
随后的 TIE 宏声明:该扩展类实现了 CAAICafElementPropertyPageEdtFactory 接口。
字典文件:此时需要更新以下两项
  1. 接口字典
    即文件名以框架名加后缀 .dico 命名的文件,例如 CAACATIAApplicationFrm.edu.dico。需在框架路径 CNext/code/dictionary 目录下创建或更新该文件。接口字典包含如下声明,用于说明:CATUserSettingsManager 组件通过上述宏生成的扩展类,实现了 CAAICafElementPropertyPageEdtFactory 接口,相关代码位于 libCAACafEltToolsOptions 共享库(DLL)中:
    CATUserSettingsManager CAAICafElementPropertyPageEdtFactory libCAACafEltToolsOptions
  2. 工厂字典
    即文件名以框架名加后缀 .fact 命名的文件,例如 CAACATIAApplicationFrm.edu.fact。需在框架路径 CNext/code/dictionary 目录下创建或更新该文件。工厂字典包含如下声明,用于说明:CAAICafElementPropertyPageEdtFactory 是一个工厂接口,其实现用于创建 CAACafElementPropertyPageEdt 类的实例:
    CAACafElementPropertyPageEdt   CAAICafElementPropertyPageEdtFactory
    运行时,存放这些字典文件的目录路径会被拼接到环境变量 CATDictionaryPath 中。

创建属性页编辑器

接下来需要创建属性页编辑器对应的类。该类需要实现 CATIUserSettings 接口,继承自 CATEditor 类,并重写 CATEditor 实现中为纯虚函数或空实现的方法。你需要为这些方法编写函数体,使其实现以下功能:
BuildEditor  实例化关联的对话框类
SetUserSettingValue  通过设置控制器将配置值加载到属性页中
ResetUserSettingValue  恢复管理员设置的值;若未设置,则恢复代码中定义的默认值
CancelModification  取消属性页中的修改,恢复为修改前的值
CommitModification  将修改保存至配置文件
下方展示了属性页编辑器类的头文件。
#ifndef CAACafElementPropertyPageEdt_H
#define CAACafElementPropertyPageEdt_H

// CATIAApplicationFrame framework
#include "CATEditor.h"                // Needed to derive from CATEditor
class CATIIniSettingManagment ;       // Interface to handle the setting controller

// Local framework
class CAACafElementPropertyPageDlg;   // Property page dialog  

// System framework
class CATSettingRepository;

class CAACafElementPropertyPageEdt : public CATEditor
{
  CATDeclareClass;

  public :

    CAACafElementPropertyPageEdt();
    virtual ~CAACafElementPropertyPageEdt();

    void             BuildEditor           (CATEditorPage * iTabPage);
    void             SetUserSettingsValue  (CATSettingRepository * iUselessFileRep);
    void             ResetUserSettingsValue();
    void             CancelModification    (CATSettingRepository * iUselessFileRep);
    void             CommitModification    (CATSettingRepository * iUselessFileRep);

 private:

   CAACafElementPropertyPageEdt(const CAACafElementPropertyPageEdt &iObjectToCopy);
   CAACafElementPropertyPageEdt & operator = (const CAACafElementPropertyPageEdt &iObjectToCopy);

  private : 

    CAACafElementPropertyPageDlg  *  _pDialogPage;
    CATIIniSettingManagment       *  _pISettingManagmentForCtrl ;
};
#endif

CAACafElementProperetyPageEdt 类以 C++ 语言继承自 CATEditor 类。CATDeclareClass 宏用于声明 CAACafElementProperetyPageEdt 类归属于一个组件。请注意:拷贝构造函数赋值运算符被声明为私有权限,且未在源文件中实现。这可以避免编译器在你不知情的情况下自动将它们生成为公有成员。我们将逐一讲解每个方法的具体实现。

_pDialogPage 是指向属性页对话框的指针,该对话框在 BuildEditor 方法中创建。
_pISettingManagmentForCtrl 是 CATIIniSettingManagment 接口的指针。该接口指针在类的构造函数中完成初始化,并在 ResetUserSettingsValue、CancelModification 和 CommitModification 方法中被使用。该接口用于对设置控制器所封装的配置存储库执行保存、回滚、恢复为管理员默认值、提交等管理操作。
属性页编辑器类的源文件如下所示。
 
CAACafElementPropertyPageEdt.cpp 文件的开头部分如下:
// 本地框架
#include "CAACafElementPropertyPageEdt.h"
#include "CAACafElementPropertyPageDlg.h"
#include "CAAICafGeometryEltSettingAtt.h"
#include "GetCAACafGeometryEltSettingCtrl.h"
 
// 交互接口框架
#include <CATIIniSettingManagment.h>
...
 
#include <TIE_CATIUserSettings.h>
TIE_CATIUserSettings(CAACafElementPropertyPageEdt);
CATImplementClass(CAACafElementPropertyPageEdt, Implementation, CATBaseUnknown, CATNull);
...
通过 TIE_CATIUserSettings 宏,CAACafElementPropertyPageEdt 类声明实现了 CATIUserSettings(用户设置)接口。
 
CATImplementClass 宏借助关键字 Implementation(实现类),声明 CAACafElementPropertyPageEdt 类为一个实现类(即组件主类),同时该类在对象模型(OM)层面继承自 CATBaseUnknown。第四个参数必须固定设为 CATNull,该参数无实际意义,在实现类中不会被使用。
需更新接口字典文件(例如文件名为 CAACATIAApplicationFrm.edu.dico):该文件的目录路径会在运行时拼接到环境变量 CATDictionaryPath 中。文件内需添加如下声明,用于指明 CAACafElementPropertyPageEdt 类实现了 CATIUserSettings 接口,且其代码位于 libCAACafEltToolsOptions 共享库(动态链接库 DLL)中。更新内容以加粗字体展示:
CATUserSettingsManager CAAICafElementPropertyPageEdtFactory libCAACafEltToolsOptions
CAACafElementPropertyPageEdt CATIUserSettings libCAACafEltToolsOptions
 
构造函数会获取专属配置文件的配置控制器上的 CATIIniSettingManagment 接口指针。
...
 
CAACafElementPropertyPageEdt::CAACafElementPropertyPageEdt()
 
: CATEditor(), _pDialogPage(NULL)
{
 
// 初始化接口指针
 
_pISettingManagmentForCtrl = NULL;
 
// 调用全局函数获取配置控制器的接口指针
 
HRESULT rc = ::GetCAACafGeometryEltSettingCtrl (IID_CATIIniSettingManagment,
 
(void**) &_pISettingManagmentForCtrl);
 
}
 
...
GetCAACafGeometryEltSettingCtrl 全局函数用于获取 CAACafGeometryElt 配置文件的接口指针。
 
第一个参数为待获取的接口标识符(IID)。
 
析构函数仅将对话框页面指针重置为NULL,并释放CATIIniSettingManagment接口的指针。
...
 
CAACafElementPropertyPageEdt::~CAACafElementPropertyPageEdt()
 
{
 
_pDialogPage = NULL;
 
if ( NULL != _pISettingManagmentForCtrl )
 
{
 
_pISettingManagmentForCtrl->Release();
 
_pISettingManagmentForCtrl = NULL;
 
}
 
}
 
...
 
BuildEditor 方法实例化并创建属性页的对话框对象。
...
void CAACafElementPropertyPageEdt::BuildEditor(CATEditorPage * iDlgPageParent)
{
  if ( NULL != iDlgPageParent)
  {
    _pDialogPage = new CAACafElementPropertyPageDlg(iDlgPageParent);
    if ( NULL != _pDialogPage )
    { 
      _pDialogPage->Build();
    }
  }
}
...

该对话框对象的相关说明详见创建属性页对话框章节。

SetUserSettingsValue 方法请求对话框对象设置所显示参数的数值。

...
void CAACafElementPropertyPageEdt::SetUserSettingsValue(CATSettingRepository * iUselessFileRep)
{
  if ( NULL != _pDialogPage )
  { 
    _pDialogPage->ValueSettings();
  }
}
...

对话框类的 ValueSettings 方法从设置控制器中读取设置属性值,并将这些值赋给属性页中代表对应设置属性的控件。

ResetUserSettingsValue 函数将参数值重置为默认值。

...
void CAACafElementPropertyPageEdt::ResetUserSettingsValue()
{
  if ( NULL != _pISettingManagmentForCtrl )
  {
    _pISettingManagmentForCtrl->ResetToAdminValues();  
  }
}
...

当最终用户点击重置(Reset)按钮,且该选项卡页面属于重置范围时,系统会调用此方法。

 ResetToAdminValues 方法会读取管理员预先配置的文件中的设置值。
 该方法执行完毕后,会立即调用 SetUserSettingsValue 方法来更新界面上显示的参数值。
 

当最终用户点击 ** 取消(Cancel)** 按钮,撤销对参数值所做的修改时,将调用CancelModification方法。

...
void CAACafElementPropertyPageEdt::CancelModification(CATSettingRepository * iUselessFileRep)
{
  if ( NULL != _pISettingManagmentForCtrl )
  {
    _pISettingManagmentForCtrl->Rollback();
    _pISettingManagmentForCtrl->Commit();
 }
}
...

设置仓库对象用于恢复之前保存的参数值,并且会再次保存,以便处理后续可能的取消操作 —— 因为Rollback(回滚)方法会删除已保存的设置对象。

 

当最终用户点击 ** 确定(OK)** 按钮,将修改后的参数值从设置仓库保存到设置文件时,会调用CommitModification方法。

...
void CAACafElementPropertyPageEdt::CommitModification(CATSettingRepository * iUselessFileRep)
{
  if ( NULL != _pISettingManagmentForCtrl )
  {
    _pISettingManagmentForCtrl ->SaveRepository();
  }
}
...

为属性页编辑器配置资源

属性页编辑器的资源包含页面标题,以及与你的开发模块(workshop)或工作台(workbench)关联的属性表,你的属性页将展示在该属性表中。
属性页的标题定义在 CAACATIAApplicationFrm.edu 框架的 CNext\resources\msgcatalog 目录下的 CAACafElementPropertyPageEdt.CATNls 文件中。
TabPage.Title = "Elements" ;
其中:

  • TabPage:属性页的必填关键字
  • Title:用于定义标题的关键字

该属性页被配置在基础架构(Infrastructure)解决方案下的 CAA V5 几何创建(CAA V5 Geometrical Creation) 工作台的属性表中。

 

该配置信息写在 CAACATIAApplicationFrm.edu 框架的 CNext\resources\msgcatalog 目录下的 CAACafElementPropertyPageEdt.CATRsc 文件内。

TabPage.SolutionName = "Infrastructure" ;
TabPage.WorkbenchName = "CAAAfrGeoCreationWkb" ;
其中:
  • TabPage:属性页的必填关键字
  • SolutionName:你的开发模块或工作台在开始菜单中所属的子菜单。该名称在你的开发模块 / 工作台的 CATRsc 文件中,通过关键字 Category 定义。
  • WorkbenchName:你的开发模块或工作台的标识符,在 CreateWorkshopCreateWorkbench 方法中通过 NewAccess 宏进行设置 [1]。

在同一个资源文件中,可获取上下文帮助的统一资源定位符(URL):

 TabPage.LongHelpId = "ToolsOptions.Infrastructure.CAAV5GeometricalCreation.Elements";
其中:

  • TabPage:属性页的必填关键字
  • LongHelpId:用于定义(帮助文档)统一资源定位符(URL)的必填关键字
  • ToolsOptions:固定强制字符串
  • Infrastructure:解决方案名称(实际为分类名称)
  • CAAV5GeometricalCreation:自定义开发模块或工作台的标识符,在 CreateWorkshopCreateWorkbench 方法中通过 NewAccess 宏进行设置 [1]
  • Elements:该属性页的英文名称
 

创建属性页对话框


该对话框类用于表示属性页的内容,也就是对话框的右侧区域。头文件代码如下:
#ifndef CAACafElementPropertyPageDlg_H
#define CAACafElementPropertyPageDlg_H

#include "CATDlgFrame.h"          // Needed to derive from CATDlgFrame

// Dialog Framework
class CATDlgRadioButton;
class CATDlgSlider;

// System Framework
class CAAICafGeometryEltSettingAtt;

class CAACafElementPropertyPageDlg : public CATDlgFrame
{
  public :
    DeclareResource(CAACafElementPropertyPageDlg, CATDlgFrame);

    CAACafElementPropertyPageDlg(CATDialog * ipParent);
    virtual ~CAACafElementPropertyPageDlg();

    void Build();
    void ValueSettings();

  private :
    CAACafElementPropertyPageDlg ();
    CAACafElementPropertyPageDlg(const CAACafElementPropertyPageDlg &iObjectToCopy);
    CAACafElementPropertyPageDlg & operator = (const CAACafElementPropertyPageDlg &iObjectToCopy);
      
    void IdHideCB            (CATCommand         * iPublishingCommand,
                              CATNotification    * iNotification,
                              CATCommandClientData iUsefulData);
    void IdShowCB            (CATCommand         * iPublishingCommand,
                              CATNotification    * iNotification,
                              CATCommandClientData iUsefulData);
    void IdPreSelectShowCB   (CATCommand         * iPublishingCommand,
                              CATNotification    * iNotification,
                              
    void MaxPointCB          (CATCommand         * iPublishingCommand,
                              CATNotification    * iNotification,
                              CATCommandClientData iUsefulData);
                              
    void ImplPointHideCB     (CATCommand         * iPublishingCommand,
                              CATNotification    * iNotification,
                              CATCommandClientData iUsefulData);
    void ImplPointShowCB     (CATCommand         * iPublishingCommand,
                              CATNotification    * iNotification,
                              CATCommandClientData iUsefulData);
    
  private :
    CATDlgRadioButton    * _pIdHide;
    CATDlgRadioButton    * _pIdShow;
    CATDlgRadioButton    * _pIdPreSelectShow;
    
    CATDlgRadioButton    * _pImplPointShow;
    CATDlgRadioButton    * _pImplPointHide;    
    
    CATDlgSlider         * _pMaxPoint;
    
    CAAICafGeometryEltSettingAtt * _pISettingAttForCtrl;
};
属性页对话框必须继承自 CATDlgFrameDeclareResource 宏声明:消息资源将从 CAACafElementPropertyPageDlg.CATNls 文件中读取,界面资源将从 CAACafElementPropertyPageDlg.CATRsc 文件中读取。这些文件存放于 CAACATIAApplicationFrm.edu 框架的 CNext\resources\msgcatalog 目录下。
该类包含一个接收父窗口指针的构造函数和一个析构函数。构造函数仅用于初始化数据成员,而 Build 方法负责创建并布局控件,同时为这些控件设置回调函数。ValueSettings 方法读取设置属性值,并将其赋值给属性页中展示对应设置属性的控件。
默认构造函数和拷贝构造函数被声明为私有权限,且不会在源文件中实现。这可以避免编译器在你不知情的情况下自动将它们生成为公有成员函数。
作为数据成员声明的控件会在回调方法中使用:单选按钮、滑块控件。
_pISettingAttForCtrlCAAICafGeometryEltSettingAtt 接口的指针。该指针在类的构造函数中完成初始化,并在 ValueSettings 方法及所有回调方法中使用。该接口用于对设置控制器封装的设置仓库执行属性值的读写操作。
我们将逐一讲解每个方法或每组方法的作用。
 
构造函数
// Local Framework
#include "CAACafElementPropertyPageDlg.h"
#include "CAAICafGeometryEltSettingAtt.h"

// Dialog Framework
#include "CATDlgInclude.h"
#include "CATDlgGridConstraints.h"
#include "CATDlgLock.h"

// System Framework 
#include "CATSettingInfo.h"

// CATIAApplicationFrame Framework 
#include "CATDlgToolsOptionsFrame.h"

CAACafElementPropertyPageDlg::CAACafElementPropertyPageDlg(CATDialog * parent)
                            : CATDlgFrame(parent, "GeometryElementTO",
                              CATDlgFraNoFrame|CATDlgGridLayout),
                              _pIdHide(NULL), _pIdShow(NULL), _pIdPreSelectShow(NULL),
                              _pImplPointShow(NULL),_pImplPointHide(NULL),
                              _pMaxPoint(NULL)
{
  _pISettingAttForCtrl = NULL;
  ::GetCAACafGeometryEltSettingCtrl(IID_CAAICafGeometryEltSettingAtt,
                                    (void**)&_pISettingAttForCtrl);
}
...

所有数据成员均已完成初始化。GetCAACafGeometryEltSettingCtrl 全局函数用于获取 CAACafGeometryElt 设置文件的接口指针。第一个参数是需要获取的接口的标识符(IID)。

析构函数将所有控件数据成员的指针置空,因为对话框对象会被自动删除,同时释放 CAAICafGeometryEltSettingAtt 接口的指针。
...
CAACafElementPropertyPageDlg::~CAACafElementPropertyPageDlg()
{
  _pIdHide = NULL ; 
  _pIdShow =NULL ; 
  _pIdPreSelectShow = NULL ;
  _pImplPointShow = NULL ; 
  _pImplPointHide =NULL ;
  _pMaxPoint = NULL;

  if ( NULL != _pISettingAttForCtrl )
  {
    _pISettingAttForCtrl->Release();
    _pISettingAttForCtrl = NULL ;
  }
}
...

Build 方法负责完成所有工作:创建控件、将控件布局在独立的框架中,并设置回调函数以响应预期的事件。

...
void CAACafElementPropertyPageDlg::Build()
{
  if ( NULL == pISettingAttForCtrl )
  {
     return ;
  }
    
  // Frame 1
  See first frame 
  
  // Frame 2
  See second frame    
        
  // Frame 3
  See third and last frame     
}
...  

每个框架都是 CATDlgToolsOptionsFrame 类的实例,该类的样式由最后一个参数定义。

第一个框架如下:

图片

 框架 “标识符 (Identifier)” 包含三个前方不带图标的单选按钮。

 ...

  CATString    TOFrameId1      = "Identifier" ;
  CATString    IconName1      = "" ;
  CATDlgStyle  TOFrameStyle1   = CATDlgToolsOptionsInvisibleIcon ;
  
  CATDlgToolsOptionsFrame * pToolsOptionsFrame1 = NULL ;
  pToolsOptionsFrame1 = new CATDlgToolsOptionsFrame(this,
                                                    TOFrameId1,
                                                    IconName1,
                                                    TOFrameStyle1);
  
  pToolsOptionsFrame1->SetGridConstraints(0,0,1,1,CATGRID_TOP);

  CATDlgFrame * pIdentifierFrame = NULL ;
  pIdentifierFrame = pToolsOptionsFrame1->GetOptionsFrame();

  ...
对于第一个框架,样式为 CATDlgToolsOptionsInvisibleIcon
 
这表示在当前属性页中部分框架带有图标,该样式用于保证整体布局整齐统一。
pToolsOptionsFrame1 框架内部包含一个由 GetOptionsFrame 方法返回的子框架,该子框架将作为第二个框架所有对话框对象的父容器。
 
pIdentifierFrame 是以下对话框控件的父框架:三个单选按钮和一个锁定控件。
 ...
     // Lock sets at the top of the three radio buttons
     CATSettingInfo InfoForLockForId ;
     _pISettingAttForCtrl->GetInfoIdentifierVisibility(&InfoForLockForId);    
           
     CATDlgLock * pIdentifierLock = NULL ;
     pIdentifierLock = new CATDlgLock(pIdentifierFrame,"IdentifierLock",InfoForLock);
     pIdentifierLock->SetGridConstraints(0,0,1,3,CATGRID_LEFT);

     // 3 Radio buttons 
     _pIdHide   = new CATDlgRadioButton(pIdentifierFrame, "IdHide");
     _pIdHide->SetGridConstraints(0,1,1,1,CATGRID_LEFT);
     pIdentifierLock->AddAssociatedDialog(_pIdHide);

     _pIdShow  = new CATDlgRadioButton(pIdentifierFrame, "IdShow");
     _pIdShow->SetGridConstraints(1,1,1,1,CATGRID_LEFT);
     pIdentifierLock->AddAssociatedDialog(_pIdShow);

     _pIdPreSelectShow = new CATDlgRadioButton(pIdentifierFrame, "IdPreSelectShow");
     _pIdPreSelectShow->SetGridConstraints(2,1,1,1,CATGRID_LEFT);
     pIdentifierLock->AddAssociatedDialog(_pIdPreSelectShow);
  ...
在设置仓库中,每个属性都对应一个 CATSettingInfo 类实例。设置控制器的 GetInfoIdentifierVisibility 方法获取该实例,并将其传递给 CATDlgLock 对话框控件。
单选按钮创建完成后,可将锁定控件与受该锁定影响的各个对话框控件进行关联。
回调函数按照对话框的常规方式进行设置。
 ...
  AddAnalyseNotificationCB(_pIdHide,
                           _pIdHide->GetRadBModifyNotification(),
                           (CATCommandMethod)&CAACafElementPropertyPageDlg::IdHideCB,
                           NULL);

  AddAnalyseNotificationCB(_pIdShow,
                           _pIdShow->GetRadBModifyNotification(),
                           (CATCommandMethod)&CAACafElementPropertyPageDlg::IdShowCB,
                           NULL);

  AddAnalyseNotificationCB(_pIdPreSelectShow,
                           _pIdPreSelectShow->GetRadBModifyNotification(),
                           (CATCommandMethod)&CAACafElementPropertyPageDlg::IdPreSelectShowCB,
                           NULL);
  ...
}
...
第二个框架如下所示。

图片

 “最大点数 / 曲线(Max Points/Curve)” 框架包含一个前方带有图标的滑块控件。

 ...  
  CATString    TOFrameId2      = "MaxPointCurve";
  CATString    IconName2       = "I_CAAToolsOptionsEltMaxPointCurve";
  CATDlgStyle  TOFrameStyle2   = NULL; 
  
  CATDlgToolsOptionsFrame * pToolsOptionsFrame2 = NULL;
  pToolsOptionsFrame2 = new CATDlgToolsOptionsFrame(this,TOFrameId2,
                                                    IconName2,
                                                    TOFrameStyle2);
  
  pToolsOptionsFrame2->SetGridConstraints(1,0,1,1,CATGRID_TOP);
  
  CATDlgFrame             * pMaxPointCurveFrame = NULL;
  pMaxPointCurveFrame = pToolsOptionsFrame2->GetOptionsFrame();
  ...
由于带有图标且下方配有附属框架是属性页中框架的标准样式,因此该样式为默认样式,设置为 NULL
图标名称以 CATString 实例形式传入。该图标名称并非像常规对话框那样从资源文件读取,传入的字符串对应图标位图文件名(不含 .bmp 后缀,示例:I_CAAToolsOptionsEltMaxPointCurve.bmp),该位图文件存放于 CAACATIAApplicationFrm.edu 框架的 CNext\resources\graphic\icons\normal 目录下。
pToolsOptionsFrame2 框架内部包含一个由 GetOptionsFrame 方法返回的子框架,该子框架将作为第二个框架内所有对话框控件的父容器。pMaxPointCurveFrame 是以下对话框控件的父框架:一个滑块控件和一个锁定控件。
  ...
  // Lock sets before the slider  
   CATSettingInfo * pInfoList = NULL ;
   int nbInfo = 0;
  _pISettingAttForCtrl->GetInfoMaxPointCurve(&pInfoList,&nbInfo);
  
  CATDlgLock * pMaxPointLock = NULL ;
  pMaxPointLock = new CATDlgLock(pMaxPointCurveFrame,"MaxPointLock",pInfoList,nbInfo);
  pMaxPointLock->SetGridConstraints(0,0,1,1,CATGRID_LEFT);

  delete [] pInfoList ;
  pInfoList = NULL ;
  
  // Slider 
  _pMaxPoint = new CATDlgSlider(pMaxPointCurveFrame, "MaxPoint");
  _pMaxPoint->SetRange(2, 100, 100);
  _pMaxPoint->SetGridConstraints(0,1,1,1,CATGRID_CENTER);
  // Associate the lock to one dialog object, the slider
  _pMaxPointLock->AddAssociatedDialog(_pMaxPoint);
  ...
设置控制器的 GetInfoMaxPointCurve 方法会获取一组 CATSettingInfo 对象列表。你将该列表传入 CATDlgLock 对话框控件,之后可以释放 GetInfoMaxPointCurve 方法中创建的列表。
滑块控件创建完成后,可将锁定控件与受该锁定控制的各个对话框控件进行关联。
回调函数按照对话框的常规方式进行设置。
 ...
  AddAnalyseNotificationCB(_pMaxPoint,
                      _pMaxPoint->GetSliderModifyNotification(),
                      (CATCommandMethod)&CAACafElementPropertyPageDlg::MaxPointCB,
                      NULL);
  ...
}
...

回调函数通过设置控制器访问并修改设置仓库中的设置属性值。

 

第三个也是最后一个框架如下:

图片

 “隐式点 (Implicit Points)” 框架包含两个前方带有图标的单选按钮。

 ...  
  CATString    TOFrameId3      = "ImplicitePoint" ;
  CATString    IconName3      = "I_CAAToolsOptionsEltImplicitePoint" ;
  CATDlgStyle  TOFrameStyle3   = CATDlgToolsOptionsBottomFrame ; 
  
  CATDlgToolsOptionsFrame * pToolsOptionsFrame3 = NULL ;
  pToolsOptionsFrame3 = new CATDlgToolsOptionsFrame(this,
                                                    TOFrameId3,
                                                    IconName3,
                                                    TOFrameStyle3);
  ...
该框架是最后一个框架,因此必须将 CATDlgToolsOptionsBottomFrame 样式与另一种可选样式进行组合。此处 NULL | CATDlgToolsOptionsBottomFrame = CATDlgToolsOptionsBottomFrame。该样式可避免在页面末尾生成一条不可见的分隔线。
该框架不再完整描述,因为其实现方式与第二个框架完全一致。
ValueSettings 方法根据设置属性值,对界面上展示的参数进行赋值。
...
void CAACafElementPropertyPageDlg::ValueSettings()
{
  CATString ident; 
  _pISettingAttForCtrl->GetIdentifierVisibility(ident);

  if      (ident == "IdHide")           _pIdHide->SetState(CATDlgCheck, 0);
  else if (ident == "IdShow")           _pIdShow->SetState(CATDlgCheck, 0);
  else if (ident == "IdPreSelectShow")  _pIdPreSelectShow->SetState(CATDlgCheck, 0);  
  
  int maxpoint;
  _pISettingAttForCtrl->GetMaxPointCurve(maxpoint);

  float maxpointf = maxpoint ;
  _pMaxPoint->SetCurrentValue(maxpointf, 0);
  
  CATString implpoint; 
  _pISettingAttForCtrl->GetImplPointVisibility(implpoint);

  if      (implpoint == "ImplPointHide")  _pImplPointHide->SetState(CATDlgCheck, 0);
  else if (implpoint == "ImplPointShow")  _pImplPointShow->SetState(CATDlgCheck, 0);
}
...

它通过调用 CAAICafGeometryEltSettingAtt 接口的方法,为对话框控件赋值。

 

IdHideCB 是其中一个回调函数,用于在控件被触发时修改设置属性值。

...
void CAACafElementPropertyPageDlg::IdHideCB(
                              CATCommand         * iPublishingCommand,
                              CATNotification    * iNotification,
                              CATCommandClientData iUsefulData)
{
  if (_pIdHide->GetState() == CATDlgCheck)
  {
     _pISettingAttForCtrl->SetIdentifierVisibility("IdHide");
  }
...

如果 ** 隐藏(Hide)** 单选按钮被选中,则通过 SetIdentifierVisibility 方法将标识符(Identifier)设置属性值设为 IdHide

 其余访问设置属性值的回调函数逻辑基本一致,此处不再展示。

为属性页对话框配置资源

在位于 CNext/resources/msgcatalog 目录下定义的 CAACafElementPropertyPageDlg.CATNls 文件中,为属性页对话框内创建的每一个对话框控件配置多语言文本(NLS)
框架的标题
IdFrame.HeaderFrame.Global.Title ="xxx";
其中:
  • IdFrame:框架的标识符,为 CATDlgToolsOptionsFrame 方法的第二个参数
  • HeaderFrame.Global.Title:固定必填关键字

Identifier.HeaderFrame.Global.Title = "标识符"; 

MaxPointCurve.HeaderFrame.Global.Title = "最大点数/曲线";

框架内各个控件

框架ID.IconAndOptionsFrame.OptionsFrame.控件ID.Title = "xxx";

说明:
  • 框架 ID:框架标识符,为 CATDlgToolsOptionsFrame 方法的第二个参数
  • IconAndOptionsFrame.OptionsFrame:固定必填关键字
  • 控件 ID:框架内部对话框控件的标识符
  • Title:固定必填关键字

Identifier.IconAndOptionsFrame.OptionsFrame.IdHide.Title = "隐藏"; 

Identifier.IconAndOptionsFrame.OptionsFrame.IdShow.Title = "显示"; 

Identifier.IconAndOptionsFrame.OptionsFrame.PreSelectShow.Title = "预选显示";

管理员模式下测试

要测试新建的属性页,必须以管理员模式运行。可通过设置环境变量 CATReferenceSettingPath 进入该模式。
 
首先,向 CNEXT 命令传入 -admin 参数,以管理员身份进行测试;随后不带参数重新启动 CNEXT,使用管理员配置文件完成测试。
 
UNIX 系统操作
$ mkrun -c "/bin/ksh"
$ export CATReferenceSettingPath=MySettingPath
$ CNEXT -admin
$ CNEXT
 
Windows 系统操作
mkrun -c "cmd"
set CATReferenceSettingPath=MySettingPath
CNEXT -admin
CNEXT
 
其中 MySettingPath 为你的设置文件目录路径。
 
注意MySettingPath 对应的目录必须提前创建完成。

简要总结

为 ** 工具选项(Tools Options)** 菜单创建属性页,需要实现以下内容:
 
创建一个属性页编辑器工厂、一个由该工厂实例化的属性页编辑器类,同时提供一个属性页对话框类,该类集成各类控件,供终端用户查看并修改相关参数与数值。
该属性页通过设置控制器管理对设置仓库与配置文件的访问,实现参数和数值的读取与保存。
 
posted @ 2026-05-11 17:09  Breadss  阅读(9)  评论(0)    收藏  举报