Creating Search Queries-如何编写查询语句,在 V5 文档中检索零部件对象?

摘要
本文介绍如何创建并执行检索,在 CATIA V5 文档中查找模型对象。
  • 本案例学习要点
  •     CAACafSearch 示例工程
    • CAACafSearch 实现功能
    • CAACafSearch 启动方式
    • CAACafSearch 源码路径
  • 实现分步详解
  • 内容小结
  • 参考资料

 

本案例可学到的内容

本案例旨在演示如何创建并执行检索,在 CATIA V5 文档中查找对象。你将重点掌握:
  1. 创建简单检索条件(对应 CATIA【搜索】命令的常规选项卡用法);
  2. 创建基于知识工程类型与属性的检索条件(对应【搜索】命令的高级选项卡用法);
  3. 创建组合检索条件(两个条件间实现与、或、非逻辑运算);
  4. 通过本地化字符串或转换格式字符串生成检索条件;
  5. 执行检索查询;
  6. 将检索结果置入预选高亮对象(PSO)。
在研读案例代码前,建议先熟悉 CATIA 搜索功能的基础概念,概述内容可查阅参考文献 [1]。

CAACafSearch 示例工程

CAACafSearch 是CAACATIAApplicationFrm.edu框架下的示例案例,用于演示交互接口(InteractiveInterfaces)框架的功能特性。

CAACafSearch 实现功能

CAACafSearch 示例是状态命令,依托通用工作台插件集成至 CATIA V5 环境,也就是说:无论当前打开何种文档,该命令均可调用。
图 1:搜索演示命令

图片

 该名为「搜索演示器」的命令通过如下交互界面,供用户在预设筛选条件与多种检索环境之间进行选择:

图 2:搜索演示对话框

图片

 共有八种预设检索条件,具体如下:

图 3:筛选条件列表

图片

 所有筛选条件会在状态命令启动时统一创建、退出时统一销毁;仅在销毁前保留筛选条件的文本(多语言格式或 Transformat 格式)。用户点击【执行】按钮后会触发动作函数,该函数根据保存的文本重新生成筛选条件,并结合当前检索上下文执行查询。

共有四种检索上下文,具体如下:

图 4:检索上下文列表

图片

 如需了解这四种检索上下文的详细信息,请参阅技术文档 [1]。

用户点击执行按钮后,查询到的对象数量会在编辑框中显示,同时选中对象自动预选高亮。

图 5:一次查询结果

图片

 该图展示了第一次检索的运行结果:规格树中有三个对象被高亮预选。在三维视图可视区域内,仅点与凸台特征呈现预选高亮;切换至隐藏元素显示状态后,草图也会变为预选高亮样式。

如何启动 CAACafSearch 示例

想要运行 CAACafSearch,需先配置编译环境,编译该示例及其依赖组件,再配置运行环境,最后执行案例程序【4】。
正式运行前,需要修改接口字典文件 CAAApplicationFrame.edu.dico,文件路径位于 CAAApplicationFrame.edu 框架的 dictionary 目录下:
  • Windows 系统:安装根目录\CAAApplicationFrame.edu\CNext\code\dictionary\
  • UNIX 系统:安装根目录/CAAApplicationFrame.edu/CNext/code/dictionary/

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

在该文件中,删除下面两行代码前的#注释符,之后执行mkCreateRuntimeView命令。

#CAAAfrGeneralWksAddin       CATIWorkbenchAddin          libCAAAfrGeneralWksAddin  
#CAAAfrGeneralWksAddin       CATIAfrGeneralWksAddin      libCAAAfrGeneralWksAddin

上述两行用于注册通用工作台插件,对应案例文档【3】中的CAAAfrGeneralWksAddin示例,该示例隶属于 CAAApplicationFrame.edu 框架下的CAAAfrGeneralWksAddin.m模块。

随后在执行 mkrun 命令的终端窗口中,命令行不要输入模块名,改为输入 CNEXT。CATIA 程序启动就绪后,按以下步骤操作:
  1. 点击菜单栏【文件】→【打开】
  2. 在文件选择弹窗选中 CAACafSearch.CATPart,点击【打开】
  3. 点击菜单栏【编辑】→【Search Demonstrator...(搜索演示工具)】
  4. 在搜索演示对话框内,选定一条筛选条件与检索范围
  5. 点击【启动】
  6. 点击【关闭】
  7. 再次点击菜单栏【文件】→【打开】
  8. 在文件选择弹窗选中 CAACafSearch.CATProduct,点击【打开】
  9. 点击菜单栏【编辑】→【Search Demonstrator...(搜索演示工具)】
  10. 在搜索演示对话框内,选定一条筛选条件与检索范围
  11. 点击【启动】
  12. 点击【关闭】

(*) 该模型文件存放在 CAACATIAApplicationFrm.edu 框架的 InputData 目录中:

  • Windows 系统路径:安装根目录\CAACATIAApplicationFrm.edu\InputData\
  • Unix 系统路径:安装根目录/CAACATIAApplicationFrm.edu/InputData/

其中 InstallRootDirectory 为 CAA 安装包的根目录路径。

CAACafSearch 源码位置

CAACafSearch 示例由多个类文件组成,代码存放于 CAACATIAApplicationFrm.edu 框架下的 CAACafSearch.m 模块目录:

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

InstallRootDirectory 指代 CAA 开发盘的安装根文件夹。

项目包含三个类:

  1. CAACafSearchCmd:状态命令类,负责创建检索条件、供用户执行查询并通过预选高亮(PSO)展示查询结果。本文仅讲解和搜索 API相关的代码片段。
  2. CAACafSearchDlg:绑定 CAACafSearchCmd 状态命令的对话框类,本文不对该类展开详述。
  3. CAACafLaunchNextQueryNotification:用户点击启动按钮时,由 CAACafSearchDlg 发送的通知类;CAACafSearchCmd 接收该通知后,赋值对话框代理 [5],触发查询执行与结果展示动作。本文不对该类展开详述。

前置依赖代码为通用工作台插件,该插件内置了搜索演示命令。如需详情,可查阅 CAAAfrGeneralWksAddin 示例【3】文档里的「CAAAfrGeneralWksAddin 代码存放位置」章节。

分步实现

CAACafSearch 整体分为四大逻辑步骤:
  1. 创建检索引擎、检索上下文与服务组件
  2. 构建检索筛选条件
  3. 执行检索查询
  4. 通过 PSO 预选高亮展示查询到的对象

创建检索引擎、检索上下文及服务组件

在 CAACafSearchCmd 类的构造函数中,实例化状态命令运行全程所需的各类搜索组件。各类组件通过全局函数CATCreateInstance结合CATIniSearchxxxComponent头文件中定义的 CLSID 标识符完成创建【6】。

...

#include "CATIIniSearchServices.h"
#include "CATIIniSearchEngine.h"
#include "CATIIniSearchContext.h"
#include "CATIniSearchEngineComponent.h"
#include "CATIniSearchContextComponent.h"
#include "CATIniSearchServicesComponent.h"

// 创建搜索引擎实例
::CATCreateInstance(CLSID_CATIniSearchEngineComponent, NULL, 0,
                     IID_CATIIniSearchEngine,
                     (void**)&_pIniSearchEngineOnCurrentEngine);

// 创建搜索上下文实例
::CATCreateInstance(CLSID_CATIniSearchContextComponent, NULL, 0,
                     IID_CATIIniSearchContext,
                     (void**)&_pIniSearchContextOnCurrentContext);

// 创建搜索服务实例
::CATCreateInstance(CLSID_CATIniSearchServicesComponent, NULL, 0,
                     IID_CATIIniSearchServices,
                     (void**)&_pIniSearchServices);

...

第一个组件为搜索引擎组件,由接口指针_pIniSearchEngineOnCurrentEngineCATIIniSearchEngine类型)管理,后续在 CAACafSearchCmd 的动作函数中,依靠该指针执行用户选定的检索。
第二个组件为搜索上下文组件,由接口指针_pIniSearchContextOnCurrentContextCATIIniSearchContext类型)管理。执行查询前,程序从 CAACafSearchDlg 对话框实例中读取用户所选检索范围;上下文是查询入参之一,另一个入参为检索条件。
第三个组件是搜索服务组件,由CATIIniSearchServices接口指针_pIniSearchServices管控。
 
该服务组件在「基于名称的检索条件构建」环节使用,同时和前两个组件一样,也会在「执行检索」环节被调用。

构建筛选条件

在由 CAACafSearchCmd 构造函数调用的方法中创建八项筛选条件(见图 3),每条条件的创建流程一致:
  1. 生成筛选条件对象
  2. 将条件文本存入全局链表
  3. 销毁筛选条件对象
保存条件文本有两个目的:填充对话框 CAACafSearchDlg 的下拉选项,以及在发起查询前重新还原生成筛选条件。

简易检索条件:

  • 基于颜色的筛选条件
  • 基于颜色与可见性的筛选条件
  • 基于线型与线粗的筛选条件
  • 基于图层的筛选条件
  • 基于名称的筛选条件

高级检索条件:

  • 读取类型字典
  • 基于尺寸属性的筛选条件
  • 基于字符串属性的筛选条件
  • 基于用户自定义属性的筛选条件
  1. 基于颜色的检索条件

目的:筛选出全部红色(RGB:255,0,0)的元素对象。
首先创建颜色条件组件,pIniSearchColorCriterionCATIIniSearchColorCriterion接口指针,用于管控该组件。
...

CATIIniSearchColorCriterion * pIniSearchColorCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchColorCriterionComponent, NULL, 0,
                         IID_CATIIniSearchColorCriterion,
                         (void**)&pIniSearchColorCriterion);

...

通过CATIIniSearchColorCriterion接口配置颜色参数:

...

unsigned int *Color = new unsigned int[3];
Color[0]=255; Color[1]=0; Color[2]=0;
CATUnicodeString ColorName;
         
rc = pIniSearchColorCriterion->FindColorNameFromRGBColorCode(Color,ColorName);

rc = pIniSearchColorCriterion->SetParameters(Color[0],Color[1],Color[2],
                                   CATIniSearchEnumeration::Equal,
                                   ColorName);
delete []Color;

...

FindColorNameFromRGBColorCode函数依据 RGB 三色值查询对应颜色名称;若无匹配色名,返回错误码E_FAIL。系统内置 48 种基础色 + 16 种自定义色,共 64 个预设色名。获取到的色名ColorName作为入参传入SetParameters,用于拼接生成检索条件的显示文本。

最后读取该检索条件的文本内容:

...

CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchColorCriterion->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetNLSQuery(Text);

...

最终生成的条件文本:

 Color=Basic 25
 其中Basic 25是系统内红色对应的标准色名。
  1. 基于颜色与可见性的筛选条件
目标:筛选出颜色为 (253,4,191) 且处于显示状态的所有对象。
首先创建颜色筛选组件,pIniSearchColorCriterionCATIIniSearchColorCriterion接口指针,用作该组件的操作句柄。
...
CATIIniSearchColorCriterion * pIniSearchColorCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchColorCriterionComponent, NULL, 0,
                         IID_CATIIniSearchColorCriterion,
                         (void**)&pIniSearchColorCriterion);
...
随后传入 RGB 三色参数配置颜色组件,不传入颜色名称,最终筛选条件文本可体现该区别。
...
unsigned int *Color = new unsigned int[3];
Color[0]=253; Color[1]=4; Color[2]=191;
 
rc = pIniSearchColorCriterion->SetParameters(Color[0],Color[1],Color[2],
                                   CATIniSearchEnumeration::Equal);
delete []Color;
...
接着创建可见性筛选组件,pIniSearchVisibilityCriterionCATIIniSearchVisibilityCriterion接口指针,为组件操作句柄。
...
CATIIniSearchVisibilityCriterion * pIniSearchVisibilityCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchVisibilityCriterionComponent, NULL, 0,
                         IID_CATIIniSearchVisibilityCriterion,
                         (void**)&pIniSearchVisibilityCriterion);
...
调用SetParameters方法配置参数:筛选属性为显示属性CATShowAttr、匹配规则为等于(Equal)。
...
rc = pIniSearchVisibilityCriterion->SetParameters(
                                          CATIIniSearchVisibilityCriterion::CATShowAttr,
                                          CATIniSearchEnumeration::Equal);
...
第三种条件为上述两个条件的逻辑与组合条件
...
CATIIniSearchAndCriterion * pIniSearchAndCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchAndCriterionComponent, NULL, 0,
                         IID_CATIIniSearchAndCriterion,
                         (void**)&pIniSearchAndCriterion);
...
将颜色条件、可见性条件作为参数传入组合条件:
...
rc = pIniSearchAndCriterion->SetParameters(pIniSearchVisibilityCriterion,
                                           pIniSearchColorCriterion);
...
最后读取多语言格式(NLS)的筛选条件文本:
...
CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchAndCriterion->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetNLSQuery(Text);
...
生成的条件文本:
(Visibility=Visible & Color='(253,141,91)')
备注:因创建颜色条件时未传入色名,颜色字段采用 RGB 三元组格式填写。
  1. 基于线型与线宽的筛选条件

目标:筛选所有线型为点划线、线宽大于 0.1 毫米的图元。
首先创建线型筛选组件,pIniSearchDashedCriterionCATIIniSearchDashedCriterion接口指针,作为该组件的操作句柄。
...
CATIIniSearchDashedCriterion * pIniSearchDashedCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchDashedCriterionComponent, NULL, 0,
                         IID_CATIIniSearchDashedCriterion,
                         (void**)&pIniSearchDashedCriterion);
...
之后传入线型取值与比较运算符作为参数。线型取值既可以是索引值(可选取值参考CATVisPropertiesValues类的线型读写接口 Get/SetLineType),也可使用字符串。本示例采用本地化字符串"Dotted",即多语言名称;搜索命令里的线型下拉框会展示全部线型本地化名称。
...
rc = pIniSearchDashedCriterion->SetParameters("Dotted",
                                   CATIniSearchEnumeration::Equal);
...
接着创建线宽筛选组件,pIniSearchWeightCriterionCATIIniSearchWeightCriterion接口指针,对应组件操作句柄。
...
CATIIniSearchWeightCriterion * pIniSearchWeightCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchWeightCriterionComponent, NULL, 0,
                         IID_CATIIniSearchWeightCriterion,
                         (void**)&pIniSearchWeightCriterion);
...
配置筛选数值与比较条件:
...
float weight = .1f ;
rc = pIniSearchWeightCriterion->SetParameters(weight,
                                   CATIniSearchEnumeration::Superior);
...
第三种条件为以上两个条件做逻辑与(And)组合
...
CATIIniSearchAndCriterion * pIniSearchAndCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchAndCriterionComponent, NULL, 0,
                         IID_CATIIniSearchAndCriterion,
                         (void**)&pIniSearchAndCriterion);
...
将线宽条件、线型条件传入组合条件:
...
rc = pIniSearchAndCriterion->SetParameters(pIniSearchWeightCriterion,
                                                     pIniSearchDashedCriterion);
...
最后读取多语言(NLS)格式的筛选条件文本:
...
CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchAndCriterion->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetNLSQuery(Text);
...
最终生成的条件表达式:
 
(Weight>0.1mm & Dashed=Dotted)
  1. 基于图层的筛选条件

目的:筛选位于 2 层或 3 层上的所有对象。
首先创建第一个图层条件组件,pIniSearchLayer2CriterionCATIIniSearchLayerCriterion接口指针,作为该组件的操作句柄。
...
CATIIniSearchLayerCriterion * pIniSearchLayer2Criterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchLayerCriterionComponent, NULL, 0,
                         IID_CATIIniSearchLayerCriterion,
                         (void**)&pIniSearchLayer2Criterion);
...
调用SetParameters方法设置图层编号:
...
CATUnicodeString LayerIndex ;
LayerIndex.BuildFromNum(2);
rc = pIniSearchLayer2Criterion->SetParameters(LayerIndex,
                                   CATIniSearchEnumeration::Equal);
...
接着创建第二个图层条件组件,pIniSearchLayer3CriterionCATIIniSearchLayerCriterion接口指针,对应组件操作句柄。
...
CATIIniSearchLayerCriterion * pIniSearchLayer3Criterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchLayerCriterionComponent, NULL, 0,
                         IID_CATIIniSearchLayerCriterion,
                         (void**)&pIniSearchLayer3Criterion);
..
同样通过SetParameters配置图层编号:
...
CATUnicodeString LayerIndex ;
LayerIndex.BuildFromNum(3);
rc = pIniSearchLayer3Criterion->SetParameters(LayerIndex,
                                   CATIniSearchEnumeration::Equal);
...
第三个条件是上述两个条件的逻辑或组合条件
...
CATIIniSearchOrCriterion * pIniSearchOrCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchOrCriterionComponent, NULL, 0,
                         IID_CATIIniSearchOrCriterion,
                         (void**)&pIniSearchOrCriterion);
...
将两个图层条件传入组合条件作为入参:
...
rc = pIniSearchOrCriterion->SetParameters(pIniSearchLayer2Criterion,
                                             pIniSearchLayer3Criterion);
...
最后读取多语言(NLS)格式的筛选条件文本:
...
CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchOrCriterion ->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetNLSQuery(Text);
...
生成的条件表达式:
 
(Layer=2 + Layer=3)
  1. 基于名称的筛选条件
目标:查找所有名称以字符串 “Line” 开头、且不含 “Width” 字符串的对象;前者匹配不区分大小写,后者匹配区分大小写。
首先创建第一个名称筛选组件,pIniSearchNameLineCriterionCATIIniSearchNameCriterion接口指针,作为组件操作句柄。
...
CATIIniSearchNameCriterion * pIniSearchNameLineCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchNameCriterionComponent, NULL, 0,
                         IID_CATIIniSearchNameCriterion,
                         (void**)&pIniSearchNameLineCriterion);
...
检索文本填写为Line*,此处*不作为通配符使用。CorrectString方法可将字符*按普通星号字符解析、而非通配符;该方法第二个入参用于标记原字符串不含通配符,最终筛选文本可体现该效果。
...
CATUnicodeString Name = "" ;
CATUnicodeString StringToCorrect = "Line*" ;
_pIniSearchServices->CorrectString(StringToCorrect,FALSE,Name);
...
调用SetParameters绑定处理后的字符串,配置不区分大小写:Line、line、LINE 均能匹配。
...
CATBoolean CaseSensibility = FALSE ;
rc = pIniSearchNameLineCriterion->SetParameters(Name,CaseSensibility,
                                   CATIniSearchEnumeration::Equal);
...
接着创建第二个名称筛选组件,pIniSearchNameWidthCriterionCATIIniSearchNameCriterion接口指针。
...
CATIIniSearchNameCriterion * pIniSearchNameWidthCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchNameCriterionComponent, NULL, 0,
                         IID_CATIIniSearchNameCriterion,
                         (void**)&pIniSearchNameWidthCriterion);
...
本条件*Width**为通配符,无需字符串校正;开启区分大小写,仅大写小写完全一致的Width才可命中。
...
CATUnicodeString Name = "*Width*" ;
CATBoolean CaseSensibility = TRUE ;
rc = pIniSearchNameWidthCriterion->SetParameters(Name,CaseSensibility,
                                   CATIniSearchEnumeration::Equal);
...
第三个条件为差集逻辑运算(Except:包含前者、剔除后者)
...
CATIIniSearchExceptCriterion * pIniSearchExceptCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchExceptCriterionComponent, NULL, 0,
                         IID_CATIIniSearchExceptCriterion,
                         (void**)&pIniSearchExceptCriterion);
...
将两条名称条件传入差集组合条件,参数先后顺序至关重要
...
rc = pIniSearchExceptCriterion->SetParameters(pIniSearchNameLineCriterion,
                                                     pIniSearchNameWidthCriterion);
...
最后获取转换格式的筛选文本 [1]:
...
CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchExceptCriterion->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetTransFormatQuery(Text);
...
最终生成条件字符串:
(Name=Line'*' - Name_CAP=*Width*)
说明:
  • Name:对应不区分大小写匹配
  • Name_CAP:对应区分大小写匹配
  1. 读取类型字典

高级筛选条件由基于知识类型的条件构成,该类型为CATIType,可通过类型字典获取【1】。
...
CATITypeDictionary_var pITypeDictionaryOnCurrentDic ;
pITypeDictionaryOnCurrentDic = CATGlobalFunctions::GetTypeDictionary();
...
后续章节会用到pITypeDictionaryOnCurrentDic字典指针。
  1. 基于尺寸属性的筛选条件

需求:筛选所有直径大于等于 10 毫米的孔特征。
首先创建类型筛选组件,pIniSearchTypeCriterionCATIIniSearchTypeCriterion接口指针,作为组件操作句柄。
...
CATIIniSearchTypeCriterion * pIniSearchTypeCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchTypeCriterionComponent, NULL, 0,
                         IID_CATIIniSearchTypeCriterion,
                         (void**)&pIniSearchTypeCriterion);
...
调用FindTypeInPackage方法获取孔特征对应的类型;该方法前两个入参说明参考检索技术文档【1】。本例中孔(Hole)隶属于零件设计(PartDesign)模块包。
...
CATIType_var TypePtr;
rc = pITypeDictionaryOnCurrentDic->FindTypeInPackage("Hole","PartDesign",TypePtr);
...
将获取的CATIType类型指针传入类型条件组件;SetParameters最后一个入参为对应工作台内部名,搜索命令的【工作台】下拉列表展示全部工作台,内部名获取方式查阅技术文档【1】。
...
rc = pIniSearchTypeCriterion->SetParameters(TypePtr,
                                   CATIniSearchEnumeration::Equal,"CATPrtSearch");
...
直径属于尺寸类属性,因此创建尺寸属性筛选组件,pIniSearchDimensionCriterion为对应接口操作指针。
...
CATIIniSearchDimensionCriterion * pIniSearchDimensionCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchDimensionCriterionComponent, NULL, 0,
                         IID_CATIIniSearchDimensionCriterion,
                         (void**)&pIniSearchDimensionCriterion);
...
配置参数:属性内部名称、对比数值、比较运算符、属性本地化名称【1】。
...
CATUnicodeString AttributeInternalName = "Diameter" ;
CATUnicodeString AttributeValue = "10.0mm" ;
CATUnicodeString AttributeNLSName = "Diameter" ;

rc = pIniSearchDimensionCriterion->SetParameters(AttributeInternalName,
                                               AttributeValue,
                                               CATIniSearchEnumeration::SupEqual,
                                               AttributeNLSName);
...
将上述类型条件尺寸属性条件逻辑与(And)组合:
...
CATIIniSearchAndCriterion * pIniSearchAndCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchAndCriterionComponent, NULL, 0,
                         IID_CATIIniSearchAndCriterion,
                         (void**)&pIniSearchAndCriterion);
...
参数顺序不可颠倒,类型条件必须放在第一位
...
rc = pIniSearchAndCriterion->SetParameters(pIniSearchTypeCriterion,
                                                     pIniSearchDimensionCriterion);
...
最后获取转换格式的条件文本【1】:
...
CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchAndCriterion->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetTransFormatQuery(Text);
...
生成条件表达式:
 
CATPrtSearch.Hole.Diameter>=10mm
说明:转换格式字符串全部使用内部命名:
 
CATPrtSearch:工作台内部名;Hole:特征类型名;Diameter:属性内部名。
  1. 基于字符串属性的筛选条件

目标:检索所有零部件编号以 “CAAPart” 开头的产品特征。
首先创建类型筛选组件,pIniSearchTypeCriterionCATIIniSearchTypeCriterion接口指针,用作该组件的操作句柄。
...
CATIIniSearchTypeCriterion * pIniSearchTypeCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchTypeCriterionComponent, NULL, 0,
                         IID_CATIIniSearchTypeCriterion,
                         (void**)&pIniSearchTypeCriterion);
...
通过FindTypeInPackage【1】方法获取产品特征对应的类型。
...
CATIType_var TypePtr;
rc = pITypeDictionaryOnCurrentDic->FindTypeInPackage("Product","ProductPackage", TypePtr);
...
随后将CATIType接口指针作为参数传入类型组件。SetParameters方法最后一个入参是该特征所属工作台的内部名称【1】。
...
rc = pIniSearchTypeCriterion->SetParameters(TypePtr,
                                   CATIniSearchEnumeration::Equal,
                                   "CATProductSearch");
...
“零部件编号(Part Number)” 属于字符串类型属性,因此创建字符串筛选组件,pIniSearchStringCriterionCATIIniSearchStringCriterion接口指针与组件句柄。
...
CATIIniSearchStringCriterion * pIniSearchStringCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchStringCriterionComponent, NULL, 0,
                         IID_CATIIniSearchStringCriterion,
                         (void**)&pIniSearchStringCriterion );
...
为字符串组件赋值:属性内部名、比对内容、大小写标识、比较规则、属性本地化名称【1】。末尾参数为可选参数,若不配置且未加载带该属性的模型文档,GetNLSQuery接口会返回失败码 E_FAIL。
...
CATUnicodeString AttributeInternalName = "PartNumber" ;
CATUnicodeString AttributeNLSName = "Part Number" ;
CATUnicodeString AttributeValue        = "CAAPart*" ;
CATBoolean CaseSensibility             = FALSE ;
rc = pIniSearchStringCriterion->SetParameters(AttributeInternalName,
                                               AttributeValue,
                                               CaseSensibility ,
                                               CATIniSearchEnumeration::Equal,
                                               AttributeNLSName);
...
第三步对类型条件字符串属性条件逻辑与(And)组合:
...
CATIIniSearchAndCriterion * pIniSearchAndCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchAndCriterionComponent, NULL, 0,
                         IID_CATIIniSearchAndCriterion,
                         (void**)&pIniSearchAndCriterion);
...
两个筛选条件传入组合对象,入参顺序不可调换,类型条件必须在前
...
rc = pIniSearchAndCriterion->SetParameters(pIniSearchTypeCriterion,
                                             pIniSearchStringCriterion);
...
最后读取标准格式化查询文本【1】:
...
CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchAndCriterion->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetTransformatQuery(Text);
...
生成查询表达式:
 
CATProductSearch.Product.PartNumber="CAAPart*"
格式化表达式内全部字段均采用内部命名:
 
CATProductSearch:工作台内部名;Product:特征类型名;PartNumber:属性内部名。可与下一条筛选表达式做对比。
  1. 基于用户自定义属性的筛选条件

目标:检索所有【CAAAttr】自定义属性值小于等于 0.1 的产品特征。
首先创建类型筛选组件,pIniSearchTypeCriterionCATIIniSearchTypeCriterion接口指针,作为组件操作句柄,实现细节参考上一章节。
属性CAAAttr为用户自定义属性,因此创建自定义属性筛选组件,pIniSearchUserCriterionCATIIniSearchUserCriterion接口指针与组件句柄。
...
CATIIniSearchUserCriterion * pIniSearchUserCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchUserCriterionComponent, NULL, 0,
                         IID_CATIIniSearchUserCriterion,
                         (void**)&pIniSearchUserCriterion);
...
给自定义属性筛选组件配置参数:属性内部名称、对比数值、比较运算符【1】。
...
CATUnicodeString AttributeInternalName = "CAAAttr" ;
CATUnicodeString AttributeValue = ".1" ;
rc = pIniSearchUserCriterion->SetParameters(AttributeInternalName,
                                               AttributeValue,
                                               CATIniSearchEnumeration::InfEqual);
...
第三步将特征类型条件自定义属性条件进行逻辑与(And)组合:
...
CATIIniSearchAndCriterion * pIniSearchAndCriterion = NULL ;
rc = ::CATCreateInstance(CLSID_CATIniSearchAndCriterionComponent, NULL, 0,
                         IID_CATIIniSearchAndCriterion,
                         (void**)&pIniSearchAndCriterion);
..
把两个筛选条件传入组合条件,参数顺序不可更改,类型条件必须放在首位
...
rc = pIniSearchAndCriterion->SetParameters(pIniSearchTypeCriterion,
                                             pIniSearchUserCriterion);
....
最后读取多语言格式(NLS)的条件文本【1】:
...
CATIIniSearchCriterion * pSearchCriterion = NULL ;
rc = pIniSearchAndCriterion->QueryInterface(IID_CATIIniSearchCriterion,
                                                  (void**) &pSearchCriterion);

CATUnicodeString Text = "" ;
pSearchCriterion->GetNLSQuery(Text);
...
生成条件文本:
 
'Product Structure'.Product.CAAAttr<=.1
该字符串为本地化 NLS 文本,字段全部采用译文名称:
 
Product Structure:工作台显示名称;Product:特征类型名;CAAAttr:自定义属性名。可与上一条格式化查询文本做对照。
  1. 执行检索查询

用户点击【启动】按钮(见图 2)后,会触发 CAACafSearchCmd 类的动作回调函数。该函数执行逻辑:先根据条件文本重建检索条件、获取当前检索范围,最后发起查询。
第一步:读取用户选中项对应的条件文本。
...
int CriterionIndex = -1 ;
_pSearchDlg->GetCurrentCriterion(CriterionIndex);

CATUnicodeString CriterionText = "";
if ( NULL != _pListCriterionTexts )
{
   if ( (CriterionIndex >= 1) && (CriterionIndex <= _pListCriterionTexts->Size()) )
   {
      CriterionText = (*_pListCriterionTexts)[CriterionIndex];
   }
}
...
第二步:调用 CAACafSearchDlg 类的 GetCurrentContext 接口,获取用户选定的检索上下文范围。
...
CATIIniSearchContext::Scope ContextValue = CATIIniSearchContext::Everywhere ;
_pSearchDlg->GetCurrentContext(ContextValue);
...
第三步:通过CATIIniSearchServices接口的DecodeStringToCriterion方法,由条件文本反向生成检索条件对象。
 
_pIniSearchServices是前文「创建引擎、上下文与服务组件」章节实例化的服务组件句柄;入参CriterionText即上一步取出的条件文本,出参pIniSearchCriterion为新生成条件的接口指针。第二个入参FALSE代表:解析出错时不弹出错误提示窗口。
...
CATIIniSearchCriterion * pIniSearchCriterion = NULL ;
rc = _pIniSearchServices->DecodeStringToCriterion(CriterionText,
                                                   FALSE,
                                                   pIniSearchCriterion);
...
第四步:使用当前选中范围更新上下文组件,_pIniSearchContextOnCurrentContext为之前创建的上下文组件指针。
...
rc = _pIniSearchContextOnCurrentContext->SetScope(ContextValue);
...
第五步:绑定检索条件与检索上下文,组装查询任务。_pIniSearchEngineOnCurrentEngine是已创建的搜索引擎对象。
...
rc = _pIniSearchEngineOnCurrentEngine->SetCriterionAndContext(pIniSearchCriterion,
                                                _pIniSearchContextOnCurrentContext);
...
第六步:执行文档检索。LaunchSearchOnDocument默认入参为 NULL,代表在当前激活文档内执行搜索。
...
rc = _pIniSearchEngineOnCurrentEngine->LaunchSearchOnDocument();
...
检索结果的处理逻辑在下一章节说明。
  1. 在 PSO 中显示检索到的对象

检索命中的对象需要进行预选高亮,这些对象会被存入绑定当前文档(实际是当前文档对应的编辑器)的CATPSO实例中。成员变量_pPsoCAACafSearchCmd类的构造函数内完成获取,代码如下:
...
CATFrmEditor * pEditor = GetEditor();
if ( NULL !=  pEditor )
{
    _pPso = pEditor->GetPSO();
}
...
GetEditorCATStateCommand(状态命令)的成员方法,用于获取关联激活文档的CATFrmEditor编辑器实例,PSO 实例由该编辑器创建【6】。
调用CATIIniSearchEngine接口的GetFoundObjects方法获取全部检索结果,返回值pListOfFoundObjectsCATSO类型对象,存储所有对象的完整路径;列表内每个元素都是可视化框架下的CATPathElement对象。
补充说明:pListOfFoundObjects不会为空;若无匹配对象,GetFoundObjects直接返回错误码E_FAIL
...
CATSO * pListOfFoundObjects = NULL ;
int nbelt = 0 ;
_pIniSearchEngineOnCurrentEngine->GetFoundObjects(pListOfFoundObjects);
...
由于搜索结果可能包含多个对象,循环调用AddElements将对象全路径添加至 PSO,全部添加完毕后调用EndAddElements结束添加操作。
...
nbelt = pListOfFoundObjects->GetSize();
        
if ( NULL != _pPso )
{
   for ( int i= 0 ; i < nbelt ; i++ )
   {
      CATBaseUnknown * pCurrent = (*pListOfFoundObjects)[i] ;
      if ( NULL != pCurrent )
      {
               _pPso->AddElements(pCurrent);
      }
    }
    _pPso->EndAddElements();
}
...
 
posted @ 2026-06-02 14:18  Breadss  阅读(10)  评论(0)    收藏  举报