My_elementRef 是当前model中选中的参考文件的元素,写XAttribute失败了,返回值是-105。但是如果将参考文件合并到主文件,就会写入成功。请问是什么原因呢?
ElementRefP My_elementRef = mdlDisplayPath_getElem(path, mdlDisplayPath_getCursorIndex((DisplayPathP)path)); ElementID elID = My_elementRef->GetElementId(); EditElementHandle eeh(elID, ACTIVEMODEL); //添加attribute的元素 ... ... ... XAttributeHandlerId xAttHandlerId(234, 567); UInt32 xAttId = 101; XAttributeHandle xAttHandle(eeh.GetElementRef(), xAttHandlerId, xAttId); StatusInt iRet = -1; if (xAttHandle.m_node.m_xattr == NULL) { //直接存 iRet = ITxnManager::GetCurrentTxn().AddXAttribute(eeh.GetElementRef(), xAttHandlerId, xAttId, pdata, size); // eeh.ScheduleWriteXAttribute(xAttHandlerId, xAttId, size, pdata); }
参考文件是只读的,所以无法对参考文件进行写操作。
我改成参考文件的model指针也不行啊。返回值-108
还是一样的,对当前文件中参考文件是没办法去进行写操作的,要么合并,要么重新打开参考文件进行编辑。
我代码中不是重新打开参考文件进行编辑了吗?现在问题就是我重新打开参考文件进行编辑但是没有效果。filepath就是参考文件的路径
下面代码可以对打开的dgn写元素,既然能写,属性肯定也可以的:
WString strDgn("D:\\test.dgn"); DgnDocumentPtr pDgnDoc = DgnDocument::CreateForLocalFile(strDgn.GetWCharCP()); DgnFilePtr pDgn = DgnFile::Create(*pDgnDoc, DgnFileOpenMode::ReadWrite); StatusInt openForWriteStatus; pDgn->LoadDgnFile(&openForWriteStatus); if (!pDgn->IsOpen()) { mdlDialog_dmsgsPrint(L"The file can't be written"); return false; } pDgn->FillDictionaryModel(); DgnModelPtr pModel = pDgn->LoadModelById(pDgn->GetDefaultModelId()); pDgn->FillSectionsInModel(pModel.get()); DSegment3d segment = DSegment3d::From(0, 0, 0, 0, 0, 10000); EditElementHandle eeh; LineHandler::CreateLineElement(eeh, nullptr, segment, true, *pModel); eeh.AddToModel(); pDgn->ProcessChanges(DgnSaveReason::FileClose);
谢谢,我拿您这段代码试试。
给您完整的代码吧 :
WString strDgn("D:\\test.dgn"); DgnDocumentPtr pDgnDoc = DgnDocument::CreateForLocalFile(strDgn.GetWCharCP()); DgnFilePtr pDgn = DgnFile::Create(*pDgnDoc, DgnFileOpenMode::ReadWrite); StatusInt openForWriteStatus; pDgn->LoadDgnFile(&openForWriteStatus); if (!pDgn->IsOpen()) { mdlDialog_dmsgsPrint(L"The file can't be written"); return false; } pDgn->FillDictionaryModel(); DgnModelPtr pModel = pDgn->LoadModelById(pDgn->GetDefaultModelId()); pDgn->FillSectionsInModel(pModel.get()); DSegment3d segment = DSegment3d::From(0, 0, 0, 0, 0, 10000); EditElementHandle eeh; LineHandler::CreateLineElement(eeh, nullptr, segment, true, *pModel); eeh.AddToModel(); char *appData = "My XAttribute Data"; XAttributeHandlerId xAttHandlerId(234, 567); UInt32 xAttId = 101; XAttributeHandle xAttHandle(eeh.GetElementRef(), xAttHandlerId, xAttId); StatusInt iRet = -1; if (xAttHandle.m_node.m_xattr == NULL) { //直接存 iRet = ITxnManager::GetCurrentTxn().AddXAttribute(eeh.GetElementRef(), xAttHandlerId, xAttId, appData, 30); } else { //删除再存 ITxnManager::GetCurrentTxn().DeleteXAttribute(xAttHandle); ITxnManager::GetCurrentTxn().AddXAttribute(eeh.GetElementRef(), xAttHandlerId, xAttId, appData, 30); // eeh1.ScheduleDeleteXAttribute(xAttHandlerId, xAttId); // eeh1.ScheduleWriteXAttribute(xAttHandlerId, xAttId, size, pdata); } //mdlModelRef_freeWorking(dgnModel); pDgn->ProcessChanges(DgnSaveReason::FileClose);
我这还是不行,我看了一下被参考的文件,发现被参考的文件是一个2Dmodel,然后该model又参考了该dgn的3Dmodel.如下图所示,而我用的defaultModel,所以该Dgn还是只读的,现在我改成了3Dmodel指针,该线画出来了,但是属性没写成功还是返回-108。
加载model时我改成了这样
DgnModelPtr pModel = file->LoadModelById(elRef->GetDgnModelP()->GetModelId());//加载鼠标所选的参考文件的元素所在的model
线画出来了(红色框内),DSegment3d segment = DSegment3d::From(0, 0, 0, 1000000, 0, 0);坐标改了, 要不会是一个点。
但是iRet = ITxnManager::GetCurrentTxn().AddXAttribute(elRef, xAttHandlerId, xAttId, pdata, size)还是返回-108.
你把你的模型上传一下,我这边试试。
我邮箱发给你了的
你直接给我发邮件吧xiaoqi.zhang@bentley.com,把你的模型给我发下,注明dgn哪个是参考的,你想把xattribute写到哪个dgn里。
多谢张老师的指导,根据张老师提供的代码和其他帖子做的了以下总结:
写参考文件元素属性时,不能直接通过当前DGN中所选中的参考文件中元素的elementRefP来构造XAttributeHandle,这样写不成功,现已成功的一种方式如下,需记录选中的元素ID即ElementID,并重新打开参考文件进行编辑并加载选中元素所在model,且通过ElementRefP elRefP = pModel->FindElementByID(elmID) 来获取elRefP,通过该elRefP来构造XAttributeHandle,这样才能写成功,代码如下:
ElementRefP elRefP = mdlDisplayPath_getElem(path, mdlDisplayPath_getCursorIndex((DisplayPathP)path)); ElementId elmID = elRefP->GetElementId(); WString filepath = elRefP->GetDgnModelP()->GetDgnFileP()->GetDocumentPtr()->GetFileName(); DgnDocumentPtr pDgnDoc = DgnDocument::CreateForLocalFile(filepath.GetWCharCP()); DgnFilePtr file = DgnFile::Create(*pDgnDoc, DgnFileOpenMode::ReadWrite); StatusInt openForWriteStatus; file->LoadDgnFile(&openForWriteStatus); if (!file->IsOpen()) { mdlDialog_dmsgsPrint(L"The file can't be written"); return; } file->FillDictionaryModel(); DgnModelPtr pModel = file->LoadModelById(elRefP->GetDgnModelP()->GetModelId()); file->FillSectionsInModel(pModel.get()); if (pModel != NULL) { // 获取参考文件中的元素对象 elRefP = pModel->FindElementByID(elmID); } //存储的key值 XAttributeHandlerId xAttHandlerId(234, 567); UInt32 xAttId = 101; XAttributeHandle xAttHandle(elRefP, xAttHandlerId, xAttId); StatusInt iRet = -1; if (xAttHandle.m_node.m_xattr == NULL) { //直接存 iRet = ITxnManager::GetCurrentTxn().AddXAttribute(elRefP, xAttHandlerId, xAttId, pdata, size); } else { //删除再存 ITxnManager::GetCurrentTxn().DeleteXAttribute(xAttHandle); ITxnManager::GetCurrentTxn().AddXAttribute(elRefP, xAttHandlerId, xAttId, pdata, size); } file->ProcessChanges(DgnSaveReason::FileClose);
参考帖子:
https://communities.bentley.com/communities/other_communities/chinafirst/f/microstation-projectwise/188733/ms-v8i-c
Answer Verified By: Xiang Liu