当前位置: 首页 > news >正文

MFC多文档程序,从菜单关闭一个文档和直接点击右上角的x效果不同

MFC多文档程序,从菜单关闭一个文档和直接点击右上角的x效果不同

若文档内容有修改,则前者会询问用户,是否保存修改;后者不保存修改直接关闭。
原因在于,从菜单关闭时,调用OnClose,一定会调用SaveModified(),其源码如下

/
// Standard file menu commands

void CDocument::OnFileClose()
{
	if (!SaveModified())
		return;

	// shut it down
	OnCloseDocument();
		// this should destroy the document
}

而点击x关闭时,CanCloseFrame()函数会判断是否保存文档,其源码如下:

BOOL CDocument::CanCloseFrame(CFrameWnd* pFrameArg)
	// permission to close all views using this frame
	//  (at least one of our views must be in this frame)
{
	ASSERT_VALID(pFrameArg);
	UNUSED(pFrameArg);   // unused in release builds

	POSITION pos = GetFirstViewPosition();
	while (pos != NULL)
	{
		CView* pView = GetNextView(pos);
		ASSERT_VALID(pView);
		CFrameWnd* pFrame = pView->GetParentFrame();
		// assume frameless views are ok to close
		if (pFrame != NULL)
		{
			// assumes 1 document per frame
			ASSERT_VALID(pFrame);
			if (pFrame->m_nWindow > 0)
				return TRUE;        // more than one frame refering to us
		}
	}

	// otherwise only one frame that we know about
	return SaveModified();
}

可见,仅当父框架的窗口为0时才会执行SaveModified()语句,其余情况都只会返回TRUE。在使用多文档编程时,要注意为了文档的安全,在自己重载的CanCloseFrame()中加上SaveModified()语句。

如何默默保存,不询问用户?

CDocument::SaveModified()的实现如下:

BOOL CDocument::SaveModified()
{
	if (!IsModified())
		return TRUE;        // ok to continue

	// get name/title of document
	CString name;
	if (m_strPathName.IsEmpty())
	{
		// get name based on caption
		name = m_strTitle;
		if (name.IsEmpty())
			VERIFY(name.LoadString(AFX_IDS_UNTITLED));
	}
	else
	{
		// get name based on file title of path name
		name = m_strPathName;
		if (afxData.bMarked4)
		{
			AfxGetFileTitle(m_strPathName, name.GetBuffer(_MAX_PATH), _MAX_PATH);
			name.ReleaseBuffer();
		}
	}

	CString prompt;
	AfxFormatString1(prompt, AFX_IDP_ASK_TO_SAVE, name);
	switch (AfxMessageBox(prompt, MB_YESNOCANCEL, AFX_IDP_ASK_TO_SAVE))
	{
	case IDCANCEL:
		return FALSE;       // don't continue

	case IDYES:
		// If so, either Save or Update, as appropriate
		if (!DoFileSave())
			return FALSE;       // don't continue
		break;

	case IDNO:
		// If not saving changes, revert the document
		break;

	default:
		ASSERT(FALSE);
		break;
	}
	return TRUE;    // keep going
}

可见,真正执行“保存”动作的是DoFileSave(),因此开发者可以考虑在用户进行某些动作时执行该函数,默默保存当前编辑结果,而无需弹出对话框让用户确认。

相关文章:

  • 【漏洞复现】泛微e-office OfficeServer2.php 存在任意文件读取漏洞复现
  • 【教程】微信小程序导入外部字体详细流程
  • 面试被问:Mysql的InnoDB下RR是如何解决幻读问题的
  • win系统环境搭建(三)——Windows安装maven
  • 练习敲代码速度
  • 刷一下算法
  • 音视频转换器 Permute 3 for mac中文
  • Nacos注册中心
  • SWC 流程
  • Electron(v26.2.1)无法加载React Developer Tools(v4.28.0)
  • 深度学习的三维重建 论文+源码+解析+译文+批注 MVSNet系列最新顶刊总结 下载
  • Java工具类Hutool使用
  • Layui + Flask | 表单元素(组件篇)(06)
  • Qt(day2)
  • 浏览器报错内容:Provisional headers are shown
  • 437. 路径总和 III
  • 如何下载安装 WampServer 并结合 cpolar 内网穿透,轻松实现对本地服务的公网访问
  • 线性矩阵不等式(LMI)在控制理论中的应用
  • 【LeetCode每日一题合集】2023.9.11-2023.9.17(⭐反悔贪心拓扑排序Floyd)
  • ICS TRIPLEX T8310 自动化控制模块
  • 全国人大常委会调研组在宁波调研,张庆伟带队钟山易炼红参加
  • 几百元的工资优势已不能吸引人才流动,江苏多地探讨“抢人”高招
  • 董明珠连任格力电器董事,回应管理层年轻化
  • 上海开展数据产品知识产权登记存证试点,243个产品许可收益超20亿元
  • 新任遂宁市委副书记王忠诚已任市政府党组书记
  • 用了半年的洗衣机竟比马桶还脏,别再这样洗衣服了