I mentioned ItemTypeLibraryMgr in a post on the Forum. It's a helper class to wrap common usage of the MicroStationAPI with Item Type libraries. Use at your own risk. Support is not included.
ItemTypeLibraryMgr
You need these headers...
#include <Mstn/MdlApi/MdlApi.h> #include <Mstn/MicroStation.r.h> #include <DgnPlatform/DgnPlatform.r.h> #include <ECObjects/ECObjects.h>
Here's the class declaration...
struct ItemTypeLibraryMgr { const WString libName_; /// Construct an Item Type Library Manager for the named library. ItemTypeLibraryMgr (WCharCP libName) : libName_ (libName) {} /// Determine if the Item Type Library exists in the active DGN file. bool ExistsInActiveFile () const; /// Determine if the Item Type Library exists in a given DGN file. bool ExistsInFile (DgnFileR dgnfile) const; /// Get a pointer to a library from the active DGN file. ItemTypeLibraryPtr Get () const; /// Get a pointer to a library from a given DGN file. ItemTypeLibraryPtr Get (DgnFileR dgnfile) const; /// Find a library by searching DGNLibs. bool FindAndCopyDefFromDgnLib (WCharCP libName) const; /// Find a library by searching DGNLibs. /// This method below is fine, but we've taken a different route. bool CopyFromDgnLib (WCharCP libName) const; /// Copy a library from a given DGN file to the active DGN file. /// Returns true if the copy succeeded. bool CopyToActive (DgnFileR dgnfile) const; /// Search for a named DgnLib. /// Looks in folders specified by MS_DGNLIBLIST. /// dgnLib: Pointer to a DGN file. /// fileName: DgnLib name to seek. /// Returns true if DgnLib is found and our Item Type library is defined in that file. bool FindDgnLib (DgnFilePtr& dgnLib, WCharCP fileName) const; /// Check whether our Item Type library is defined in the active DGN file. static bool EnsureAnnotatorLibraryIsAvailable (); /// Check whether a specified Item Type library is defined in the active DGN file. /// If not defined, create Item Type and Report definitions. static bool EnsureLibraryIsAvailable (WCharCP libName, ItemDataCollectionCR itemData, AggregatorCollectionCR aggregateData, ReportDefsCR reportDefs); /// Warn about missing Item Type library: cannot proceed. static void WarnAndUnload (); };
Implementation: this uses the app's message lists stored in MDL resource files, which are not included here.
/////////////////////////////////////////////////////////////////////// bool ItemTypeLibraryMgr::ExistsInActiveFile () const { DgnFileP pDgnFile { MicroStation::GetActiveDgnFile () }; return ExistsInFile (*pDgnFile); } /////////////////////////////////////////////////////////////////////// bool ItemTypeLibraryMgr::ExistsInFile (DgnFileR dgnfile) const { const ItemTypeLibraryPtr lib { Get (dgnfile) }; return lib.IsValid (); } /////////////////////////////////////////////////////////////////////// ItemTypeLibraryPtr ItemTypeLibraryMgr::Get () const { DgnFileP pDgnFile { MicroStation::GetActiveDgnFile () }; return Get (*pDgnFile); } /////////////////////////////////////////////////////////////////////// ItemTypeLibraryPtr ItemTypeLibraryMgr::Get (DgnFileR dgnFile) const { return ItemTypeLibrary::FindByName (libName_.c_str (), dgnFile); } /////////////////////////////////////////////////////////////////////// bool ItemTypeLibraryMgr::CopyToActive (DgnFileR dgnFile) const { ItemTypeLibraryPtr lib { Get (dgnFile) }; if (lib.IsValid ()) { const bool Replace { true }; ItemTypeLibraryPtr clone { lib->CloneForFile (*MicroStation::GetActiveDgnFile (), Replace) }; if (clone.IsValid ()) { return clone->Write (); } } return false; } /////////////////////////////////////////////////////////////////////// bool ItemTypeLibraryMgr::FindDgnLib (DgnFilePtr& dgnLib, WCharCP fileName) const { bool found { false }; BeFileName dgnLibFile; if (SUCCESS == mdlFile_find (&dgnLibFile, fileName, L"MS_DGNLIBLIST", nullptr)) { DgnDocumentPtr document { DgnDocument::CreateForLocalFile (dgnLibFile.c_str ()) }; dgnLib = DgnFile::Create (*document, DgnFileOpenMode::ReadOnly); StatusInt openForReadStatus { 0 }; DgnPlatform::DgnFileStatus dgnOpenStatus = dgnLib->LoadDgnFile (&openForReadStatus); if (DGNFILE_STATUS_Success == dgnOpenStatus) { // TODO: not sure this is necessary dgnLib->FillDictionaryModel (); found = ExistsInFile (*dgnLib); } } return found; } /////////////////////////////////////////////////////////////////////// // static void ItemTypeLibraryMgr::WarnAndUnload () { WString error; mdlOutput_rscsPrintf (error, 0, MESSAGELIST_Errors, ERROR_DgnLib, ItemTypes::LibraryName ().c_str ()); const long msgAttributes { 0 }; NotifyMessageDetails msg (OutputMessagePriority::Error, error.c_str (), error.c_str (), msgAttributes, OutputMessageAlert::Dialog); NotificationManager::OutputMessage (msg); mdlDialog_cmdNumberQueue (false, CMD_MDL_UNLOAD, mdlSystem_getCurrTaskID (), MSInputQueuePos::INPUTQ_EOQ); } /////////////////////////////////////////////////////////////////////// // static bool ItemTypeLibraryMgr::EnsureAnnotatorLibraryIsAvailable () { return EnsureLibraryIsAvailable (ItemTypes::LibraryName ().c_str (), g_itemData, g_aggregates, g_reportDefs); } /////////////////////////////////////////////////////////////////////// // static bool ItemTypeLibraryMgr::EnsureLibraryIsAvailable (WCharCP libName, ItemDataCollectionCR itemData, AggregatorCollectionCR aggregateData, ReportDefsCR reportDefs) { WString announce; ItemTypeLibraryMgr libMgr (libName); bool found { libMgr.ExistsInActiveFile () }; if (found) { ItemTypeLibraryPtr pLib { libMgr.Get () }; mdlOutput_rscsPrintf (announce, 0, MESSAGELIST_Messages, MESSAGE_LibraryFound, libName); mdlOutput_messageCenter (DgnPlatform::OutputMessagePriority::Info, announce.c_str (), announce.c_str (), DgnPlatform::OutputMessageAlert::None); } else { SchemaDefinition schemaDef (libName, itemData); found = schemaDef.Create (); mdlOutput_rscsPrintf (announce, 0, MESSAGELIST_Messages, MESSAGE_LibraryCreated, libName); mdlOutput_messageCenter (DgnPlatform::OutputMessagePriority::Info, announce.c_str (), announce.c_str (), DgnPlatform::OutputMessageAlert::None); } if (found) { const UInt32 nReports { ReportDefinitions::ExistInActiveFile (reportDefs)}; if (0 == nReports) { const UInt32 nNewReports { ReportDefinitions::Create (reportDefs) }; } } return found; } /////////////////////////////////////////////////////////////////////// bool ItemTypeLibraryMgr::CopyFromDgnLib (WCharCP libName) const { ItemTypeLibraryMgr libMgr (libName); bool copied { false }; if (!libMgr.ExistsInActiveFile ()) { if (libMgr.FindAndCopyDefFromDgnLib (libName)) { copied = true; } else { WString warn; mdlOutput_rscsPrintf (warn, 0, MESSAGELIST_Errors, ERROR_DgnLibFind, libName); const long msgAttributes {0}; NotifyMessageDetails notify (OutputMessagePriority::Warning, warn.c_str (), warn.c_str (), msgAttributes, OutputMessageAlert::Balloon); NotificationManager::OutputMessage (notify); } } return copied; } /////////////////////////////////////////////////////////////////////// bool ItemTypeLibraryMgr::FindAndCopyDefFromDgnLib (WCharCP libName) const { bool found { false }; DgnFilePtr dgnLibFile; if (FindDgnLib (dgnLibFile, libName)) { if (ExistsInFile (*dgnLibFile)) { ItemTypeLibraryPtr pLib2 = Get (*dgnLibFile); if (CopyToActive (*dgnLibFile)) { found = true; ItemTypeLibraryPtr pLib3 = Get (); } else { WString warn; mdlOutput_rscsPrintf (warn, 0, MESSAGELIST_Errors, ERROR_DgnLibCopy, ItemTypes::LibraryName ().c_str ()); const long msgAttributes {0}; NotifyMessageDetails notify (OutputMessagePriority::Warning, warn.c_str (), warn.c_str (), msgAttributes, OutputMessageAlert::Balloon); NotificationManager::OutputMessage (notify); } } } return found; }