您的位置:首页 > 移动开发 > Objective-C

ObjectARX中使用非模态对话框的问题(写数据库导致AutoCAD异常问题、刷新显示)

2011-12-21 14:16 495 查看
ObjectARX中使用非模态对话框遇到的两个问题及解决办法

一、写数据库导致AutoCAD异常问题

默认状态下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());

}

二、刷新显示屏幕问题

有时在程序中修改了实体,比如删除了实体,但在屏幕上没有及时地刷新,这时执行屏幕选取实体函数acedSSGet(),

仍然能够选中原来的实体,明明它们已经删除了,这时怎么办呢,考虑用acedCommand(RTSTR, "REGEN", RTNONE);

虽然也可以,但它会重新生成整个图形数据库,如果数据量很大,那么重生成的速度会很慢,

这样就不可能在程序的一段循环语句中修改每一个实体后都对数据库重生成,那程序运行的时间大部分都花在刷新数据库上了,

显然这不合理.

解决方法:

// 刷新显示屏幕

actrTransactionManager->flushGraphics();

acedUpdateDisplay();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐