CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

MDI 感知示例应用程序

2022-12-31 18:57| 发布者: admin| 查看: 306| 评论: 0|来自: AutoCAD

下面的示例演示一个简单的 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;
}

路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 12:23

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部