admin 发表于 2024-3-13 22:57:23

objectArx ---多文档管理

一、概述
定义:为了实现 MDI(多文档用户界面)而提供的一个接口,应用范围较小,文档对象(AcApDocument)需关联数据库对象(AcDbDatabase),才能对其进行操作
功能:模拟人新建文件,点击文件标签切换,关闭标签等动作
二、文档打开、切换、关闭
2.1 测试代码
Commands.h
#include "stdafx.h"

void AddCommands();
void saveDoc();

Commands.cpp
#include "stdafx.h"
#include "Commands.h"
#include "Editor.h"
#include "Database.h"

void AddCommands()
{        // 此处参数为ACRX采用CMD采用SESSION:因为多文档管理的并不仅限于当前文档
        Editor::AddCommand(L"c-SAVEDWGOPENDOC", ACRX采用CMD采用SESSION, saveDoc);
}

void saveDoc()
{        // 以下为当前文档操作数据库
        // 新建CAD文件,还没保存,相当于appContextNewDocument,下面代码注释       
        // 以下功能为:遍历当前文档,获取直线数量
        AcDbObjectIdArray lineArray = NULL, circleArray = NULL;
       
        AcDbObjectIdArray ids = Database::GetAllEntIds();
        for (int i = 0; i < ids.length(); i++)
        {
                AcDbEntity *pEnt = NULL;
                if (acdbOpenObject(pEnt, ids.at(i), AcDb::kForRead) == Acad::eOk)
                {
                        if (pEnt->isKindOf(AcDbLine::desc()))
                        {
                                lineArray.append(pEnt->objectId());
                        }
                        pEnt->close();
                }
        }       
        acutPrintf(采用T("\n在文档1中打印"));

        // 以下也为在当前文档中操作数据库
        // 宏:#define acDocManager acDocManagerPtr(),函数返回的是AcApDocManager 对象指针
        // lockDocument锁定当前文档,curDocument获取当前文档,只有写操作需要锁定,kforread一类不用
        acDocManager->lockDocument(acDocManager->curDocument());

        // 此处直接操作数据库对象,因为有对数据库写入操作PostToModelSpace
        // 所以锁定文档要在写操作之前
        AcDbDatabase *pDb1 = new AcDbDatabase();
        // 此处操作 就是在数据库pDb1中写入圆,当前文档中有几个线,就在pdb1中加几个圆
        for (int i = 0; i < lineArray.length(); i++)
        {
                AcDbCircle *pCir = new AcDbCircle(AcGePoint3d(i*200,0,0), AcGeVector3d(0, 0, 1), 200);
                Database::PostToModelSpace(pCir,pDb1);
        }

        CString fileName = 采用T("C:/db1.dwg");
        // saveAs覆盖式保存数据库:但需要在锁定文档状态下使用
        pDb1->saveAs(fileName);
        delete pDb1;

        acutPrintf(采用T("\n此处还是在文档1中打印"));
        // 解锁当前文档(写操作完成)
        acDocManager->unlockDocument(acDocManager->curDocument());


        // 新建文档,并设置为当前文档
        // 括号内为:模板数据库文件,可为null,后期可手动更换新建文件的模板
        // 打开的标签是 "drawing 数字" ,保存的话 会弹出 另存为对话框
        acDocManager->appContextNewDocument(采用T("acad.dwt"));
        acutPrintf(采用T("\n此处在文档2中打印"));
        AfxMessageBox(采用T("\nNewDocument操作结束,确认后关闭当前文档"));
        acDocManager->closeDocument(acDocManager->curDocument());

        // 新建文档,并设置为当前文档(括号内为链接的数据库地址)
        // 打开的标签是 "db1.dwg" ,保存的话 会直接 存入 db1.dwg
        acDocManager->appContextOpenDocument(fileName);
        acutPrintf(采用T("\n此处在文档3中打印"));
        // 通常在此文档中操作已存在的数据库,此处为db1.dwg,
        // 此方法比较常用,若对数据库写操作,需注意锁定文件
        AfxMessageBox(采用T("\nOpenDocument操作结束,确认后关闭当前文档"));
        acDocManager->closeDocument(acDocManager->curDocument());
}

closeDocument关闭问题:当同时有NewDocument和OpenDocument操作,后者可以正常关闭,前者不可以,两个单独用就没问题,后续复核

2.2 效果
drawing1文档

drawing2文档

db1文档

db1.dwg中的图形

2.3 常用函数汇总
获得当前文档对象指针
// 获得 当前文档对象指针
AcApDocument *pAd = acDocManager->curDocument();
// 通过对象指针获得文档名称
acutPrintf(采用T("\n文档名为:%s"), pAd->fileName());

由文档获得数据库指针
// 由 文档指针 获得 数据库指针
AcDbDatabase *pDbtemp = pAd->database();
// 操作后记得释放内存
delete pDbtemp;

由数据库获得文档指针
// 查询数据库对象pDbtemp所属于的文档pAd1
AcApDocument *pAd1 = acDocManager->document(pDbtemp);

文档的切换
// 新建文档:传入CAD模板文件
acDocManager->appContextNewDocument(采用T("acad.dwt"));
// 打开文档:传入文件路径字符串
acDocManager->appContextOpenDocument(采用T("C:/db1.dwg"));
// 切换文档:传入文档对象指针
acDocManager->activateDocument(pAd);

文档的关闭
acDocManager->closeDocument(pAd );
页: [1]
查看完整版本: objectArx ---多文档管理