如图所示:我才用代码读取 某一个参数cell 的 属性(参数),发现可以读取 Genneral、Geometry、Raw Data、等板块的信息,但是 Variables 板块的信息 没有读取到, 请问大神 是什么原因?
具体代码如下:
bool doubleClickCallbackFunc2(DisplayPathCP path) { WString filename; ElementRefP eP = path->GetHeadElem(); DgnModelRefP currFileP = mdlDisplayPath_getPathRoot(path); MSElementDescrP elDescr; mdlElmdscr_getByElemRef(&elDescr, eP, currFileP, FALSE, NULL); EditElementHandle eeh(elDescr, FALSE, TRUE , 0); FindInstancesScopePtr scope = FindInstancesScope::CreateScope(eeh, FindInstancesScopeOption(DgnECHostType::All)); ECQueryPtr query = ECQuery::CreateQuery(ECQUERY_PROCESS_SearchAllClasses); DgnECInstanceIterable iterable = Bentley::DgnPlatform::DgnECManager::GetManager().FindInstances(*scope, *query); DgnECInstancePtr instance = *((iterable.begin())); ECN::ECClassCR instanceClass = instance->GetClass(); ECPropertyIterable properties = instanceClass.GetProperties(); for (ECPropertyIterable::const_iterator it0 = properties.begin(); it0 != properties.end(); ++it0) { ECValue v; ECPropertyCP pProp = (*it0); WString ddeea = pProp->GetTypeName(); WString ecpName = pProp->GetName(); WString ecpDesc = pProp->GetDescription(); WString ecpVVV = pProp->GetInvariantDescription(); WString ersV = pProp->GetDisplayLabel(); mdlDialog_dmsgsPrint(WPrintfString(L"名称:%s 类型:%s 内容:%s", ecpName, ddeea, ersV)); } filename.Sprintf(L"D:\\1.xml"); instance->WriteToXmlFile(filename.data(), true, true); instance->WriteChanges(); mdlDialog_dmsgsPrint(WPrintfString(L"名称:%s 内容:%s ", L"长度:", L"123" )); return true; }
这个帖子里边的方法您试过没有:https://communities.bentley.com/communities/other_communities/chinafirst/f/microstation-projectwise/143095/c-ce
测试过了,我编写的demo 就是根据 上面的代码 进行的修改,但是 还死活不能获取 图中 标红部分的 参数信息,也就是 我们设置的尺寸信息 或 与约束相关的信息,也就是 edit item 部分的变量 ,遍历不出来。
Bentley 二次开发小白一枚
当我们放置一个参数化单元时,会首先在当前文件中生成一个隐藏的模型,该模型来自于参数化单元库中对该单元的定义。我们看到的每个参数化单元元素都是对该定义的一个引用(或者叫实例)。在隐藏的那个定义模型中有一套参数集,在我们能看到的每个参数化单元实例上也有一套参数集。
Answer Verified By: 平凡人生
Celltest4-chengtai.cel
老师好:
我测试了 您的代码,发现 生成的xml 文件 已经存在我想要的参数(属性)了,但是,并没有打印出来,也就是说 没有再数组里面哪些参数。
另外,经过测试我发现
ECPropertyIterable properties = inst.GetClass().GetProperties(); ECPropertyCP pProp = *properties.begin(); ECValue v; inst.GetValue(v, pProp->GetName().data()); ArrayInfo ai = v.GetArrayInfo(); // array of structures, first to get array
代码中 pProp->GetName().data() 的返回值 为Name ,ai.GetCount()返回值为0。
是不是说明,我的参数 没有 再 数组里面?
不知道你是如何测试的。我这里测试的结果如下:
之所以我们显示的属性对比较多,是因为我们将隐藏的所有属性对都显示出来了。
是不是 我的 cell 文件 在定义 参数化cell 的时候 有问题, 老师 辛苦您一下, 看一下 我给您传的文件。0636.Celltest4-chengtai.cel
你的参数化单元定义是否引用了ItemType?我看到如下内容:
对于这种复杂的情况,还得再增加一个过滤,我简化的代码直接取的是properties.begin()
改进后的代码如下:
void extractParametricCellVariables(WCharCP) { ElementHandle eh(3090L, ACTIVEMODEL); if (!eh.IsValid()) { mdlDialog_dmsgsPrint(L"Element is invalid"); return; } ParametricCellHandler* pHandler = dynamic_cast<ParametricCellHandler*>(&eh.GetHandler()); if (nullptr == pHandler) { mdlDialog_dmsgsPrint(L"Element is not a parametric cell element"); return; } ParameterStatus status; ParametricCellInfoPtr pInfo = pHandler->GetCellInfo(status, eh); if (ParameterStatus::Success != status) { mdlDialog_dmsgsPrint(L"Fail to get parametric cell information"); return; } IECInstanceR inst = pInfo->GetProperties(); inst.WriteToXmlFile(L"D:\\PCInfo.XML", true, true); //Open this XML file to learn more about this complex instance ECPropertyIterable properties = inst.GetClass().GetProperties(); for (ECPropertyIterable::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) { ECPropertyCP pProp = *iter; if (!pProp->GetName().Equals(L"ParameterValuesContainer")) continue; ECValue v; inst.GetValue(v, pProp->GetName().data()); ArrayInfo ai = v.GetArrayInfo(); // array of structures, first to get array for (uint32_t i = 0; i < ai.GetCount(); i++) { ECValue label, value; inst.GetValue(v, pProp->GetName().data(), i); IECInstancePtr pInst2 = v.GetStruct(); // then get strucuture pInst2->GetValue(label, L"Adhoc_Label"); pInst2->GetValue(value, L"Adhoc_Value"); WPrintfString wStr(L"PropertyLabel:%s, Value:%s", label.GetString(), value.GetString()); mdlDialog_dmsgsPrint(wStr); } } }
执行结果如下:
我的问题已经解决,万分感谢您的帮助和支持!!!!
但是还有一些问题没有弄明白,期望您能给出专业详实的意见或分析。
1、我的问题是:我可以读取出cell 中的 属性参数为,右键单击 属性后,除 去变量外的所有属性信息,如下图所示:
2、在您的帮助下,我已经能够成功读取出 图 中 不能读取出来的部分,而且是只能读取出来 那部分,没有其他:信息。
我经过代码比对后发现:
差异部分为:
1、不能读取变量的代码为:
FindInstancesScopePtr scope = FindInstancesScope::CreateScope(eeh, FindInstancesScopeOption(DgnECHostType::All)); ECQueryPtr query = ECQuery::CreateQuery(ECQUERY_PROCESS_SearchAllClasses); DgnECInstanceIterable iterable = Bentley::DgnPlatform::DgnECManager::GetManager().FindInstances(*scope, *query); DgnECInstancePtr instance = *((iterable.begin()));//ECN::ECClassCR instanceClass =instance->GetClass() ; ECPropertyIterable properties = instance->GetClass().GetProperties();
2、可以读取变量,但是不能读取其他信息的代码为:
ParametricCellInfoPtr pInfo = pHandler->GetCellInfo(status, eeh);//获取指定参数化cell 的 信息 IECInstanceR inst = pInfo->GetProperties(); ECPropertyIterable properties = inst.GetClass().GetProperties();
也就是 由类 FindInstancesScopePtr、ECQueryPtr 、DgnECInstanceIterable 和 ParametricCellInfoPtr 、IECInstanceR 造成的,
这些类的功能和作用 是什么?或者 是什么原因造成的结果的不同呢?他们针对的是 参数化单元不同结构的信息吗?或者是其他的逻辑业务呢?
iterable是一个容器,里边有多个元素。您通过iterable.begin()获取到的只是容器内第一个元素的“指针”。通过对这个“指针”进行++运算可以依次访问容器内后边的元素。iterable.end()是最后一个元素后边的位置,所以对“指针”++元素时,判断等于iterable.end()时就要结束循环了。我上边引用的那个帖子里边代码第一层循环就是在遍历这个容器。而您不能读取变量的代码就是因为只是访问了这个容器的第一个元素所以读取不到,要遍历这个容器内的所有元素才能读取到。
谢谢您的 回复 !!! 感谢!!!
但是 我 想问的是 :
1、FindInstancesScope 代表什么?
2、ECQuery代表什么?
3、DgnECInstance代表什么?
4、ParametricCellInfo代表什么?
5、IECInstance代表什么?
6、另外 您说的容器中的元素,指的是 什么?在您不同的循环中,因为您 是一个 嵌套循环嘛,所以 不同层的 循环中 容器 中存放的元素 是什么?
理解清楚我上边给您解释的EC相关的概念这几个对象自然就明白什么意思了。至于容器建议您找一本c/c++语言的书,把模板以及c/c++通用模板库相关的章节看一下