objectArx ---多文档管理

本文档介绍了如何在AutoCAD中实现多文档用户界面(MDI)的操作,包括文档的打开、切换和关闭。通过测试代码展示了新建、切换和关闭文档的流程,以及对数据库的读写操作。在数据库操作部分,创建了新的CAD文件并保存,同时在不同文档间进行数据迁移。此外,还列举了常用的相关函数,如获取当前文档对象、切换文档和关闭文档的方法。

一、概述

  • 定义:为了实现 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 );
    

传送门 返回 列表

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值