找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1842|回复: 1

[分享] 用arx 如何让 cad关闭文档时,不提示保存

[复制链接]

已领礼包: 20个

财富等级: 恭喜发财

发表于 2016-12-6 12:50:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
最近,有一个这样的需求,所以把解决方法给贴出来一下。

首先,cad判断图纸是否被修改过,是根据一个变量的值来判断的,这个变量就是 DBMOD,很多人肯定会想到,那我把这个变量的值给修改成0或者是-1不就行了吗? 很不幸告诉你,这个变量是只读的。那么怎么办呢? 幸好桌子公司还挺厚道的,导出了一个接口给我们来修改database的这个flag,只不过是在官方的sdk文档里没有给出来而已,这个接口的原型如下:
//声明设置数据库模式的函数
extern long acdbSetDbmod(AcDbDatabase * pDb, long newVal);
这个函数在我以前的blog文章中也提到过,按照我上面的方法,声明一下,就可以使用这个接口来解决问题。
好了,现在有解决问题的接口啊,那么设置的时机应该在什么时候? 我想说的是,一个是,在你所有的修改操作之后,还有一个就是关闭文档之前。
明显的后面一个实现起来更现实,因为,我们知道,可以通过反应器这个东东来实现,我就是通过反应器来实现的,能过editor反应器来hook Quit命令和CLOSE命令 willstart的时候,来设置对应数据库的flag,这样就可以认cad不弹出提示保存的对话框了,代码如下:
void AMenEditorReactor::commandWillStart(const ACHAR * cmdStr)
{
CString strCmd = cmdStr;
strCmd.MakeUpper();
if( !strCmd.CompareNoCase(_T("_CLOSE")) || !strCmd.CompareNoCase(_T("CLOSE")) )
{
   const TCHAR* szBuffer = NULL;
   acdbCurDwg()->getFilename(szBuffer);
   CString strRemoteFile = AMenFileManager::GetInstance()->GetLocaleBindFile(szBuffer);
   if( !strRemoteFile.IsEmpty() )
   {
    struct resbuf res;
    acedGetVar(L"DBMOD",&res);
    if(res.resval.rint) // If changes have been made...
    {
     //清除保存位
     acdbSetDbmod(acdbCurDwg(),0);
    }
   }
}
else if( !strCmd.CompareNoCase(_T("_QUIT")) || !strCmd.CompareNoCase(_T("QUIT")) )
{
   AcApDocumentIterator *pIt;
   pIt=acDocManager->newAcApDocumentIterator();
   while(!pIt->done())
   {
    // For each open document...
    AcApDocument* pDoc=pIt->document();
    acDocManager->setCurDocument(pDoc);
    struct resbuf res;
    acedGetVar(L"DBMOD",&res);
    if(res.resval.rint) // If changes have been made...
    {
     acDocManager->lockDocument(pDoc); // Lock
     acdbSetDbmod(pDoc->database(),0); // clear changes flag
     acDocManager->unlockDocument(pDoc);//unlock
    }
    pIt->step();
   }
   delete pIt;
}
AcEditorReactor::commandWillStart (cmdStr) ; }

PS: 另外还有方法的,记得AcApDocment类有两个成员接口,pushDbmod和popDbmod。 看文档可以得知,pushDbmod接口是copy当前DBMOD变量的值放在DBMOD栈上,从而pushDbmod之后对database的修改,改变是将是你copy后的这个值,在编辑完毕后,你再把这个值给popDbmod,这样就可以做到系统修改的是一个临时值,而不是database的DBMOD,而当系统判断database是否被修改的时候,就会以database本身的DBMOD来判断,这样也就不会提示保存对话框了。所以,这个模型可以如下:
修改前:pushDbmod
修改ing
修改后:popDbmod
关闭:不提示

O了。



评分

参与人数 1D豆 +2 收起 理由
ScmTools + 2 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 305个

财富等级: 日进斗金

发表于 2017-12-11 16:03:36 | 显示全部楼层
CString strRemoteFile = AMenFileManager::GetInstance()->GetLocaleBindFile(szBuffer);
请问,里面的AMenFileManager 是定义的什么类呢?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-24 20:30 , Processed in 0.174768 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表