【问题描述】通过查阅论坛讨论找到重写DgnElementSetTool的_IsModifyOriginal方法(返回false)可以让选择工具选中参考文件中的元素,但是这样子做了之后在_OnModifyComplete方法中无法获取元素id(得到的id始终为0),而_IsModifyOriginal方法返回true时可以正确获取元素id。
请问如何在能够选中参考文件中的元素的同时正确的获取元素的id?
从GetElementAgenda中获得选中的元素的列表,然后进一步获得ElementID应该可行吧?
符老师,这个我测试过了哈,一样不行;同时我还仔细看了下接口传入的EditElementHandle的其他接口,GetElementRef返回为NULL,GetModelRef返回不为空,但是模型错误(我把model的名称打印出来对比了下),PeekElementDescrCP返回不为NULL。目前怀疑是因为仅MSElementDescr有效导致无法获取元素id的。
重写一下DgnElementSetTool的成员函数_OnPostInstall,在这个函数里边调用DgnElementSetTool的基类ModifyOp的成员函数_GetCopyContext,调用返回的ElementCopyContext的AddHandler函数,给一个ElementCopyContext::IEventHandler监听器,在监听器的OnElementCopied函数里边可以获取到原始的元素。
Answer Verified By: yxChen
郭老师,我这边试了下,写了个空白的IEventHandler子类,仅在OnElementCopied方法内部打印EditElementHandle的id,但是实际运行时程序会奔溃,查看日志是奔溃再了Bentley::DgnPlatform::ElementCopyContext::CalculateReferenceScale这,而且无论我选择的元素是否是参考文件元素均会奔溃。
传递给AddHandler的不能是局部变量的地址,如下所示可以传递这个类的静态变量的地址:
class TestEventHandlerVerifier : public Bentley::DgnPlatform::ElementCopyContext::IEventHandler { public: static TestEventHandlerVerifier s_TestEventHandlerVerifier; private: mutable UInt32 m_refCount; public: TestEventHandlerVerifier() { m_refCount = 0; } virtual ~TestEventHandlerVerifier() {} virtual void OnElementCopied(EditElementHandleR eh, Bentley::DgnPlatform::ElementCopyContext &, bool isPre) { if(isPre) { ElementId id = eh.GetElementId(); printf("OnElementCopied==%d\n", id); } return; } virtual void OnLevelCloned(ULong destLevelId, ULong sourceLevelId, bool uniqueName, Bentley::DgnPlatform::ElementCopyContext &cc) { } UInt32 AddRef() const override { return ++m_refCount; } UInt32 Release() const override { if (1 < m_refCount--) return m_refCount; delete this; return 0; } };