Message 1 of 2
Custom block can't be dynamic

Not applicable
05-25-2020
11:40 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi,
I created a new class (PICBlock) inherited from AcDbBlockReference I also create a wrapper(MgPICBlock) to use it in .Net.
class PICBlock : public AcDbBlockReference { public: ACRX_DECLARE_MEMBERS(PICBlock); static void makeMembers(AcRxMemberCollectionBuilder& collectionBuilder, void* customData); protected: static Adesk::UInt32 kCurrentVersionNumber; public: PICBlock(); PICBlock(const AcGePoint3d& position, AcDbObjectId blockTableRec); Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const final; Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler)final; Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const final; Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler)final; Acad::ErrorStatus subClose()override; void setManagedWrapper(gcroot<Autodesk::PIC::MgPICBlock^> p); private: gcroot<Autodesk::PIC::MgPICBlock^> m_pManaged; // the managed wrapper pointer. }; Adesk::UInt32 PICBlock::kCurrentVersionNumber = 1; ACRX_DXF_DEFINE_MEMBERS_WITH_PROPERTIES( PICBlock, AcDbBlockReference, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation, PIC-BLOCK, PICBLOCK "|Product Desc: PIC-ACAD" "|Company: So.Build" "|WEB Address: www.sobuild.fr", PICBlock::makeMembers ) void PICBlock::makeMembers( AcRxMemberCollectionBuilder& collectionBuilder, void* customData) { readFromResource("PIC_Attributs.xml", collectionBuilder); } PICBlock::PICBlock() : AcDbBlockReference() { // } PICBlock::PICBlock(const AcGePoint3d& position, AcDbObjectId blockTableRec) : AcDbBlockReference(position, blockTableRec) { // } Acad::ErrorStatus PICBlock::dwgOutFields(AcDbDwgFiler* pFiler) const { Acad::ErrorStatus retStat = AcDbBlockReference::dwgOutFields(pFiler); if (retStat != Acad::eOk) return retStat; retStat = pFiler->writeUInt32(PICBlock::kCurrentVersionNumber); return retStat; } Acad::ErrorStatus PICBlock::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus retStat = AcDbBlockReference::dwgInFields(pFiler); if (retStat != Acad::eOk) return retStat; Adesk::UInt32 uiVersion = 0; retStat = pFiler->readUInt32(&uiVersion); return retStat; } Acad::ErrorStatus PICBlock::dxfOutFields(AcDbDxfFiler* pFiler) const { Acad::ErrorStatus retStat = AcDbBlockReference::dxfOutFields(pFiler); if (retStat != Acad::eOk) return retStat; retStat = pFiler->writeUInt32(AcDb::kDxfInt32, PICBlock::kCurrentVersionNumber); return retStat; } Acad::ErrorStatus PICBlock::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus retStat = AcDbBlockReference::dxfInFields(pFiler); if (retStat != Acad::eOk) return retStat; resbuf data; Adesk::UInt32 uiVersion = 0; retStat = pFiler->readItem(&data); if ((data.restype != AcDb::kDxfInt32) || (retStat != Acad::eOk)) return (retStat != Acad::eOk) ? retStat : Acad::eNotApplicable; uiVersion = data.resval.rint; return retStat; } Acad::ErrorStatus PICBlock::subClose() { Acad::ErrorStatus es; if ((es = AcDbBlockReference::subClose()) != Acad::eOk) return es; if (isWriteEnabled() == Adesk::kTrue) { //You have to cast it back to the managed type to do a null check: if (static_cast<Autodesk::PIC::MgPICBlock^>(m_pManaged) != nullptr) { // Call the method on the wrapper which will propagate to all managed // listeners of this event... m_pManaged->PICBlockModified(ToObjectId(objectId())); } } return Acad::eOk; } void PICBlock::setManagedWrapper(gcroot<Autodesk::PIC::MgPICBlock^> p) { m_pManaged = p; } ACDB_REGISTER_OBJECT_ENTRY_AUTO(PICBlock)
[Autodesk::AutoCAD::Runtime::Wrapper("PICBlock")] public ref class MgPICBlock : public Autodesk::AutoCAD::DatabaseServices::BlockReference { public: MgPICBlock(); MgPICBlock(Point3d position, Autodesk::AutoCAD::DatabaseServices::ObjectId blockTableRecord); internal: MgPICBlock(System::IntPtr unmanagedPointer, bool autoDelete); // Here is the method which will consistently give us our unmanaged (AsdkSimpleSquare) object. inline PICBlock* GetImpObj() { // UnmanagedObject() is a method of the AutoCAD managed wrappers which always // gives us a way to access the underlying ObjectARX objects so we can use them // within our C++ application freely. return static_cast<PICBlock*>(UnmanagedObject.ToPointer()); } public: // Here are the methods defined to support exposure of our event. event PICBlockModifiedHandler^ PICBlockModified { public: void add(PICBlockModifiedHandler^); void remove(PICBlockModifiedHandler^); void raise(Autodesk::AutoCAD::DatabaseServices::ObjectId); } private: // Here is our member delegate which represents the event for this object. PICBlockModifiedHandler^ m_pPICBlockModifiedHandler; }; MgPICBlock::MgPICBlock() : Autodesk::AutoCAD::DatabaseServices::BlockReference(System::IntPtr(new PICBlock()), true) { GetImpObj()->setManagedWrapper(this); m_pPICBlockModifiedHandler = nullptr; } MgPICBlock::MgPICBlock(Point3d position, Autodesk::AutoCAD::DatabaseServices::ObjectId blockTableRecord) : Autodesk::AutoCAD::DatabaseServices::BlockReference(System::IntPtr(new PICBlock(AcGePoint3d(position.X, position.Y, position.Z), AcDbObjectId((const AcDbStub*)blockTableRecord.OldIdPtr.ToInt64()))), true) { GetImpObj()->setManagedWrapper(this); m_pPICBlockModifiedHandler = nullptr; } ////////////////////////////////////////////////////////////////////////// // constructor for the managed wrapper This form takes an already established unmanaged object // and simply attaches this wrapper to it. MgPICBlock::MgPICBlock(System::IntPtr unmanagedPointer, bool autoDelete) : Autodesk::AutoCAD::DatabaseServices::BlockReference(unmanagedPointer, autoDelete) { m_pPICBlockModifiedHandler = nullptr; }
If I create a blockrefrence from a dynamic block it works BUT if I create a PICBloc with the same blockrecord
I loose the dynamic properties.
I create blockrefrence and MgPICBlock in the same way.
MgPICBlock picblock = new MgPICBlock(position, blockRecId); BlockReference blockref = new BlockReference (position, blockRecId);
What I'm doing wrong ?
thanks