下面的示例演示一个简单的 MDI 感知 ObjectARX 应用程序。这是“使用数据库反应器”中的示例代码,添加了使应用程序 MDI 感知的代码。 class AsdkDbReactor; class AsdkDocReactor: public AcApDocManagerReactor { public: virtual void documentToBeActivated(AcApDocument* pDoc); virtual void documentCreated(AcApDocument* pDoc); virtual void documentToBeDestroyed(AcApDocument* pDoc); }; class AsdkPerDocData { friend class AsdkAppDocGlobals; public: AsdkPerDocData(AcApDocument* pDoc); private: AcApDocument* m_pDoc; AsdkPerDocData* m_pNext; long m_EntAcc; // Entity count AsdkDbReactor* m_pDbr; // Pointer to database reactor }; class AsdkAppDocGlobals { public: AsdkAppDocGlobals(AcApDocument* pDoc); void setGlobals(AcApDocument* pDoc); void removeDocGlobals(AcApDocument *pDoc); void removeAllDocGlobals(AsdkPerDocData* pTarget); void unload(); long &entityCount(); void incrementEntityCount(); void decrementEntityCount(); AsdkDbReactor *dbReactor(); void setDbReactor(AsdkDbReactor *pDb); private: AsdkPerDocData *m_pHead; AsdkPerDocData *m_pData; AsdkDocReactor *m_pDocReactor; }; AsdkAppDocGlobals *gpAsdkAppDocGlobals; // Custom AcDbDatabaseReactor class for Database // event notification. // class AsdkDbReactor : public AcDbDatabaseReactor { public: virtual void objectAppended(const AcDbDatabase* dwg, const AcDbObject* dbObj); virtual void objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObj); virtual void objectErased(const AcDbDatabase* dwg, const AcDbObject* dbObj, Adesk::Boolean pErased); }; // This is called whenever an object is added to the database. // void AsdkDbReactor::objectAppended(const AcDbDatabase* db, const AcDbObject* pObj) { printDbEvent(pObj, "objectAppended"); acutPrintf(" Db==%lx\n", (long) db); gpAsdkAppDocGlobals->incrementEntityCount(); acutPrintf("Entity Count = %d\n", gpAsdkAppDocGlobals->entityCount()); } // This is called whenever an object in the database is modified. // void AsdkDbReactor::objectModified(const AcDbDatabase* db, const AcDbObject* pObj) { printDbEvent(pObj, "objectModified"); acutPrintf(" Db==%lx\n", (long) db); } // This is called whenever an object is erased from the database. // void AsdkDbReactor::objectErased(const AcDbDatabase* db, const AcDbObject* pObj, Adesk::Boolean pErased) { if (pErased) { printDbEvent(pObj, "objectErased"); gpAsdkAppDocGlobals->decrementEntityCount(); else { printDbEvent(pObj, "object(Un)erased"); gpAsdkAppDocGlobals->incrementEntityCount(); } acutPrintf(" Db==%lx\n", (long) db); acutPrintf("Entity Count = %d\n", gpAsdkAppDocGlobals->entityCount()); } // Prints the message passed in by pEvent; then // proceeds to call printObj() to print the information about // the object that triggered the notification. // void printDbEvent(const AcDbObject* pObj, const char* pEvent) { acutPrintf(" Event: AcDbDatabaseReactor::%s ", pEvent); printObj(pObj); } // Prints out the basic information about the object pointed // to by pObj. // void printObj(const AcDbObject* pObj) { if (pObj == NULL) { acutPrintf("(NULL)"); return; } AcDbHandle objHand; char handbuf[17]; // Get the handle as a string. // pObj->getAcDbHandle(objHand); objHand.getIntoAsciiBuffer(handbuf); acutPrintf( "\n (class==%s, handle==%s, id==%lx, db==%lx)", pObj->isA()->name(), handbuf, pObj->objectId().asOldId(), pObj->database()); } // Document swapping functions // void AsdkDocReactor::documentToBeActivated(AcApDocument *pDoc) { gpAsdkAppDocGlobals->setGlobals(pDoc); } void AsdkDocReactor::documentCreated(AcApDocument *pDoc) { gpAsdkAppDocGlobals->setGlobals(pDoc); } void AsdkDocReactor::documentToBeDestroyed(AcApDocument *pDoc) { gpAsdkAppDocGlobals->removeDocGlobals(pDoc); } AsdkPerDocData::AsdkPerDocData(AcApDocument *pDoc) { m_pDoc = pDoc; m_pNext = NULL; m_EntAcc = 0; m_pDbr = NULL; } AsdkAppDocGlobals::AsdkAppDocGlobals(AcApDocument *pDoc) { m_pData = m_pHead = NULL; m_pDocReactor = new AsdkDocReactor(); acDocManager->addReactor(m_pDocReactor); } // Iterate through the list until the documents's global data is // found. If it is not found, create a new set of document globals. // void AsdkAppDocGlobals::setGlobals(AcApDocument *pDoc) { AsdkPerDocData *p_data = m_pHead, *prev_data = m_pHead; while (p_data != NULL) { if (p_data->m_pDoc == pDoc) { m_pData = p_data; break; } prev_data = p_data; p_data = p_data->m_pNext; } if (p_data == NULL) { if (m_pHead == NULL) m_pHead = m_pData = new AsdkPerDocData(pDoc); else prev_data->m_pNext = m_pData = new AsdkPerDocData(pDoc); } } // Delete the globals associated with pDoc. // void AsdkAppDocGlobals::removeDocGlobals(AcApDocument *pDoc) { AsdkPerDocData *p_data = m_pHead, *prev_data = m_pHead; while (p_data != NULL) { if (p_data->m_pDoc == pDoc) { if (p_data == m_pHead) m_pHead = p_data->m_pNext; else prev_data->m_pNext = p_data->m_pNext; if (m_pData == p_data) m_pData = m_pHead; delete p_data; break; } prev_data = p_data; p_data = p_data->m_pNext; } } // Delete all the doc globals in the list (recursively). // void AsdkAppDocGlobals::removeAllDocGlobals(AsdkPerDocData *p_target) { if (p_target == NULL) return; if (p_target->m_pNext != NULL) removeAllDocGlobals(p_target->m_pNext); if (p_target->m_pDbr != NULL) { acdbHostApplicationServices()->workingDatabase( )->removeReactor(p_target->m_pDbr); delete p_target->m_pDbr; p_target->m_pDbr = NULL; } delete p_target; } // Application was unloaded - delete everything associated with this // document. // void AsdkAppDocGlobals::unload() { acDocManager->removeReactor(m_pDocReactor); delete m_pDocReactor; removeAllDocGlobals(m_pHead); m_pHead = m_pData = NULL; } long & AsdkAppDocGlobals::entityCount() { return m_pData->m_EntAcc; } void AsdkAppDocGlobals::incrementEntityCount() { m_pData->m_EntAcc++; } void AsdkAppDocGlobals::decrementEntityCount() { m_pData->m_EntAcc--; } AsdkDbReactor * AsdkAppDocGlobals::dbReactor() { return m_pData->m_pDbr; } void AsdkAppDocGlobals::setDbReactor(AsdkDbReactor *pDb) { m_pData->m_pDbr = pDb; } // Adds a reactor to the database to monitor changes. // This can be called multiple times without any ill // effects because subsequent calls will be ignored. // void watchDb() { AsdkDbReactor *pDbr; if (gpAsdkAppDocGlobals->dbReactor() == NULL) { pDbr = new AsdkDbReactor(); gpAsdkAppDocGlobals->setDbReactor(pDbr); acdbHostApplicationServices()->workingDatabase( )->addReactor(pDbr); acutPrintf( " Added Database Reactor to " "acdbHostApplicationServices()->workingDatabase().\n"); } } // Removes the database reactor. // void clearReactors() { AsdkDbReactor *pDbr; if ((pDbr = gpAsdkAppDocGlobals->dbReactor()) != NULL) { acdbHostApplicationServices()->workingDatabase( )->removeReactor(pDbr); delete pDbr; gpAsdkAppDocGlobals->setDbReactor(NULL); } } // ObjectARX entry point function // extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* appId) { switch (msg) { case AcRx::kInitAppMsg: acrxUnlockApplication(appId); acrxRegisterAppMDIAware(appId); gpAsdkAppDocGlobals = new AsdkAppDocGlobals(curDoc()); gpAsdkAppDocGlobals->setGlobals(curDoc()); acedRegCmds->addCommand("ASDK_NOTIFY_TEST", "ASDK_WATCH", "WATCH", ACRX_CMD_TRANSPARENT, watchDb); acedRegCmds->addCommand("ASDK_NOTIFY_TEST", "ASDK_CLEAR", "CLEAR", ACRX_CMD_TRANSPARENT, clearReactors); break; case AcRx::kUnloadAppMsg: if (gpAsdkAppDocGlobals != NULL) { gpAsdkAppDocGlobals->unload(); delete gpAsdkAppDocGlobals; gpAsdkAppDocGlobals = NULL; } acedRegCmds->removeGroup("ASDK_NOTIFY_TEST"); break; } return AcRx::kRetOK; } |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-1-8 19:07
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.