【MSCE mdl C++】DgnElementSetTool如何获取选中的参考文件元素id

【问题描述】通过查阅论坛讨论找到重写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;
    	}
    };