看看以下内容,是否能有帮助:
默认状态下AutoCAD2004是多文档应用程序,系统变量SDI=0,
acdbHostApplicationServices()->workingDatabase();
不是指一个文档,而是多个文档.当使用模态对话框时,这个对话框资源属于唯一的一个文档,所以不会产生错误; 而使用非模态对话框时,对话框资源不属于任何一个文档,如果修改往数据库(写操作),就会导致AutoCAD异常.
解决的方法是:
使用非模态对话框时要显式地管理文档的状态,当然,如果不需要多文档,则将系统变量SDI设为1也能解决非模态对话框的问题, 一般以写的方式操作实体时,要将当前文档锁定,操作结束后,解锁文档,而以读的方式打开对象,不需要锁定文档:
acDocManager->lockDocument(acDocManager->curDocument(), AcAp::kWrite, NULL, NULL, true);
这个函数的使用是锁定文档以便访问它们的资源,这些资源包括与文档相关联的的数据库对象(AcDbDatabases objects associated with a document),以及这些数据库中的实体对象(AcDbObject objects),还有数据库常驻系统变量(all AcDbDatabase resident system variables). 它还包括了基于系统变量的所有文档(all document based system variables),及与文档关联的事务管理器(the Transaction Manager associated with a document).文档在以AcDb::kForRead打开一个AcDbObject对象时不需要锁定,读取系统变量时也不需要锁定文档. ... acDocManager->unlockDocument(acDocManager->curDocument());
示例:
void lockDocument_Test() { AcGePoint3d start(0.0,0.0,0.0), end(10.0,10.0,0.0); AcDbLine *line = new AcDbLine(start, end); AcDbBlockTable *pBlockTable;
// 锁定当前文档 acDocManager->lockDocument(acDocManager->curDocument(), AcAp::kWrite, NULL, NULL, true);
acDocManager->curDocument()->database()->getBlockTable(pBlockTable, AcDb::kForRead); //acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRec; pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRec, AcDb::kForWrite); pBlockTable->close(); AcDbObjectId objId; pBlockTableRec->appendAcDbEntity(objId, line); line->close(); pBlockTableRec->close(); // 运行完解锁文档 acDocManager->unlockDocument(acDocManager->curDocument()); } |